Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <>2002-01-02 03:06:36 +0300
committercvs2svn <>2002-01-02 03:06:36 +0300
commit9783ce28caf426c5ab39d1d6aefa31cfdb1b8234 (patch)
tree4bac6085e7b0a39a0eb017a135fee30dadc49b16
parent10caff1aadd69ebe7fbfba162dd23f6b2dc8b5a4 (diff)
This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.
Cherrypick from master 2002-01-02 00:06:35 UTC Christopher Faylor <me@cgf.cx> '* speclib: Remove temp files automatically.': winsup/cygwin/ChangeLog-2001 winsup/cygwin/cygmagic winsup/cygwin/fhandler_disk_file.cc winsup/cygwin/how-fhandlers-work.txt winsup/cygwin/newsym winsup/cygwin/regex/COPYRIGHT winsup/cygwin/regex/cclass.h winsup/cygwin/regex/cname.h winsup/cygwin/regex/engine.c winsup/cygwin/regex/engine.ih winsup/cygwin/regex/mkh winsup/cygwin/regex/regcomp.c winsup/cygwin/regex/regcomp.ih winsup/cygwin/regex/regerror.c winsup/cygwin/regex/regerror.ih winsup/cygwin/regex/regex.3 winsup/cygwin/regex/regex.7 winsup/cygwin/regex/regex.h winsup/cygwin/regex/regex2.h winsup/cygwin/regex/regexec.c winsup/cygwin/regex/regfree.c winsup/cygwin/regex/tests winsup/cygwin/regex/utils.h winsup/cygwin/regexp/v8_regerror.c winsup/cygwin/regexp/v8_regexp.c winsup/cygwin/regexp/v8_regsub.c winsup/cygwin/rmsym winsup/cygwin/speclib winsup/cygwin/winbase.h
-rw-r--r--winsup/cygwin/ChangeLog-20015337
-rwxr-xr-xwinsup/cygwin/cygmagic20
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc857
-rw-r--r--winsup/cygwin/how-fhandlers-work.txt65
-rwxr-xr-xwinsup/cygwin/newsym24
-rw-r--r--winsup/cygwin/regex/COPYRIGHT20
-rw-r--r--winsup/cygwin/regex/cclass.h31
-rw-r--r--winsup/cygwin/regex/cname.h102
-rw-r--r--winsup/cygwin/regex/engine.c1019
-rw-r--r--winsup/cygwin/regex/engine.ih35
-rwxr-xr-xwinsup/cygwin/regex/mkh76
-rw-r--r--winsup/cygwin/regex/regcomp.c1546
-rw-r--r--winsup/cygwin/regex/regcomp.ih48
-rw-r--r--winsup/cygwin/regex/regerror.c127
-rw-r--r--winsup/cygwin/regex/regerror.ih12
-rw-r--r--winsup/cygwin/regex/regex.3509
-rw-r--r--winsup/cygwin/regex/regex.7235
-rw-r--r--winsup/cygwin/regex/regex.h83
-rw-r--r--winsup/cygwin/regex/regex2.h134
-rw-r--r--winsup/cygwin/regex/regexec.c141
-rw-r--r--winsup/cygwin/regex/regfree.c38
-rw-r--r--winsup/cygwin/regex/tests477
-rw-r--r--winsup/cygwin/regex/utils.h22
-rw-r--r--winsup/cygwin/regexp/v8_regerror.c28
-rw-r--r--winsup/cygwin/regexp/v8_regexp.c1321
-rw-r--r--winsup/cygwin/regexp/v8_regsub.c88
-rwxr-xr-xwinsup/cygwin/rmsym11
-rwxr-xr-xwinsup/cygwin/speclib12
-rw-r--r--winsup/cygwin/winbase.h83
29 files changed, 12501 insertions, 0 deletions
diff --git a/winsup/cygwin/ChangeLog-2001 b/winsup/cygwin/ChangeLog-2001
new file mode 100644
index 000000000..140b2a9e9
--- /dev/null
+++ b/winsup/cygwin/ChangeLog-2001
@@ -0,0 +1,5337 @@
+2001-12-31 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Strip path when installing library.
+
+2001-12-30 Christopher Faylor <cgf@redhat.com>
+
+ * include/getopt.h: Fix define.
+
+2001-12-30 Christopher Faylor <cgf@redhat.com>
+ Ralf Habacker <Ralf.Habacker@freenet.de>
+
+ * speclib: New file.
+ * Makefile.in: Create library versions of automode.o, textmode.o, and
+ binmode.o for easier use on command line. Create libpthread.a, libm.a,
+ and libc.a with subsets of exports found in libcygwin.a.
+
+2001-12-30 Ralf Habacker <Ralf.Habacker@freenet.de>
+
+ * cygmagic: Eliminate unneeded use of 'tr' and 'bc'.
+
+2001-12-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (open_local_policy): Use POLICY_EXECUTE instead of
+ enumerating user rights.
+
+2001-12-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (open_local_policy): Initialize lsa handle to NULL.
+ Request only needed access rights in call to LsaOpenPolicy().
+ (create_token): Check for NULL lsa pointer.
+
+2001-12-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din: Add symbols for endutent(), getutent(), getutid(),
+ getutline(), setutent() and utmpname().
+ * syscalls.cc (setutent): New function.
+ (endutent): Ditto.
+ (utmpname): Ditto.
+ (getutent): Ditto.
+ (getutid): Ditto.
+ (getutline): Ditto.
+ * include/cygwin/version.h: Bump API minor version.
+
+2001-12-26 Christopher Faylor <cgf@redhat.com>
+
+ * cygmagic: Add define name to warning.
+ * dcrt0.cc (_dll_crt0): Check for changes in child_info size.
+ (multiple_cygwin_problem): Avoid "proc" errors when testing. Just
+ assume new cygwin proc.
+ * shared_info.h (mount_info): Add 'cb' element for sanity checks.
+ (shared_info): Ditto.
+ * child_info.h (child_info): Add fhandler_union_size element for sanity
+ checking.
+ * shared.cc (open_shared): Detect shared region size mismatch between
+ parent and child.
+ (shared_info::initialize): Detect shared region size mismatch with
+ expectation.
+ (memory_Init): Ditto.
+ * sigproc.cc (init_child_info): Correctly set cb in passed structure.
+ * shared.cc (open_shared):
+
+2001-12-26 Christopher Faylor <cgf@redhat.com>
+
+ * include/getopt.h: Protect a declaratin.
+
+2001-12-26 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond::Signal): Use a separate flag for signal
+ detection and broadcast semantics.
+ (__pthread_cond_dowait): Ditto.
+ * thread.h (pthread_cond): New flag for testing when a waiter has
+ woken.
+
+2001-12-26 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Quote arguments to shell scripts.
+ (clean): Remove new *_magic.h autogenerated files.
+
+2001-12-25 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Autogenerate some header files which provide magic
+ numbers. Force dependencies for files which depend on autogenerated
+ headers to ensure that they are always built.
+ * child_info.h (child_info): Add new fields to accommodate new magic
+ number header stuff.
+ * dcrt0.cc: Rely on "child_info_magic.h" to ensure that correct
+ child_info magic numbers are used.
+ (dll_crt0_1): Temporarily remove _cygwin_testing_magic test.
+ (_dll_crt0): Do more testing on magic numbers from fork_info structure.
+ Call "multiple_cygwin_problem" where appropriate.
+ (multiple_cygwin_problem): Rename from multiple_cygwin_die. Issue a
+ warning or die, as appropriate based on cygwin version/magic number
+ mismatch.
+ * pinfo.cc (pinfo::exit): Don't attempt to dereference `this' if it
+ doesn't exist. This can happen when a fatal error occurs early in
+ process initialization.
+ * shared.cc: Rely on "shared_info_magic.h" to accommodate that new
+ magic number header stuff.
+ (shared_info::initialize): Use new magic number stuff, for shared
+ region.
+ (memory_init): Ditto, for mount table.
+ * shared_info.h: Accomodate new magic number stuff for shared region
+ and mount table.
+ * sigproc.cc: Rely on "child_info_magic.h" to accommodate new magic
+ number header stuff.
+ (init_child_info): Initialize new fields in child_info) to accomodate
+ magic numbers.
+ * winsup.h: Rename multiple_cygwin_die to multiple_cygwin_problem.
+ * include/cygwin/version.h: Define macros for manipulating version
+ magic.
+ * cygmagic: New shell script for generating magic numbers.
+
+2001-12-20 Christopher Faylor <cgf@redhat.com>
+
+ * include/cygwin/version.h: Bump API minor version for below changes.
+
+2001-12-19 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (VPATH): Add regex directory.
+ (NM): new variable.
+ (OBSOLETE_FUNCTIONS): Ditto.
+ (NEW_FUNCTIONS): Ditto.
+ (install-headers): Install regex.h.
+ (install-man): New target.
+ (install): Use new target.
+ (DLL_OFILES): Add v8_reg* stuff.
+ (new-cygwin1.dll): Eliminate stamp-cygwin-lib creation.
+ (libcygwin.a): Remove obsolete functions from import lib. Add new functions.
+ * configure.in: Detect 'nm' tool.
+ * configure: Regenerate.
+ * cygwin.din: Export posix_reg* functions. Eliminate export of v8 reg* functions.
+ This is now handled in object files themselves.
+ * regex/*: New files.
+ * regexp/v8_*.c: New files, renamed from non v8_ equivalents.
+
+2001-12-17 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/getopt.h: Don't define getopt_long() and friends when
+ included through unistd.h.
+
+2001-12-17 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::init_std_file_from_handle): Avoid initializing
+ using an invalid handle.
+
+2001-12-16 David Billinghurst <David.Billinghurst@riotinto.com>
+
+ * include/limits.h: Define LLONG_MIN, LLONG_MAX, ULLONG_MAX.
+
+2001-12-11 Christopher Faylor <cgf@redhat.com>
+
+ * include/getopt.h: Add HAVE_DECL_GETOPT to save pain elsewhere.
+
+2001-12-10 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_serial::ev): New class member.
+ * fhandler_serial.cc (fhandler_serial::raw_read): Use class member for
+ event status.
+ * select.cc (peek_serial): Ditto.
+
+2001-12-07 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Use full path name for determining
+ attributes when /cygdrive/x/foo.
+
+2001-12-06 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Reset FH_CYGDRIVE if iterating through
+ path.
+
+2001-12-06 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Don't complain if /dev/x/foo when x
+ doesn't exist.
+ (mount_info::conv_to_win32_path): Keep translating when a /cygdrive is
+ found. Don't attempt to translate to a device name when devn ==
+ FH_CYGDRIVE.
+ (cygwin_conv_to_win32_path): Set buffer to empty on error.
+ (cygwin_conv_to_full_win32_path): Ditto.
+
+ * window.cc: Include unistd.h to verify definitions.
+
+2001-12-05 Christopher Faylor <cgf@redhat.com>
+
+ * dir.cc (opendir): Detect error return from build_fhandler_from_name.
+
+2001-12-04 David Rothenberger <daveroth@acm.org>
+
+ * net.cc (cygwin_getsockopt): Dereference optlen pointer when passing
+ to __check_null_invalid_struct_errno.
+
+2001-12-03 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (cygwin_getsockopt): Allow NULL optval.
+ (cygwin_setsockopt): Ditto.
+ (cygwin_recvfrom): Allow NULL from.
+
+ * path.cc (mount_info::read_cygdrive_info_from_registry): Don't write
+ cygdrive to registry if it doesn't exist.
+
+2001-12-03 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (mount_info::conv_to_win32_path): Avoid returning error if
+ cygdrive == '/'.
+ (mount_info::cygdrive_win32_path): Return 0 if invalid cygdrive path.
+
+2001-11-30 Christopher Faylor <cgf@redhat.com>
+
+ * debug.cc (makethread): Eliminate unneeded function call.
+ * miscfuncs.cc (tls_ix): Predefine.
+ * perthread.h (set_reent): Eliminate.
+ (get_reent): Ditto.
+ * winbase.h (my_tlsalloc): Use global stack base pointer. Set newly
+ allocated location to NULL.
+ (my_tlssetvalue): Use global stack base pointer.
+ (my_tlsgetvalue): Ditto.
+
+2001-11-27 Christopher Faylor <cgf@redhat.com>
+
+ * winsup.h: Reorganize to avoid use of experimental stuff.
+ * shortcut.cc: Move winsup.h first in include order.
+
+2001-11-27 Christopher Faylor <cgf@redhat.com>
+
+ * cygwin.din (ualarm): New export.
+ * dcrt0.cc (_dll_crt0): Add experimental tls storage declaration.
+ (dll_crt0): Ditto.
+ * debug.cc (thread_stub): Ditto.
+ * thread.cc: Minor cleanup.
+ (__pthread_create): Add experimental tls storage declaration.
+ * miscfuncs.cc: Define tls index.
+ * winsup.h: Declare experimental tls storage.
+
+ * window.cc (alarm): Use old timer return from setitimer.
+ (ualarm): New function. From Alexandr V. Shutko.
+
+2001-11-26 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (libcygwin.a): Use ar commands to build libcygwin.a since
+ adding an archive doesn't work the way we want it to.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_cygdrive::readdir): Avoid reporting
+ inaccessible drives.
+
+2001-11-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_hstrerror): Allow s == NULL.
+ (cygwin_rcmd): Add parameter checking.
+ (cygwin_rexec): Ditto.
+
+2001-11-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_inet_ntoa): Add parameter checking.
+ (cygwin_inet_network): Return INADDR_NONE instead of 0 in case of
+ EFAULT.
+ (cygwin_hstrerror): Add parameter checking.
+ (cygwin_rresvport): Ditto.
+ (socketpair): Ditto.
+ * winsup.h (check_null_str): Add extern declaration.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Tighten FH_CYGDRIVE check to avoid
+ matching trailing component, like other devices.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (IsDebuggerPresent): Make conditional load since it is
+ not available everywhere.
+
+ * path.cc (mount_info::conv_to_win32_path): Only consider /cygdrive to
+ be FH_CYGDRIVE, not /cygdrive/x.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (inet_makeaddr): Revert previous change.
+
+2001-11-23 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (chdir): Allow 'cd /cygdrive'.
+
+2001-11-23 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::vfork_parent_restore): Add debugging statement.
+
+ * exceptions.cc (try_to_debug): Spin only as long as we don't have a
+ debugger attached.
+
+ * fhandler.h (fhandler_base::set_nohandle): New method.
+ (fhandler_base::get_nohandle): New method.
+ * fhandler.cc (fhandler_base::dup): Avoid duplicating handle if there
+ is no handle.
+ * fhandler_disk_file.cc (fhandler_disk_file::opendir): Set nohandle
+ flag on dummy fd.
+
+2001-11-23 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Make intermediate library for eventual inclusion in
+ libcygwin.a
+
+ * fhandler.h (fhandler_pipe::fhandler_pipe): Remove default argument
+ setting since it is no longer used.
+
+ * miscfuncs.cc (check_null_str): New function.
+ (check_null_str_errno): Ditto.
+ * net.cc: Add defensive buffer checking throughout.
+ (cygwin_sendto): Protect against invalid fd.
+ (cygwin_recvfrom): Ditto.
+ (cygwin_getpeername): Ditto.
+ (cygwin_recv): Ditto.
+ (cygwin_send): Ditto.
+ * winsup.h: Declare a new function.
+
+2001-11-23 Corinna Vinschen <corinna@vinschen.de>
+
+ * select.cc (set_bits): Fix conditional for setting fd in exceptfds.
+ * dtable.cc (dtable::build_fhandler): Create fhandler_pipe using
+ correct device type.
+ * path.cc (get_devn): Set correct pipe device type from device name.
+
+2001-11-22 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (conv_path_list): Fix wild indexing into path due to
+ conflicting methods for setting src pointer.
+
+ * dir.cc (opendir): Only pass path_conv argument to opendir, since name
+ is already part of the fhandler.
+ * dtable.cc (dtable::build_fhandler): Accomodate new FH_CYGDRIVE type.
+ * fhandler.cc (fhandler_base::opendir): Nuke name argument.
+ * fhandler.h: Add FH_CYGDRIVE to "device" enum.
+ (fhandler_base::opendir): Nuke name argument.
+ (fhandler_disk_file::opendir): Ditto.
+ (fhandler_disk_file::fhandler_disk_file): Declare new method which
+ passes devtype through.
+ (fhandler_cygdrive): Add elements for tracking drives.
+ (fhandler_cygdrive::set_drives): Declare new method.
+ (fhandler_cygdrive::iscygdrive_root): Declare new method.
+ (fhandler_cygdrive::opendir): Declare new method.
+ (fhandler_cygdrive::readdir): Declare new method.
+ (fhandler_cygdrive::telldir): Declare new method.
+ (fhandler_cygdrive::seekdir): Declare new method.
+ (fhandler_cygdrive::rewinddir): Declare new method.
+ (fhandler_cygdrive::closedir): Declare new method.
+ (fhandler_cygdrive::fstat): Declare new method.
+ * fhandler_disk_file.cc (fhandler_disk_file::fhandler_disk_file):
+ Define new method which passes devtype through.
+ (fhandler_disk_file::open): Tweak debug output.
+ (fhandler_disk_file::opendir): Nuke first argument. Use info from
+ path_conv and class rather than calling fstat.
+ (fhandler_cygdrive::set_drives): New method.
+ (fhandler_cygdrive::iscygdrive_root): New method.
+ (fhandler_cygdrive::opendir): New method.
+ (fhandler_cygdrive::readdir): New method.
+ (fhandler_cygdrive::telldir): New method.
+ (fhandler_cygdrive::seekdir): New method.
+ (fhandler_cygdrive::rewinddir): New method.
+ (fhandler_cygdrive::closedir): New method.
+ (fhandler_cygdrive::fstat): New method.
+ * path.cc (iscygdrive_device): Assume cygdriveness is already verified.
+ (path_conv::check): Treat FH_CYGDRIVE "method" as a special case,
+ setting file attributes as needed.
+ (mount_info::conv_to_win32_path): Allow stand-alone /cygdrive, meaning
+ "the directory which contains all of the drives on the system".
+ (fillout_mntent): Use cyg_tolower for conversions.
+ (mount_info::cygdrive_win32_path): Replace unused argument with unit
+ number.
+ * shared_info.h (mount_info::cygdrive_win32_path): Reflect argument
+ change.
+
+2001-11-21 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (DLL_OFILES): Add fhandler_disk_file.o.
+ * cygheap.h (cygheap_fdnew::operator =): New operator.
+ * dir.cc: Add invalid struct checking throughout. Use methods for all
+ directory manipulation throughout.
+ * fhandler.cc: Move fhandler_disk_file stuff to own file.
+ (fhandler_base::opendir): New method.
+ (fhandler_base::readdir): New method.
+ (fhandler_base::telldir): New method.
+ (fhandler_base::seekdir): New method.
+ (fhandler_base::rewinddir): New method.
+ (fhandler_base::closedir): New method.
+ * fhandler_disk_file.cc: New file.
+ * fhandler.h (fhandler_base): Declare new virtual methods.
+ (fhandler_disk_file): Ditto.
+ (fhandler_cygdrive): New class.
+
+ * path.cc (conv_path_list): Use strccpy to break apart path.
+
+2001-11-17 Nick Duffek <nick@duffek.com>
+
+ * path.cc (conv_path_list): Copy source paths before modifying them.
+
+2001-11-17 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_raw.cc (fhandler_dev_raw::clear): Don't reset unit.
+ * fhandler_tape.cc (fhandler_dev_tape::fhandler_dev_tape): Add debug
+ output.
+
+2001-11-15 Egor Duda <deo@logos-m.ru>
+
+ * include/pthread.h (PTHREAD_COND_INITIALIZER): Define.
+ * thread.cc (__pthread_cond_destroy): Add support for
+ PTHREAD_COND_INITIALIZER.
+ (__pthread_cond_init): Ditto.
+ (__pthread_cond_broadcast): Ditto.
+ (__pthread_cond_signal): Ditto.
+ (__pthread_cond_dowait): Ditto.
+ (__pthread_mutex_init): Handle PTHREAD_MUTEX_INITIALIZER correctly,
+ don't return error when it's passed as parameter.
+ * winsup.h (check_null_invalid_struct): Call correct function.
+
+2001-11-14 Christopher Faylor <cgf@redhat.com>
+
+ * exceptions.cc: Add stdlib.h include for alloca declaration.
+ * poll.cc: Ditto.
+ * termios.cc: Ditto.
+
+2001-11-14 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (_write): Only allow zero length when fd is valid.
+
+2001-11-14 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Add setting access time
+ and creation time to last modification time for files on filesystems
+ not supporting multiple timestamps.
+ (fhandler_disk_file::fstat_helper): Set access time and creation
+ time in incoming Windows structure instead of in stat buf to avoid
+ incorrectly overwriting Epoch timestamp.
+
+2001-11-14 Corinna Vinschen <corinna@vinschen.de>
+
+ * winsup.h: Remove alloca definition since it's now defined through
+ inclusion of stdlib.h.
+ * lib/cygwin_crt0.c: Ditto.
+
+2001-11-13 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (_write): Allow zero length as per SUSv2.
+
+2001-11-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (mkdir): Add HIDDEN file attribute if file has leading dot
+ and HIDDEN_DOT_FILES is defined.
+ * fhandler.cc (fhandler_base::open): Ditto.
+ * path.cc (symlink): Ditto.
+ * syscalls.cc (_rename): Ditto and remove HIDDEN file attribute if
+ new filename does not begin with a dot.
+
+2001-11-12 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_console.cc (fhandler_console::read): Revert 2001-10-23
+ change to only honor keydown events.
+
+2001-11-11 Christopher Faylor <cgf@redhat.com>
+
+ * include/cygwin/version.h: Bump version to 1.3.6.
+
+2001-11-10 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::build_fhandler): Don't increment console fd count
+ if new operation fails. Increment fork_fixup field here.
+ (dtable::dup2): Don't increment fork_fixup field here.
+ * net.cc (fdsock): Ditto.
+
+2001-11-08 Corinna Vinschen <corinna@vinschen.de>
+
+ * select.cc: Set errno using set_sig_errno() throughout.
+ * signal.cc (signal): Always set SA_RESTART flag.
+ * syscalls.cc (_read): Revert previous patch.
+
+2001-11-08 Corinna Vinschen <corinna@vinschen.de>
+
+ * select.cc (fhandler_tty_slave::ready_for_read): Return 0 on EBADF.
+ * syscalls.cc (_read): If ready_for_read() failed, save errno from
+ being overwritten by signal handler call.
+
+2001-11-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * lib/getopt.c (getopt_internal): Reset optind to 1 only if optreset
+ is not set.
+
+2001-11-06 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc (fhandler_tty_slave::ready_for_read): Correct inverted
+ not_open test.
+
+2001-11-05 Christopher Faylor <cgf@redhat.com>
+
+ * include/cygwin/version.h: Bump version to 1.3.5.
+
+2001-11-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap_record::find_empty): Add input parameter check.
+
+2001-11-04 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::build_fhandler): Fix debug_printf to avoid SEGV
+ due to incorrect parameter placement.
+
+2001-11-04 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_pipe::broken_pipe): Renamed from saweof.
+ (fhandler_pipe::set_eof): Reflect above change.
+ * pipe.cc (fhandler_pipe::fhandler_pipe): Ditto.
+ (fhandler_pipe::read): Ditto.
+ (fhandler_pipe::hiteof): Ditto.
+
+2001-11-04 Christopher Faylor <cgf@redhat.com>
+
+ * pipe.cc (fhandler_pipe::read): Narrow eof return to just the "broken
+ pipe" test.
+
+2001-11-04 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc: Add more comments throughout. Use bool 'true' where
+ appropriate throughout.
+ (fhandler_socket::select_read): Remove duplicate setting for *_ready
+ which inadvertently overrode previous, correct setting.
+ (fhandler_socket::select_write): Ditto.
+
+2001-11-03 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc (verify_console): New function.
+ (verify_windows): Ditto.
+ (fhandler_console::select_read): Really do need to verify that there is
+ something to read.
+ (fhandler_console::select_windows): Ditto.
+
+2001-11-03 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_base::ready_for_read): Remove unused argument.
+ (fhandler_tty_slave::ready_for_read): Ditto.
+ (select_record): Remove poll, initialize peek.
+ * select.cc: Remove all poll functions, throughout. Change second
+ argument of peek_* functions to 'bool' throughout. Specifically
+ initialize *_ready variables throughout.
+ (select_stuff::poll): Subsume previous poll functionality.
+ (peek_pipe): Don't grab guard mutex when in select loop.
+ select()/read() is racy by design so there is no need to worry about a
+ race in select().
+ (fhandler_base::ready_for_read): Remove unused argument.
+ (fhandler_tty_slave::ready_for_read): Ditto.
+ * syscalls.cc (_read): Eliminate third argument in ready_for_read call.
+
+2001-11-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (get_supplementary_group_sidlist): New function.
+ (get_group_sidlist): Call get_supplementary_group_sidlist() to
+ retrieve list of supplementary groups SIDs from /etc/group and
+ add them to the user's group list.
+
+2001-11-03 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::read): Return just read ahead characters
+ if slow device.
+ * fhandler.h (fhandler_base::set_eof): New virtual method.
+ (fhandler_pipe::set_eof): New method.
+ * pipe.cc (fhandler_pipe::fhandler_pipe): Clear saweof flag.
+ (fhandler_pipe::read): Return immediately if hit eof.
+ (fhandler_pipe::hit_eof): Return true if saweof flag is set.
+ * select.cc (peek_pipe): Don't call PeekNamedPipe if we couldn't grab
+ the guard mutex.
+
+2001-11-02 Egor Duda <deo@logos-m.ru>
+
+ * dll_init.h (class dll_list): Reorder functions to avoid compiler
+ "can't inline" warnings.
+ * security.h (class cygsid): Ditto.
+ * sigproc.cc (get_proc_lock): Ditto.
+ * sigproc.h (class sigframe): Ditto.
+ * sync.h (class muto): Ditto.
+
+2001-11-02 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_base::get_guard): Actually MAKE virtual as
+ previously indicated.
+ * pipe.cc (make_pipe): Remove extraneous set_errno.
+ * syscalls.cc (_open): Ditto.
+ * select.cc (peek_pipe): Need to check that there is still something to
+ read from the pipe after acquiring the mutex since another
+ process/thread could have eaten the input before we got to acquiring
+ the lock. (Thanks to Nick Duffek for this inspiration.)
+
+2001-11-01 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h: Change Windows 'BOOL's to c++ 'bool's for all variables.
+ * select.cc (fhandler_base::ready_for_read): Set read_ready to zero
+ prior to testing it or it will be uninitialized.
+
+ * Makefile.in (CFLAGS): Move setting to Makefile.common.
+
+2001-11-01 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.h (cygheap_fdmanip::isopen): Set appropriate errno if fd not
+ open.
+ * select.cc (fhandler_base::ready_for_read): Release an open guard
+ mutex when exiting with an error condition.
+ * syscalls.cc (_read): Check frequently for closed fd as a kludge until
+ something better is invented.
+
+2001-11-01 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::build_fhandler): Issue internal error on unknown
+ device.
+ * fhandler.cc (fhandler_base::close): Show both name and handle in
+ debugging output.
+
+ * fhandler.h (fhandler_base::get_guard): New virtual method.
+ (fhandler_pipe::get_guard): New method.
+ (fhandler_socket::ready_for_read): Delete declaration.
+ (fhandler_pipe::ready_for_read): Ditto.
+ (fhandler_serial::ready_for_read): Ditto.
+ (fhandler_console::ready_for_read): Ditto.
+ (fhandler_tty_common::ready_for_read): Ditto.
+ (fhandler_windows::ready_for_read): Ditto.
+ (struct select_record::peek): Declare new method.
+ * select.cc (MAKEready): Delete.
+ (peek_pipe): Use get_guard method to retrieve potential guard mutex
+ handle.
+ (fhandler_base::ready_for_read): Rewrite as generic ready-for-read
+ handler. Should only be called for "slow" devices.
+ (fhandler_socket::ready_for_read): Delete definition.
+ (fhandler_pipe::ready_for_read): Ditto.
+ (fhandler_serial::ready_for_read): Ditto.
+ (fhandler_console::ready_for_read): Ditto.
+ (fhandler_tty_common::ready_for_read): Ditto.
+ (fhandler_windows::ready_for_read): Ditto.
+ (fhandler_pipe::select_read): Fill in new peek record in select_record
+ structure.
+ (fhandler_console::select_read): Ditto.
+ (fhandler_tty_common::select_read): Ditto.
+ (fhandler_serial::select_read): Ditto.
+ (fhandler_socket::select_read): Ditto.
+ (fhandler_socket::select_read): Ditto.
+ (fhandler_tty_slave::ready_for_read): Check for tty not open. Set
+ errnos appropriately.
+ * syscalls.cc (_read): Allow ready_for_read to set errno.
+
+ * pinfo.cc (pinfo::init): Return spawn/NO_WAIT process as valid if it
+ is initializing.
+ * sigproc.cc (getsem): Adjust wait for process to initialize downward
+ to avoid huge waits.
+
+2001-10-31 Christopher Faylor <cgf@redhat.com>
+
+ * environ.cc: Set reset_com to false to mimic linux behavior more
+ closely.
+
+2001-10-31 Corinna Vinschen <corinna@vinschen.de>
+
+ * dtable.cc (dtable::vfork_child_dup): Revert impersonation
+ before duplicating fhandler.
+
+2001-10-30 Christopher Faylor <cgf@redhat.com>
+
+ * exceptions.cc (signal_exit): Weight the odds against the main thread
+ running when signal thread is exiting.
+
+2001-10-30 Christopher Faylor <cgf@redhat.com>
+
+ * sigproc.cc (sigproc_terminate): Don't signal main thread when exiting.
+ * sigproc.h (sigframe): Decorate some methods with `inline'.
+ (new_muto): Coerce pointer to new to void *.
+
+2001-10-30 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::fork_fixup): Pass old handle to
+ setclexec_pid.
+
+2001-10-30 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.h (cygheap_fdmanip::cygheap_fdmanip): Clear fh.
+ (cygheap_fdmanip::isopen): New method.
+ * syscalls.cc (_read): Avoid accessing closed fd.
+
+ * path.h (fe_types): New enum.
+ (path_conv::set_path): New method.
+ (find_exec): Change null_if_not_found argument to something more
+ generic.
+ * spawn.cc (find_exec): Default to returning the POSIX path rather than
+ the windows path, unless instructed otherwise.
+ (spawn_guts): Force call to find_exec to use native paths.
+ * dlfcn.cc (check_path_access): Accommodate new find_exec arguments.
+ * environ.h (win_env::get_posix): New method.
+
+2001-10-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::close): Add error handling.
+
+2001-10-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::dup): Revert previous change.
+
+2001-10-30 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::dup2): Add some debugging. Use methods from
+ passed in class rather than cygheap->fdtab.
+ * fhandler_socket.cc (fhandler_socket::fixup_before_fork_exec): Add
+ more debugging output.
+ (fhandler_socket::dup): Allocate new space for prot_info_ptr for
+ duplicated entry.
+ (fhandler_socket::close): Loop closesocket() as long as WSAEWOULDBLOCK
+ is returned.
+ * syscalls.cc (stat_worker): Always delete fh if it has been created.
+
+2001-10-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (is_group_member): Call NetLocalGroupGetMembers() for
+ local machine only.
+ (get_user_local_groups): Ditto for NetLocalGroupEnum().
+
+2001-10-29 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::set_name): Set namehash here to catch
+ name changes.
+ (fhandler_base::open): Remove namehash setting.
+ (fhandler_base::fstat): Subtract 1 from arbitrary time setting to avoid
+ strange ls -l granularity problem.
+
+2001-10-29 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc (MAKEready): Remove extraneous select_read.
+
+2001-10-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * uinfo.cc (internal_getlogin): Set environment variable $HOME
+ from either /etc/passwd or $HOMEDRIVE/$HOMEPATH if necessary.
+
+2001-10-29 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_serial::fhandler_serial): Change to only accept
+ unit argument.
+ * fhandler_serial.cc (fhandler_serial::fhandler_serial): Ditto.
+ (fhandler_serial::open): Avoid else when previous clause is a return().
+ * path.cc (get_devn): Alias /dev/ttyS0 -> /dev/com1, etc.
+ (get_device_number): Reallow standalone "com1" as a valid name for
+ /dev/com1.
+
+2001-10-26 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc (MAKEready): Check for read_ready in loop since select_read
+ could set it.
+ (peek_socket): Check ready/write/except specifically since they could
+ have been set even prior to peek_socket call.
+
+2001-10-24 Christopher Faylor <cgf@redhat.com>
+
+ * shared_info.h (MOUNT_VERSION): Change to a smaller, still arbitrary
+ number.
+ * shared.cc (open_shared): Accept a number to denote the shared memory
+ region.
+ (memory_init): Use shared memory version as part of the object name of
+ the shared region. Ditto for the mount table.
+ * path.cc (CYGWIN_REGNAME): New define used in place of
+ CYGWIN_INFO_CYGWIN_REGISTRY_NAME throughout.
+ * external.cc (cygwin_internal): Implement CW_[GS]ET_CYGWIN_REGISTRY_NAME.
+ * cygheap.h (init_cygheap::cygwin_regname): New element.
+
+2001-10-23 Christopher Faylor <cgf@redhat.com>
+
+ Ensure that all fhandler_*::read definitions are __stdcall throughout.
+ * fhandler.cc (fhandler_base::set_inheritance): Be more defensive in
+ debugging code.
+ * fhandler.h: Adjust regparms throughout to reflect passing 'this'
+ parameter.
+ * fhandler_console.cc (fhandler_console::read): Remove unneeded test.
+ Only honor "key down" events.
+ * miscfuncs.cc (strcasestr): Reorganize for efficient code use.
+ (check_null_empty_str_errno): Ditto.
+ (__check_null_invalid_struct_errno): Ditto.
+ (__check_invalid_read_ptr_errno): Ditto.
+ * syscalls.cc (_read): Return 0 when length == 0, as per Single UNIX
+ Specification.
+
+2001-10-22 Christopher Faylor <cgf@redhat.com>
+
+ * debug.cc (set_errno): Return value of errno that was set, just like
+ the macro.
+ (setclexec_pid): Replace old handle with new handle.
+ * debug.h: Reflect change in arguments for setclexec_pid.
+ * fhandler.cc (fhandler_base::set_inheritance): Ditto.
+ (fhandler_base::fork_fixup): Ditto.
+ * cygerrno.h: Reflect return value change for set_errno.
+
+2001-10-22 Christopher Faylor <cgf@redhat.com>
+
+ Remove 'cb' parameter and modify fhandler_* constructors throughout.
+ * dtable.cc (dtable::build_fhandler): Remove debugging output which
+ uses 'cb'.
+ * exec.cc (execvp): New function.
+ (execvpe): Ditto.
+ * fhandler.cc (fhandler_base::fhandler_base): Use constructor
+ initialization.
+ * fhandler.h (fhandler_tty_common::fhandler_tty_common): Ditto.
+ * fhandler_clipboard.cc (fhandler_dev_clipboard::fhandler_dev_clipboard):
+ Ditto.
+ * fhandler_console.cc (fhandler_console::fhandler_console): Ditto.
+ * fhandler_raw.cc (fhandler_dev_raw::fhandler_dev_raw): Ditto.
+ * fhandler_serial.cc (fhandler_serial::fhandler_serial): Ditto.
+ * fhandler_tty.cc (fhandler_tty_master::fhandler_tty_master): Ditto.
+ (fhandler_tty_slave::fhandler_tty_slave): Ditto.
+ (fhandler_pty_master::fhandler_pty_master): Ditto.
+ * fhandler_windows.cc (fhandler_windows::fhandler_windows): Ditto.
+
+2001-10-22 Corinna Vinschen <corinna@vinschen.de>
+
+ Patch suggested by Ian Ray <ian.ray@nokia.com>:
+ * syscalls.cc (seteuid): Unset environment variables HOMEDRIVE and
+ HOMEPATH before calling internal_getlogin().
+ * uinfo.cc (internal_getlogin): Use default HOMEPATH and HOMEDRIVE
+ from environment if both are present, else query NetUserGetInfo().
+
+2001-10-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (get_2k_ifconf): Change multiple IP address naming scheme
+ to Linux style.
+
+Sun Oct 21 19:04:37 2001 Alexander Gottwald <ago@informatik.tu-chemnitz.de>
+
+ * net.cc (get_2k_ifconf): Added support for multiple IP addresses on
+ one interface.
+
+2001-10-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * miscfuncs.cc (__check_invalid_read_ptr_errno): Return error, if any.
+
+2001-10-21 Christopher Faylor <cgf@redhat.com>
+
+ * resource.cc (fill_rusage): Perform paranoid zero structure passed to
+ GetProcessMemoryInfo.
+
+2001-10-22 Robert Collins <rbtcollins@hotmail.com>
+
+ * autoload.cc: Autoload GetProcessMemoryInfo.
+ * resource.cc (fill_rusage): Calculate ru_maxrss and ru_majflt entries.
+ (Bug report on this from Guido Serassio in the squid project).
+ This requires including psapi.h.
+
+2001-10-20 Christopher Faylor <cgf@redhat.com>
+
+ * dll_init.cc (dll_list::alloc): Increase retry count to 1000.
+
+2001-10-20 Christopher Faylor <cgf@redhat.com>
+
+ * miscfuncs.cc (__check_invalid_read_ptr_errno): New function.
+ * syscalls.c (_write): Validate that write buffer is accessible for
+ reading, not writing.
+ * winsup.h: Declare new function, increase regparmization of check_*
+ functions.
+
+2001-10-19 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (getcwd): Allow len == 0 when buf == NULL.
+
+2001-10-18 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (_read): Validate input pointer.
+ (_write): Ditto.
+ (system): Ditto.
+
+2001-10-16 Frederic Devernay <Frederic.Devernay@sophia.inria.fr>
+
+ * poll.cc (poll): Call cygwin_select() if any fd is valid.
+
+2001-10-16 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_raw.cc (fhandler_dev_raw::open): Eliminate compatibility
+ code since no Win32 device names are used anymore.
+ * fhandler_tape.cc (fhandler_dev_tape::tape_set_blocksize): Allow
+ 0 as blocksize to indicate variable blocksize.
+ * path.cc (win32_device_name): Generate NT internal device names
+ using upper/lower case names for readability.
+ Generate \DosDevices\<letter>: device name for mount table
+ compatibility devices.
+
+2001-10-16 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_tape.cc (fhandler_dev_tape::tape_status): Report
+ EOTWarningZoneSize in get->mt_eotwarningzonesize.
+ * include/cygwin/mtio.h: Define DEFTAPE.
+ (struct mtget): Add member `mt_eotwarningzonesize'. Add a comment.
+ * include/cygwin/version.h: Bump API minor version to 47.
+
+2001-10-16 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::fork_fixup): Guard against compiler
+ warning.
+
+2001-10-16 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add load statement for `NtOpenFile'.
+ * fhandler.h (fhandler_dev_raw::get_unit): New method.
+ (fhandler_dev_tape::norewind): Eliminate.
+ (fhandler_dev_tape::is_rewind_device): New method.
+ * fhandler_raw.cc (fhandler_dev_raw::open): Open new
+ fixed device name devices using NT internal method.
+ Keep calling fhandler_base::open() for old mount table
+ device mapping compatibility devices.
+ (fhandler_dev_raw::fstat): Eliminate. Settings are done
+ by fhandler_base::fstat() already.
+ * fhandler_tape.cc: Remove `norewind' usage throughout.
+ * ntdll.h: Define FILE_SYNCHRONOUS_IO_NONALERT.
+ Define struct _IO_STATUS_BLOCK.
+ Declare NtOpenFile().
+ * path.cc (get_raw_device_number): Add new approach for
+ using fixed device names.
+ (win32_device_name): Ditto.
+ (get_device_number): Ditto. Require POSIX path to begin
+ with "/dev/".
+ (mount_info::conv_to_win32_path): Call win32_device_name()
+ instead of get_device_number() after evaluating mount points
+ to allow changing the win32 destination path again.
+ * security.cc (str2buf2uni): Remove `static' to be able to
+ call function from fhandler_dev_raw::open().
+ * wincap.cc: Set flag has_raw_devices appropriately.
+ * wincap.h: Add flag has_raw_devices.
+
+2001-10-16 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.h (cygheap_fdget::cygheap_fdget): Remove debugging operation
+ from set_errno.
+
+2001-10-16 Christopher Faylor <cgf@redhat.com>
+
+ * mmap.cc (mmap): Assign 'fh' from cygheap_fdget. Use 'fh' everywhere.
+
+2001-10-15 Christopher Faylor <cgf@redhat.com>
+
+ * cygerrno.h (set_errno): Define more informative version of this
+ function for debugging.
+ (__set_errno): Declare when DEBUGGING.
+ * cygheap.h (cygheap_fdget::cygheap_fdget): Add a flag to control when
+ errno is set.
+ * debug.cc (__set_errno): New function.
+ * fcntl.cc (_fcntl): Fix so that correct fd is used for second argument
+ to dup2.
+ * syscalls.cc (_cygwin_istext_for_stdio): Don't set errno here when
+ using cygheap_fdget.
+
+2001-10-15 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::fork_fixup): Don't protect handle.
+
+ * dlfcn.cc: Fix to confirm to coding standards.
+
+ Reorganize includes throughout to accommodate new cygheap.h usage.
+ * cygheap.h (cygheap_fdmanip): New class: simplifies locking and
+ retrieval of fds from cygheap->fdtab.
+ (cygheap_fdget): Ditto.
+ (cygheap_fdnew): Ditto.
+ * fcntl.cc (_fcntl): Use new method to lock fdtab and retrieve info.
+ * ioctl.cc (ioctl): Ditto.
+ * mmap.cc (mmap): Ditto.
+ * net.cc: Ditto, throughout.
+ * passwd.cc (getpass): Ditto.
+ * path.cc (fchdir): Ditto.
+ * pipe.cc (make_pipe): Ditto.
+ * sec_acl.cc (facl): Ditto.
+ * syscalls.cc: Ditto, throughout.
+ * termios.cc: Ditto, throughout.
+
+2001-10-15 Corinna Vinschen <corinna@vinschen.de>
+
+ * uname.cc (uname): Use `wProcessorLevel' unless OS sets it wrong.
+ Use `dwProcessorType' then instead.
+ * wincap.cc: Set flag has_valid_processorlevel appropriately.
+ * wincap.h: Add flag has_valid_processorlevel.
+
+2001-10-14 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::build_fhandler_from_name): Use PC_FULL to
+ determine path name.
+ * path.cc (fchdir): Remove rel -> abs path conversion.
+
+Sun Oct 14 08:10:12 2001 Gary R. Van Sickle
+
+ * fork.cc (fork_parent): Correct the "unable to allocate
+ forker_finished event" error message. It named the wrong event before.
+
+2001-10-13 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (load_wsock32): Declare dummy function to force loading
+ of winsock.
+ * fhandler.cc (fhandler_base::set_inheritance): Make debugging output
+ more verbose.
+ * fhandler_socket.cc (fhandler_socket::fixup_after_fork): Force loading
+ of winsock32 if winsock2 not available.
+ * net.cc (set_socket_inheritance): Use DuplicateHandle in all cases to
+ set inheritance correctly.
+ (fdsock): Use winsock2_active macro to determine when to set socket
+ inheritance. Remove fdtab resource locking since this function should
+ already be protected.
+ (cygwin_accept): Simplify logic. Ensure that fdtab unlock is not
+ called inappropriately.
+ (cygwin_rcmd): Use fdtab locking.
+ (cygwin_rresvport): Ditto.
+ (cygwin_rexec): Ditto.
+ * select.cc (peek_socket): Set errno appropriately if winsock select
+ fails.
+
+2001-10-13 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * winsup.h: Declare check_pty_fds.
+ * syscalls.cc (check_pty_fds): Rename from check_ttys_fds. Also check
+ pty master.
+ (setsid): Use check_pty_fds.
+ * dtable.cc (dtable::dec_console_fds): Add check on pty fds.
+
+2001-10-13 Ralf Habacker <Ralf.Habacker@freenet.de>
+
+ * fhandler_dsp.cc (fhandler_dsp::ioctl): Return 0 for successful
+ SNDCTL_DSP_GETBLKSIZE operation.
+
+2001-10-13 Christopher Faylor <cgf@redhat.com>
+
+ Remove obsolete 'name' arg from fhandler_* constructors throughout.
+ * winsup.h (winsock_active): New macro.
+ (winsock2_active): Ditto.
+ * autoload.cc (wsock_init): Use new macros to decide if winsock or
+ winsock2 is loaded.
+ (nonexist_wsock32): Dummy function to force winsock load.
+ (nonexist_ws2_32): Dummy function to force winsock2 load.
+ * fhandler.h (fhandler_socket::fstat): Declare new method. Currently
+ unused.
+ * fhandler_socket.cc (fhandler_socket::fixup_before_fork_exec): Check
+ that winsock2 is active before trying WSADuplicateSocketA.
+ (fhandler_socket::fixup_after_fork): Add extra check for
+ winsock2_active. Otherwise use iffy procedures for Windows 95.
+ (fhandler_socket::fixup_after_exec): Add debugging.
+ (fhandler_socket::dup): Add debugging.
+ (fhandler_socket::fstat): New method.
+ (fhandler_socket::set_close_on_exec): Attempt to perform iffy stuff on
+ Windows 95.
+
+ * errno.cc (_sys_nerr): Work around compiler strangeness.
+
+ * pinfo.cc (winpids::add): Add extra element at end of allocated array
+ for setting to NULL.
+ (winpids::enumNT): Ditto.
+ (winpids::init): Don't modify pidlist if it hasn't been allocated
+ (possibly due to malloc problem).
+
+2001-10-12 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (wsock_init): Reorganize slightly to accommodate a new
+ compiler.
+
+2001-10-11 Egor Duda <deo@logos-m.ru>
+
+ * net.cc (cygwin_sendto): Use correct socket address when sending
+ data to AF_UNIX socket.
+
+Wed Oct 10 16:10:41 2001 Alexander Gottwald <ago@informatik.tu-chemnitz.de>
+
+ * net.cc (get_95_ifconf): Using other registry values pointing to
+ correct networkdevice identification for Windows95.
+
+Tue Oct 9 22:22:45 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, rename PROC_FORK1 to PROC_FORK.
+ * child_info.h: Rename PROC_* to _PROC_*. Define PROC_* with
+ additional testing magic. Eliminate old PROC_FORK and rename
+ PROC_FORK1 to PROC_FORK.
+ * dcrt0.cc (_cygwin_testing_magic): New variable. Added to magic
+ number in proc_info.
+ (alloc_stack): Eliminate old PROC_FORK test.
+ (dll_crt0_1): Ditto. Use _PROC_* enums for test. Subtract
+ _cygwin_testing_magic from child_proc_info->type so that normal cygwin
+ programs invoked by test suite programs do not consider themselves to
+ be in a cygwin environment.
+ (_dll_crt0): Ditto. Move environment checks to initial_env function to
+ conserve on stack space.
+ (initial_env): New function. Checks for testing and debugging
+ environment variables.
+ * init.cc (cygwin_hmodule): Move declaration.
+ * winsup.h: Declare variables used for cygwin testing.
+
+Tue Oct 9 19:17:53 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * uinfo.cc (internal_getlogin): Reorganize slightly to minimize work in
+ default condition.
+
+Tue Oct 9 18:53:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_disk_file::open): Add missing case clash check.
+
+Mon Oct 8 01:47:27 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.cc (dtable::build_fhandler): Allocate correct amount for given
+ fhandler class.
+ * fhandler.h (fhandler_union): Properly define rather than relying on
+ fhandler_console being "big enough".
+
+Mon Oct 8 00:25:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * external.cc (fillout_pinfo): Reset counter whenever we initialize the
+ pid list.
+
+Sun Oct 7 17:16:05 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (normalize_posix_path): Don't eat a '.' after a '\\' since it
+ has special meaning on NT.
+
+ * syscalls.cc (access): Use stat_worker.
+
+Fri Oct 5 21:01:14 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_base::fork_fixup): Protect dup'ed handle and
+ record it as non-inheritable for debugging purposes in case there is a
+ subsequent fork or exec.
+ * fhandler_tty.cc (fhandler_tty_common::fixup_after_fork): Allow
+ fork_fixup to call ProtectHandle.
+
+Fri Oct 5 14:22:47 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (get_raw_device_number): Correct length arguments for
+ wdeveqn.
+
+Fri Oct 5 11:05:32 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (getcwd): Allow NULL first argument.
+
+Fri Oct 5 00:31:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * heap.h (inheap): Check for NULL.
+
+Thu Oct 4 23:17:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Add second path_conv * argument to fstat()s throughout.
+ * fhandler.h: Change read and fstat to regparm/stdcall throughout.
+ (fhandler_base::fstat): Just declare. Don't define.
+ (fhandler_disk_file::fstat_helper): Declare.
+ * fhandler.cc (fhandler_base::fstat): Move here from fhandler.h, adapt
+ from former stat_dev().
+ (fhandler_disk_file::fstat): Move most of the disk-file-specific logic
+ from stat_worker to here. Use fstat_helper to derive final fstat
+ output.
+ (fhandler_disk_file::fstat_helper): New method, renamed from former
+ fstat method.
+ (num_entries): Moved here from syscalls.cc.
+ * fhandler_mem.cc (fhandler_dev_mem::fstat): Use base class to
+ initialize most stuff. Invert has_physical_mem_access test for
+ establishing permissions.
+ * fhandler_raw.cc (fhandler_dev_raw::fstat): Eliminate unneed test and
+ memory clearing. Use base class to initialize most stuff.
+ * syscalls.cc (stat_dev): Eliminate.
+ (stat_worker): Simply call fstat method to generate fstat output. Move
+ all device specific code to appropriate fstats.
+
+ * dir.cc (opendir): Pass correct arg to stat_worker to allow following
+ symlinks.
+
+Thu Oct 4 21:37:57 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * spawn.cc (perhaps_suffix): Return NULL on non-existence of file as
+ well as "directoryness". Previous code modified on 2001/09/30 actually
+ had an arguable bug which was unmasked by the change on that day.
+
+Thu Oct 4 20:52:42 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Return ENOTDIR when leading device and
+ trailing component.
+
+Thu Oct 4 18:49:23 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (stat_worker): Make global. Accept path_conv parameter
+ for passing information back to caller.
+ * winsup.h: Declare stat_worker.
+ * dir.cc (opendir): Use stat_worker rather than stat and pass path_conv
+ parameter to stat_worker for later inspection.
+
+2001-10-04 Karellen (karellen@boreworms.com)
+
+ * syslog.cc (syslog): Teach syslog about syslog priorities other than
+ LOG_ERR, LOG_WARNING and LOG_INFO
+
+Thu Oct 4 15:50:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Don't perform file system or rootdir
+ checks on devices.
+
+Wed Oct 3 19:40:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dcrt0.cc (dll_crt0_1): Don't close hexec_proc if it is NULL.
+
+ * fork.cc (vfork): Add debugging statements.
+
+ * path.cc (get_device_number): Make static. Rewrite to inspect both unix
+ and windows paths.
+ (get_raw_device_number): Just check for parts of raw device that we
+ care about.
+ (get_devn): New function, pulled from get_device_number.
+ (win32_device_name): Accommodate arg changes to get_device_number.
+ (mount_info::get_device_number): Call get_device_number on translated
+ Windows path.
+
+ * spawn.cc (spawn_guts): Don't treat P_VFORK differently from P_NOWAIT.
+ Add handle to child's shared region to child so that it will be
+ preserved if the parent goes away.
+ * fhandler.h: Throughout, simplify to one open method for all fhandler
+ classes, requiring a path_conv first element.
+ * fhandler.cc (fhandler_base::open): Remove obsolete method.
+ Generalize to require path_conv * as first argument.
+ (fhandler_disk_file::open): Remove obsolete method.
+ (fhandler_disk_file::open): Use path_conv pointer rather than
+ reference.
+ * fhandler_clipboard.cc (fhandler_dev_clipboard::dup): Use new open
+ method.
+ (fhandler_dev_clipboard::open): Accommodate new argument for open
+ methods.
+ * fhandler_console.cc (fhandler_console::open): Ditto.
+ (fhandler_console::dup): Use new open method.
+ (fhandler_console::fixup_after_fork): Ditto.
+ (fhandler_console::fixup_after_exec): Ditto.
+ * fhandler_dsp.cc (fhandler_dev_dsp::open): Accommodate new argument for
+ open methods.
+ * fhandler_floppy.cc (fhandler_dev_floppy::open): Ditto.
+ * fhandler_mem.cc (fhandler_dev_mem::open): Ditto.
+ * fhandler_random (fhandler_dev_random::open): Ditto.
+ * fhandler_raw.cc (fhandler_dev_raw::open): Ditto.
+ * fhandler_serial.cc (fhandler_serial::open): Ditto.
+ * fhandler_tape.cc (fhandler_dev_tape::open): Ditto.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Ditto.
+ (fhandler_pty_master::open): Ditto.
+ * fhandler_windows.cc (fhandler_windows::open): Ditto.
+ * fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
+ * fhandler_socket.cc (fhandler_socket::set_connect_secret): Accommodate
+ new argument for open methods.
+ * syscalls.cc (_open): Ditto.
+ (stat_worker): Ditto.
+
+Tue Oct 2 23:49:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cfree): Remove malloc debugging probe.
+ * dlmalloc.c (errprint): Remove abort() call which causes interesting
+ error message printing to abort prematurely.
+ * environ.cc: Sprinkle MALLOC_CHECKs liberally throughout.
+ (_addenv): Allocate two empty elements at end of environ to
+ (apparently) work around problems with some buggy applications.
+ (winenv): Avoid calling alloca if no forced environment variable is
+ present.
+
+ * exceptions.cc (open_stackdumpfile): Don't print "Dumping stack trace
+ to..." when running in a cygwin environment (i.e., the parent is a
+ cygwin process).
+
+ * dtable.cc (dtable::init_std_file_from_handle): Move device type
+ detection code from build_fhandler here since it is only used by this
+ function.
+ (dtable::build_fhandler_from_name): New method. Renamed from
+ dtable::build_fhandler.
+ (dtable::build_fhandler): Use build_fhandler_from_name.
+ (cygwin_attach_handle_to_fd): Ditto.
+ * syscalls.cc (_open): Ditto.
+ (stat_worker): Ditto.
+ * dtable.h (dtable::build_fhandler_from_name): Rename declaration from
+ dtable::build_fhandler.
+
+Mon Oct 1 16:52:23 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.h (dtable::build_fhandler): Make path_conv parameter
+ non-optional.
+ (dtable::init_std_file_from_handle): Eliminate name parameter.
+ * dtable.cc (stdio_init): Don't pass bogus name to
+ init_std_file_from_handle. The function will figure out the name
+ itself.
+ (dtable::init_std_file_from_handle): Eliminate name parameter. Assume
+ that we're always called with an appropriate fd. Pass name as NULL if
+ we can't simply figure it out from context.
+ (cygwin_attach_handle_to_fd): Pass path_conv argument to
+ build_fhandler.
+ (dtable::build_fhandler): Make path_conv argument mandatory. Eliminate
+ specific call to get_device_number. With unknown device names, set
+ name from handle context for parsing by path_conv.
+ (dtable::build_fhandler): Pass path_conv argument to build_fhandler.
+ * path.h (path_conv::set_isdisk): Set disk device type.
+ (path_conv::is_device): Don't consider FH_DISK a "device".
+ * syscalls.cc (_open): Pass path_conv argument by reference.
+ (stat_worker): Ditto.
+ (_rename): Use path_conv operators. Add bounds to DeleteFile/MoveFile
+ for loop.
+
+Mon Oct 1 14:25:00 2001 Charles Wilson <cwilson@ece.gatech.edu>
+
+ * cygwin.din: export strtoll and strtoull
+
+Sun Sep 30 22:51:41 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Add "path.h" include throughout, where needed. Use new path_conv
+ methods and operators to simplify testing for directory and attributes,
+ throughout.
+ * path.h (path_conv::exists): New method.
+ (path_conv::has_attribute): Ditto.
+ (path_conv::isdir): Ditto.
+ (path_conv::DWORD &): New operator.
+ (path_conv::int &): Ditto.
+ * dir.cc (rmdir): Eliminate a goto.
+ * dtable.cc (dtable::build_fhandler): Accept opt and suffix info for
+ path_conv.check. Return fh == NULL on path_conv error. Pass unit to
+ set_name as appropriate.
+ (dtable::reset_unix_path_name): New method.
+ * dtable.h (dtable): Declare new method. Reflect arg changes to
+ build_fhandler.
+ * fhandler.cc (fhandler_disk_dummy_name): Eliminate.
+ (fhandler_base::set_name): Expect paths to be NULL. Build
+ unix_path_name from win32_path_name when it is a device.
+ (fhandler_base::reset_unix_path_name): New method.
+ (fhandler_base::raw_read): Report EISDIR when ERROR_INVALID_FUNCTION
+ or ERROR_INVALID_PARAMETER and reading a directory.
+ (fhandler_disk_file::fstat): Don't call stat_dev since we should now
+ never be calling fhandler_disk_file methods with devices.
+ (fhandler_base::fhandler_base): Clear {unix,win32}_path_name.
+ (fhandler_base::~fhandler_base): Always free {unix,win32}_path_name.
+ (fhandler_disk_file::fhandler_disk_file): Remove set_no_free_names
+ kludge.
+ (fhandler_disk_file::open): Ditto.
+ * fhandler.h (fhandler_base::no_free_names): Eliminate.
+ (fhandler_base::set_no_free_names): Ditto.
+ * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Don't set
+ unix_path_name here.
+ * path.cc (fchdir): Lock fd table throughout. Use new
+ dtable::reset_unix_path_name method to reset path.
+ * syscalls.cc (stat_worker): Reorganize to always call fstat method.
+ Pass path_conv method to fhandler_*::open.
+ (chroot): Elminate a goto.
+
+Sun Sep 30 17:37:43 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * environ.cc (winenv): Allocate exact amount of space needed for forced
+ windows environment variable rather than just using MAX_PATH.
+
+Sun Sep 30 17:10:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Depend on stamp to ensure rebuilding. Remove stamp file
+ when we've just built the DLL.
+
+Mon Oct 1 00:34:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond_dowait): Hopefully eliminate a race on multiple thread
+ wakeups.
+
+Sat Sep 29 18:26:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * pthread.cc (pthread_cond_timedwait): Deleted - exported from thread.cc.
+ (pthread_cond_wait): Deleted - exported from thread.cc.
+ * thread.cc (pthread_cond::BroadCast): Update to use the new syntax for
+ verifyable_object_isvalid ().
+ (pthread_cond::Signal): Ditto. Also attempt to fix the lost signal race
+ with pthread_cond::TimedWait().
+ (check_valid_pointer): Change definiton to void const *.
+ (verifyable_object_isvalid): Add new parameter to allow identification of
+ static initializers, and return a enum rather than magic numbers.
+ (__pthread_create): Ditto.
+ (__pthread_cleanup): Ditto.
+ (__pthread_attr_init): Ditto.
+ (__pthread_attr_getinheritsched): Ditto.
+ (__pthread_attr_getschedparam): Ditto.
+ (__pthread_attr_getschedpolicy): Ditto.
+ (__pthread_attr_getscope): Ditto.
+ (__pthread_attr_setdetachstate): Ditto.
+ (__pthread_attr_getdetachstate): Ditto.
+ (__pthread_attr_setinheritsched): Ditto.
+ (__pthread_attr_setschedparam): Ditto.
+ (__pthread_attr_setschedpolicy): Ditto.
+ (__pthread_attr_setscope): Ditto.
+ (__pthread_attr_setstacksize): Ditto.
+ (__pthread_attr_getstacksize): Ditto.
+ (__pthread_attr_destroy): Ditto.
+ (__pthread_join): Ditto.
+ (__pthread_detach): Ditto.
+ (__pthread_suspend): Ditto.
+ (__pthread_continue): Ditto.
+ (__pthread_getschedparam): Ditto.
+ (__pthread_getsequence_np): Ditto.
+ (__pthread_key_create): Ditto.
+ (__pthread_key_delete): Ditto.
+ (__pthread_setschedparam): Ditto.
+ (__pthread_setspecific): Ditto.
+ (__pthread_getspecific): Ditto.
+ (__pthread_cond_destroy): Ditto.
+ (__pthread_cond_init): Ditto.
+ (__pthread_cond_broadcast): Ditto.
+ (__pthread_cond_signal): Ditto.
+ (__pthread_condattr_init): Ditto.
+ (__pthread_condattr_getpshared): Ditto.
+ (__pthread_condattr_setpshared): Ditto.
+ (__pthread_condattr_destroy): Ditto.
+ (__pthread_kill): Ditto.
+ (__pthread_mutex_init): Ditto.
+ (__pthread_mutex_getprioceiling): Ditto.
+ (__pthread_mutex_lock): Ditto.
+ (__pthread_mutex_trylock): Ditto.
+ (__pthread_mutex_unlock): Ditto.
+ (__pthread_mutex_destroy): Ditto.
+ (__pthread_mutex_setprioceiling): Ditto.
+ (__pthread_mutexattr_getprotocol): Ditto.
+ (__pthread_mutexattr_getpshared): Ditto.
+ (__pthread_mutexattr_gettype): Ditto.
+ (__pthread_mutexattr_init): Ditto.
+ (__pthread_mutexattr_destroy): Ditto.
+ (__pthread_mutexattr_setprotocol): Ditto.
+ (__pthread_mutexattr_setprioceiling): Ditto.
+ (__pthread_mutexattr_getprioceiling): Ditto.
+ (__pthread_mutexattr_setpshared): Ditto.
+ (__pthread_mutexattr_settype): Ditto.
+ (__sem_init): Ditto.
+ (__sem_destroy): Ditto.
+ (__sem_wait): Ditto.
+ (__sem_trywait): Ditto.
+ (__sem_post): Ditto.
+ (__pthread_cond_dowait): New function, contains core logic from
+ __pthread_cond_wait and __pthread_cond_timedwait. Decrement (*cond)->waiting
+ before reentering the cond access mutex to allow detection of lost signals.
+ (__pthread_cond_timedwait): Rename to pthread_cond_timedwait, and call
+ __pthread_cond_dowait after calculating the wait length.
+ (__pthread_cond_wait): Rename to pthread_cond_wait, and call
+ __pthread_cond_dowait.
+ * thread.h: New enum for use with verifyable_object_isvalid.
+ Remove the extern exporting of __pthread_cond_timedwait and __pthread_cond_wait.
+
+Fri Sep 28 21:18:50 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * pipe.cc (fhandler_pipe::fixup_after_fork): New method.
+ * fhandler.h (fhandler_pipe::fixup_after_fork): Declare new method.
+
+Fri Sep 28 03:23:04 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * passwd.cc (read_etc_passwd): Bother with unlocking when not
+ in cygwin initialization.
+ * grp.cc (read_etc_group): Ditto.
+
+Fri Sep 28 02:57:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * passwd.cc (read_etc_passwd): Don't bother with locking when
+ in cygwin initialization since there is only one thread.
+ * grp.cc (read_etc_group): Ditto.
+
+Fri Sep 28 01:50:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * pipe.cc (fhandler_pipe::hit_eof): Return correct value when there is
+ no EOF event available.
+
+Sat Sep 28 00:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Move setting the access after evaluating fd.
+ Remove useless comment. Explain copy-on-write problem of 9x
+ more detailed. Don't set access to FILE_MAP_COPY on 9x only
+ when anonymous mapping is requested.
+ (fhandler_disk_file::mmap): Remove useless device check.
+ Add debug output.
+
+Fri Sep 27 07:35:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * Makefile.in: Only stamp winver_stamp on success.
+
+Wed Sep 26 16:02:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * select.cc (peek_pipe): REALLY only grab mutex when we actually got
+ something from the pipe.
+
+Tue Sep 25 21:25:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond::BroadCast): Use address with verifyable_object_isvalid().
+ (pthread_cond::Signal): Ditto.
+ (__pthread_create): Ditto.
+ (__pthread_cleanup): Ditto.
+ (__pthread_attr_init): Ditto.
+ (__pthread_attr_getinheritsched): Ditto.
+ (__pthread_attr_getschedparam): Ditto.
+ (__pthread_attr_getschedpolicy): Ditto.
+ (__pthread_attr_getscope): Ditto.
+ (__pthread_attr_setdetachstate): Ditto.
+ (__pthread_attr_getdetachstate): Ditto.
+ (__pthread_attr_setinheritsched): Ditto.
+ (__pthread_attr_setschedparam): Ditto.
+ (__pthread_attr_setschedpolicy): Ditto.
+ (__pthread_attr_setscope): Ditto.
+ (__pthread_attr_setstacksize): Ditto.
+ (__pthread_attr_getstacksize): Ditto.
+ (__pthread_attr_destroy): Ditto.
+ (__pthread_join): Ditto.
+ (__pthread_detach): Ditto.
+ (__pthread_suspend): Ditto.
+ (__pthread_continue): Ditto.
+ (__pthread_getschedparam): Ditto.
+ (__pthread_getsequence_np): Ditto.
+ (__pthread_key_create): Ditto.
+ (__pthread_key_delete): Ditto.
+ (__pthread_setschedparam): Ditto.
+ (__pthread_setspecific): Ditto.
+ (__pthread_getspecific): Ditto.
+ (__pthread_cond_destroy): Ditto.
+ (__pthread_cond_init): Ditto.
+ (__pthread_cond_broadcast): Ditto.
+ (__pthread_cond_signal): Ditto.
+ (__pthread_cond_timedwait): Ditto.
+ (__pthread_cond_wait): Ditto.
+ (__pthread_condattr_init): Ditto.
+ (__pthread_condattr_getpshared): Ditto.
+ (__pthread_condattr_setpshared): Ditto.
+ (__pthread_condattr_destroy): Ditto.
+ (__pthread_kill): Ditto.
+ (__pthread_mutex_init): Ditto.
+ (__pthread_mutex_getprioceiling): Ditto.
+ (__pthread_mutex_lock): Ditto.
+ (__pthread_mutex_trylock): Ditto.
+ (__pthread_mutex_unlock): Ditto.
+ (__pthread_mutex_destroy): Ditto.
+ (__pthread_mutex_setprioceiling): Ditto.
+ (__pthread_mutexattr_getprotocol): Ditto.
+ (__pthread_mutexattr_getpshared): Ditto.
+ (__pthread_mutexattr_gettype): Ditto.
+ (__pthread_mutexattr_init): Ditto.
+ (__pthread_mutexattr_destroy): Ditto.
+ (__pthread_mutexattr_setprotocol): Ditto.
+ (__pthread_mutexattr_setprioceiling): Ditto.
+ (__pthread_mutexattr_getprioceiling): Ditto.
+ (__pthread_mutexattr_setpshared): Ditto.
+ (__pthread_mutexattr_settype): Ditto.
+ (__sem_init): Ditto.
+ (__sem_destroy): Ditto.
+ (__sem_wait): Ditto.
+ (__sem_trywait): Ditto.
+ (__sem_post): Ditto.
+ (verifyable_object_isvalid): Recieve a pointer to a pointer for verification.
+ (__pthread_mutexattr_getprotocol): Fix typo in magic number.
+ (__pthread_mutexattr_getpshared): Ditto.
+ (__pthread_mutexattr_gettype): Ditto.
+ * thread.h (verifyable_object_isvalid): Change prototype to recieve a pointer to a
+ pointer for verification.
+ * include/pthread.h: Fix typo for __cleanup_routine_type typedef. (Contrib from Net).
+
+Tue Sep 25 02:09:42 2001 Christopher Faylor <cgf@redhat.com>
+
+ * select.cc (fhandler_tty_common::ready_for_read): Rewrite to correctly
+ call peek_pipe.
+
+Mon Sep 24 18:46:39 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * select.cc (peek_pipe): Only grab mutex when we actually got something
+ from the pipe.
+
+Mon Sep 24 17:41:03 2001 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_pipe::hit_eof): New method.
+ (writepipe_exists): New class element.
+ (orig_pid): Ditto.
+ (id): Ditto.
+ (is_slow): Eliminate.
+ * pipe.cc (fhandler_pipe::set_close_on_exec): Set inheritance on
+ writepipe_exists, if it exists.
+ (fhandler_pipe::hit_eof): New method, modelled after tty.
+ (fhandler_pipe::dup): Duplicate writepipe_exists, if it exists.
+ (make_pipe): Set up a dummy event for pipes on windows 9x. The
+ nonexistence of this event means that the write side of the
+ pipe has closed.
+ (_dup): Move to syscalls.cc
+ (_dup2): Ditto.
+
+ * dtable.cc (dtable::build_fhandler): Fill out set_names here, if
+ appropriate.
+ * syscalls.cc (_open): Call set_names in build_fhandler.
+
+Sun Sep 23 16:55:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (_open): Set name in fhandler object after successful
+ creation.
+ (stat_dev): Set device type to block device in FH_FLOPPY case.
+
+Sun Sep 23 11:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dtable.cc (dtable::build_fhandler): Initialize unit when using
+ optional path_conv argument.
+
+Sat Sep 22 17:33:45 2001 Christopher Faylor <cgf@cygnus.com>
+ Corinna Vinschen <corinna@vinschen.de>
+
+ * dtable.cc (dtable::build_fhandler): Accept an optional path_conv
+ argument. If available, use this to calculate path name and device
+ number.
+ * dtable.h (dtable): Reflect above change.
+ * fhandler.h (fhandler_base): Declare virtual method which accepts
+ path_conv rather than path string as first argument.
+ * fhandler.cc (fhandler_base::open): Define above new method.
+ * syscalls.cc (_open): Set aside a path_conv variable for use in
+ build_fhandler and subsequent call to open.
+
+Sat Sep 22 12:44:57 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (setup_handler): Always relinquish lock after we've
+ interrupted.
+ * fhandler.cc: Move pipe methods to pipe.cc.
+ * fhandler.h (fhandler_pipe): Add new methods.
+ * fork.cc (sync_with_parent): Make error messages more informative.
+ * pipe.cc (fhandler_pipe::fhandler_pipe): Move here from fhandler.cc.
+ (fhandler_pipe::lseek): Ditto.
+ (fhandler_pipe::set_close_on_exec): New method.
+ (fhandler_pipe::read): Ditto.
+ (fhandler_pipe::close): Ditto.
+ (fhandler_pipe::dup): Ditto.
+ (make_pipe): Create the guard mutex on the read side of the pipe.
+ * select.cc (peek_pipe): Use guard_mutex to discover if we have the
+ right to read on this pipe.
+ (fhandler_pipe::readh_for_read): Pass the read pipe guard mutex to
+ peek_pipe.
+ * syscalls.cc (_read): Always detect signal catchers, for now.
+
+ * debug.cc (makethread): Eliminate hack to make thread inheritable.
+ * sigproc.cc (subproc_init): Don't use hack to make thread inheritable.
+
+Thu Sep 20 16:48:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_base::set_inheritance): Just use
+ DUPLICATE_CLOSE_SOURCE to change inheritance. Eliminate all other
+ logic dealing with closed handles.
+ * fhandler.h (fhandler_base::set_inheritance): Reflect above change.
+ * fhandler_tty.cc (fhandler_tty_common::set_close_on_exec): Ditto.
+
+Thu Sep 20 13:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::fixup_after_exec): Close
+ socket only when not using Winsock2.
+
+Thu Sep 20 13:20:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_socket::fixup_after_exec): Remove inline
+ implementation.
+ (fhandler_dev_raw::fixup_after_exec): Ditto.
+ * fhandler_raw.cc (fhandler_dev_raw::fixup_after_fork): Don't
+ duplicate buffer on fork to avoid memory leak.
+ (fhandler_dev_raw::fixup_after_exec): New implementation equal to
+ former fixup_after_fork() implementation.
+ * fhandler_socket.cc (fhandler_socket::fixup_after_fork): Do
+ nothing when not using Winsock2.
+ (fhandler_socket::fixup_after_exec): New implementation.
+ (fhandler_socket::set_close_on_exec): Never call set_inheritance().
+
+Thu Sep 20 9:55:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::set_inheritance): If available,
+ use SetHandleInformation() to set inheritance.
+ * wincap.cc: Set flag has_set_handle_information_on_console_handles
+ appropriately.
+ * wincap.h: Add flag has_set_handle_information_on_console_handles.
+
+Wed Sep 19 12:24:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * lib/getopt.c (__progname): Don't declare if not compiling for cygwin.
+
+Wed Sep 19 18:07:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * lib/getopt.c (getopt_long): Avoid compiler warning.
+
+Wed Sep 19 11:52:42 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * lib/getopt.c: Use __progname==__argv[0] when not compiling for cygwin.
+
+ * scandir.cc (scandir): Use correct default when compar == NULL.
+
+Wed Sep 19 17:49:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::fhandler_socket): Revert
+ memory allocation to use cmalloc again.
+
+Tue Sep 18 21:04:26 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din (__argv): Export.
+ (__argc): Ditto.
+ (__progname): Ditto.
+ * include/getopt.h (getopt_long): constify arguments.
+ * lib/getopt.c: Import new file from NetBSD.
+
+Tue Sep 18 18:21:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Don't reuse anonymous memory in MAP_FIXED case.
+
+Mon Sep 17 17:29:25 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/io.h: Add access declaration.
+
+Mon Sep 17 14:04:27 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (rmdir): Set cwd to some other location if attempting to
+ rmdir current working directory.
+
+Sun Sep 16 23:04:31 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.h (not_open): Assure inline.
+ * fhandler.h (operator []): Make const.
+
+Sun Sep 16 23:02:57 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * sync.cc (muto::~muto): Fix typo which stopped muto event handle from
+ ever being closed.
+
+2001-09-16 Egor Duda <deo@logos-m.ru>
+
+ * path.cc (symlink): Check arguments for validity.
+ (getcwd): Ditto.
+ * syscalls.cc (ftruncate): Ditto.
+ * times.cc (times): Ditto.
+ * uname.cc (uname): Ditto.
+
+Sat Sep 15 22:54:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * net.cc (dup_servent_ptr): Detect old Windows 95 misaligned structure
+ and realign appropriately.
+
+Sat Sep 15 00:28:40 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Generate libcygwin.a during the link pass rather than as
+ a separate dlltool step.
+ * dcrt0.cc (_dll_crt0): pppid_handle could be NULL. Don't close it if
+ so.
+
+Fri Sep 14 20:48:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dcrt0.cc (dll_crt0_1): Create vfork main storage here so that it can
+ be queried in waitsig later.
+ * sigproc.cc (wait_sig): Don't deliver a signal if in a vfork.
+ * sigproc.h (sigframe::init): New method.
+ (sigframe): Use init.
+ * perthread.h: Declare main_vfork.
+ * fork.cc (vfork): Deliver all signals on parent return from vfork.
+
+Fri Sep 14 10:21:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dcrt0.cc (_dll_crt0()): Don't call wincap.init() here.
+
+Fri Sep 14 00:37:54 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fork.cc (vfork): Avoid recursive vforks.
+
+Fri Sep 14 00:18:52 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.h (fhandler_pipe::is_slow): Return true only if pipes are
+ reliable (i.e., not Win9x).
+ * wincap.cc: Make statics NO_COPY to avoid fork overhead.
+
+Thu Sep 13 23:01:00 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * grp.cc (read_etc_group): Just reuse group_buf storage for subsequent
+ reread of /etc/group.
+ * passwd.cc (read_etc_passwd): Just reuse passwd_buf storage for
+ subsequent reread of /etc/passwd.
+
+Thu Sep 13 20:46:05 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (dup_now): New function.
+ (cygheap_setup_for_child): Accept new argument controlling whether to
+ delay copying of cygheap to shared memory region.
+ (cygheap_setup_for_child_cleanup): Accept new arguments controlling
+ whether to copy cygheap at this point.
+ * cygheap.h: Reflect above changes.
+ * fork.cc (fork_parent): Break copying of cygheap into two parts when
+ fork_fixup is required so that the child can see the parent's changes.
+ (vfork): Do stack cleanup prior to forcing a fork error.
+ * spawn.cc (spawn_guts): Ditto.
+
+Thu Sep 13 17:14:59 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (ccalloc): Pass correct length to creturn so that
+ cygheap_max is correctly calculated.
+
+Wed Sep 12 21:06:38 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sync.cc (muto::acquire): Fix while/if typo.
+
+Wed Sep 12 23:06:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * wincap.cc (wincapc::init): Simplify W2K/XP case.
+
+Wed Sep 12 23:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * wincap.cc (wincapc::init): Set os name to "NT" on XP, too.
+
+Wed Sep 12 19:00:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in: Build wincap.o.
+ * wincap.cc: New file.
+ * wincap.h: Ditto.
+ * autoload.cc: Add dynamic load statement for `CreateHardLinkA'.
+ * dcrt0.cc (os_being_run): Eliminated.
+ (osname): Ditto.
+ (iswinnt): Ditto.
+ (set_os_type): Ditto.
+ (dll_crt0_1): Call wincap.init() instead of set_os_type().
+ (_dll_crt0): Ditto.
+ * environ.cc (set_chunksize): New function.
+ (parse_thing): `forkchunk' setting now invokes function `set_chunksize'.
+ * fork.cc (chunksize): Eliminated. Moved to be member of wincap.
+ * host_dependent.h: Removed.
+ * syscalls.cc (_link): Try using `CreateHardLinkA' first, if available.
+ * cygheap.cc, dcrt0.cc, delqueue.cc, dir.cc,
+ environ.cc, fhandler.cc, fhandler.h, fhandler_console.cc,
+ fhandler_mem.cc, fork.cc, mmap.cc, net.cc, pinfo.cc, pinfo.h,
+ security.cc, syscalls.cc, sysconf.cc, syslog.cc, thread.cc,
+ times.cc, tty.cc, uinfo.cc, uname.cc, winsup.h: Use new wincap
+ capability check throughout.
+ * winsup.h: Include wincap.h. Eliminate extern declarations of
+ `os_being_run' and `iswinnt'. Eliminate `os_type" definition.
+ * include/cygwin/version.h: Bump version to 1.3.4.
+
+Wed Sep 12 01:03:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (call_signal_handler_now): Add additional guard against
+ inappropriately calling signal handler.
+ * syscalls.cc (_read): Reset errno if not exiting due to signal.
+
+Wed Sep 12 13:03:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * autoload.cc (LoadDLLfuncEx): Auto load TryEnterCriticalSection - it's
+ an NT only call.
+ * thread.cc (pthread_cond::TimedWait): Use critical sections for NT.
+ (pthread_cond::fixup_after_fork): Don't detect bad apps.
+ (pthread_mutex::pthread_mutex): Use critical sections for NT.
+ (pthread_mutex::~pthread_mutex): Ditto.
+ (pthread_mutex::Lock): Ditto.
+ (pthread_mutex::TryLock): Ditto.
+ (pthread_mutex::UnLock): Ditto.
+ (pthread_mutex::fixup_after_fork): Ditto. Also do not detect bad apps.
+ (__pthread_mutex_trylock): Move WIN32 specific test into the class
+ method.
+ (__pthread_mutex_destroy): Prevent dereferencing passed pointer without
+ valid address.
+ * thread.h (pthread_mutex): Use critical sections for NT.
+
+Tue Sep 11 21:55:37 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.h (sigframe::unregister): Return true/false whether this
+ frame is capable of responding to signals.
+ * exceptions.cc (sigframe::call_signal_handler): Don't call signal
+ handler if it is not armed for this thread.
+
+Tue Sep 11 11:23:10 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din: Remove cygwin_getshared.
+ * shared.cc: Ditto.
+ * include/cygwin/version.h: Bump API minor number.
+
+Tue Sep 11 11:14:11 2001 Dmitry Timoshkov <dmitry@baikal.ru>
+
+ * dtable.cc (dtable::build_fhandler): Fix incorrect test for socket.
+
+Tue Sep 11 21:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond::~pthread_cond): Fix incorrect use of
+ InterlockExchangePointer.
+ (pthread_mutex::~pthread_mutex): Ditto.
+ (semaphore::~semaphore): Ditto.
+
+Tue Sep 11 18:15:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * dcrt0.cc (cygwin_finished_initializing): Copy _mtinterf on fork.
+ * fork.cc (fork_child): Fixup thread-related structures after fork.
+ * thread.cc (MTinterface::Init): Initialise the new mutex, condition
+ and semaphore lists.
+ (MTinterface::fixup_after_fork): Iterate through each list and fixup
+ the objects.
+ (pthread_cond::pthread_cond): Add this to the condition list.
+ (pthread_cond::~pthread_cond): Remove this from the condition list.
+ (pthread_cond::fixup_after_fork): Recreate as best we can the pre-fork
+ state.
+ (pthread_mutex::pthread_mutex): Add this to the mutex list.
+ (pthread_mutex::~pthread_mutex): Remove this from the mutex list.
+ (pthread_mutex::fixup_after_fork): Recreate as best we can the pre-fork
+ state.
+ (semaphore::semaphore): Store the initial value, and add this to the
+ semaphore list.
+ (semaphore::~semaphore): Remove this from the semaphore list.
+ (semaphore::Post): Increment the current semaphore value.
+ (semaphore::TryWait): Decrement the current semaphore value.
+ (semaphore::Wait): Ditto.
+ (semaphore::fixup_after_fork): Recreate the pre-fork state as best we
+ can.
+ * thread.h (pthread_mutex): New members to allow fixup_after_fork.
+ (pthread_cond): Ditto.
+ (semaphore): Ditto.
+ (MTinterface): New list heads for tracking conds and semaphores.
+
+Sun Sep 9 22:11:27 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.cc (dtable::fixup_after_fork): Use SetStdHandle appropriately
+ on inherited fds.
+
+Sun Sep 9 20:09:11 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.cc (NZOMBIES): Reduce substantially to minimize memory use.
+
+Mon Sep 10 08:28:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.h (MT_Interface): Remove pshared mutex array. Add a
+ threadsafe list for mutex tracking (for fixup after fork).
+ * thread.cc (MTInterface::Init): Remove pshared mutex array.
+ (pthread_mutex::pthread_mutex): Remove pshared mutex functionality.
+ Fail with EINVAL on attempts to use pshared functionality.
+ (__pthread_mutex_getpshared): Remove.
+ (__pthread_cond_timedwait): Remove pshared mutex functionality.
+ (__pthread_cond_wait): Ditto.
+ (__pthread_mutex_init): Ditto.
+ (__pthread_mutex_getprioceiling): Ditto.
+ (__pthread_mutex_lock): Ditto.
+ (__pthread_mutex_trylock): Ditto.
+ (__pthread_mutex_unlock): Ditto.
+ (__pthread_mutex_destroy): Ditto.
+ (__pthread_mutex_setprioceiling): Ditto.
+ (__pthread_mutexattr_setpshared): Ditto.
+
+Sun Sep 9 23:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * pwdgrp.h (pwdgrp_check::set_last_modified): Call GetFileTime()
+ instead of GetFileInformationByHandle().
+
+Sun Sep 9 15:59:53 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * heap.h (inheap): Rewrite macro to accommodate removal of brk macros
+ below.
+
+Sun Sep 9 15:02:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cygheap_fixup_in_child): Clear cygheap->base so that heap
+ is not forced to start at the same place in execed process.
+ * heap.cc: Remove brk* macros for clarity throughout.
+ * heap.h: Ditto.
+ * shared.cc (shared_info::initialize): Move heap_chunk test into
+ heap_chunk_size().
+ (heap_chunk_size): Check for chunk size here. Don't go to registry if
+ heap_chunk_in_mb is already set.
+
+ * smallprint.c (console_printf): Add Windows 95 concessions.
+
+Sun Sep 9 13:01:06 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h (PROC_MAGIC): Bump magic number.
+
+Sun Sep 9 18:36:00 2001 Corinna Vinschen <corinna@vinschen.de>
+ Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (init_cygheap::etc_changed): New method to signal
+ a change in /etc.
+ * cygheap.h (struct init_cygheap): Add member `etc_changed_h'
+ and method `etc_changed'.
+ * grp.cc (enum grp_state): Eliminate.
+ (class grp_check): Ditto.
+ (group_state): Define as `class pwdgrp_check'.
+ (parse_grp): Remeber path and modification time of /etc/group file.
+ * passwd.cc (enum_pwd_state): Eliminate.
+ (class pwd_check): Ditto.
+ (passwd_state): Define as `class pwdgrp_check'.
+ (read_etc_passwd): Remember path and modification time of /etc/passwd
+ file.
+ * pwdgrp.h: New file.
+ (enum pwdgrp_state): Substitutes `pwd_state' and `grp_state'.
+ (class pwdgrp_check): Substitutes `pwd_check' and `grp_check'.
+
+Sun Sep 9 14:31:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/version.h: Bump API minor version to 45 according
+ to adding the gamm*_r functions.
+
+Sat Sep 8 23:32:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fork.cc (fork_parent): Stop malloc activity while fork is in control
+ of the heap.
+ * sigproc.cc (NZOMBIES): Rename from ZOMBIEMAX for clarity.
+ (zombies): Revert to original behavior. Allocating zombie array
+ resulted in performance hit.
+ * winsup.h: Declare malloc lock routines.
+
+Fri Sep 7 21:35:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din: Add gamm*_r function exports.
+
+Fri Sep 7 17:11:11 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.h (init_cygheap): Move heap pointers here.
+ * include/sys/cygwin.h (perprocess): Remove heap pointers.
+ * dcrt0.cc (__cygwin_user_data): Reflect obsolete perprocess stuff.
+ (_dll_crt0): Don't initialize heap pointers.
+ (cygwin_dll_init): Ditto.
+ (release_upto): Use heap pointers from cygheap.
+ * heap.h: Ditto.
+ * fork.cc (fork_parent): Ditto. Don't set heap pointers in ch.
+ (fork_child): Remove obsolete sigproc_fixup_after_fork.
+ * shared.cc (memory_init): Reorganize so that cygheap initialization is
+ called prior to regular heap since regular heap uses cygheap now.
+ * sigproc.cc (proc_subproc): Eliminate zombies allocation.
+ (sigproc_init): Move zombies alloation here. Don't free up array on
+ fork, just reuse it.
+ (sigproc_fixup_after_fork): Eliminate.
+ * sigproc.h: Ditto.
+ * include/cygwin/version.h: Reflect change to perprocess structure.
+
+Fri Sep 7 10:53:34 2001 Jason Tishler <jason@tishler.net>
+
+ * poll.cc (poll): Change implementation to only call select() when no
+ invalid file descriptors are specified.
+
+Fri Sep 7 10:27:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/limits.h: Define PIPE_BUF.
+ * syscalls.cc (fpathconf): Use PIPE_BUF instead of numerical constant.
+ (pathconf): Ditto.
+
+Thu Sep 6 20:04:05 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_socket.cc (fhandler_socket::fhandler_socket): Ensure that
+ prot_info_ptr is zeroed for later use.
+
+Thu Sep 6 14:03:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cygheap_fixup_in_child): Don't consider a NULL bucket as
+ a candidate for deletion. It is actually the end of a linked list
+ chain.
+
+ * exceptions.cc (open_stackdumpfile): Default to "unknown" program name
+ if myself->progname hasn't been filled out yet.
+
+Thu Sep 6 01:16:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Move appropriate variables to NO_COPY segment, throughout.
+
+Thu Sep 6 00:40:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Remove initialization of static or global values to zero, throughout.
+ This just needlessly grows the size of the DLL.
+ * tty.cc (tty::alive): Make inuse handle non-inheriting on open, just
+ for thread safety.
+
+Wed Sep 5 23:36:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.h (init_cygheap): Move bucket array here from cygheap.cc.
+ * cygheap.cc: Throughout use bucket array from cygheap.
+
+ * sigproc.cc (proc_subproc): Dynamically allocate zombie buffer to save
+ DLL space.
+ (sigproc_fixup_after_fork): Free zombie array after a fork.
+ * sigproc.h (sigproc_fixup_after_fork): Declare.
+
+2001-09-06 Egor Duda <deo@logos-m.ru>
+
+ * dir.cc (mkdir): Expand buffer for security descriptor to 4K to avoid
+ stack corruption.
+ * fhandler.cc (fhandler_base::open): Ditto.
+ * path.cc (symlink): Ditto.
+
+Wed Sep 5 21:35:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * winver.rc: Change copyright to include 2001.
+
+Wed Sep 5 12:12:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_floppy.cc (fhandler_floppy::lseek): Remove iswinnt check.
+
+Wed Sep 5 11:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::close): Change 2MSL value
+ according to MSDN.
+
+Wed Sep 5 10:14:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_connect): Add WSAEALREADY and WSAEINVAL handling
+ for non-blocking sockets.
+
+Tue Sep 4 22:42:13 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (ctrl_c_handler): Only send SIGINT when we have a
+ controlling terminal and we are the head of the process group.
+
+Tue Sep 4 16:48:14 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * thread.cc (InterlockedExchangePointer): Don't define if it already
+ exists.
+
+Tue Sep 4 22:14:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * uname.cc (uname): Eliminate os specific retrieving of x86
+ processor type.
+
+2001-09-04 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * fhandler_console.cc (fhandler_console::char_command): Save the cursor
+ position relative to the top of the window.
+ * fhandler_cc (fhandler_console::write): Ditto.
+
+Mon Sep 3 21:06:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (opendir): Write version information to __d_dirent->d_version.
+
+Mon Sep 3 18:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din: Add `dirfd'.
+ * dir.cc (dirfd): New function.
+ (opendir): Open a directory file descriptor and save it in
+ __d_dirent->d_fd.
+ (closedir): Close directory file descriptor.
+ * include/cygwin/version.h: Bump API minor version to 44.
+
+Sun Sep 2 22:09:31 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h: Modify magic number.
+ * dcrt0.cc (_cygwin_testing): Define.
+ (_dll_crt0): Set _cygwin_testing if CYGWIN_TESTING environment variable
+ exists. Don't issue "conflicting versions" error if _cygwin_testing is
+ true.
+ * shared.cc (shared_name): Use _cygwin_testing global rather than
+ testing the environment.
+ * syscalls.cc (_write): Remove debugging info.
+
+Sat Sep 1 01:37:13 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * tty.cc (tty::create_inuse): Eliminate unneeded argument.
+ * tty.h: Reflect above change.
+ * fhandler_tty.cc: Reflect argument reduction in tty::create_inuse,
+ throughout. Always make inuse inheritable.
+
+Sat Sep 1 01:10:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * debug.cc (mark_closed): Rename from debug_mark_closed and make
+ static.
+ (setclexec_pid): New function for marking saved handle as
+ close-on-exec.
+ (delete_handle): New function.
+ (debug_fixup_after_fork): New function.
+ * debug.h: Declare new functions, remove obsolete ones.
+ * fork.cc (debug_fixup_after_fork): Call to cleanup close-on-exec
+ handles.
+
+ * fhandler.cc (fhandler_disk_file::close): Minor reorg.
+ (fhandler_base::set_inheritance): Set flag appropriately for debugging
+ when close-on-exec so forked process can delete closed handles.
+ * tty.h (open_output_mutex): Eliminate unneeded argument.
+ (open_input_mutex): Ditto.
+ * fhandler_tty.cc (fhandler_tty_slave::open): reflect open_*_mutex
+ argument changes.
+ * fhandler.h (fhandler_socket): Make saw_shutdown_* functions type
+ bool.
+ * tty.cc (tty::get_event): Eliminate unneeded argument.
+ (tty::common_init): Reflect change to get_event. Events should always
+ be inherited.
+
+Fri Aug 31 21:39:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (create_token): Change initialization of `exp' to comply
+ with new LARGE_INTEGER definition in winnt.h.
+
+Fri Aug 31 13:58:51 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.sc: Revert to previous NO_COPY behavior.
+ * winsup.h: Ditto.
+ * sigproc.cc: Ditto.
+ * autoload.cc: Ditto.
+
+Fri Aug 31 00:56:26 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.sc: New file -- linker script for building cygwin DLL.
+ * Makefile.in: Use linker script to control location of cygheap.
+ * cygheap.cc (buckets): Make static.
+ (init_cheap): Remove special iswinnt handling. Allocate cygheap at a
+ fixed location. Display more info when allocation fails.
+ (cygheap_fixup_in_child): Try harder to move cygheap to correct
+ location. Display more info when allocation fails.
+ * fhandler.h (fhandler_socket): Add macros for tracking socket shutdown
+ state.
+ * net.cc (cygwin_shutdown): Set appropriate shutdown value for future
+ use.
+ * select.cc (select_stuff::cleanup): New method.
+ (cygwin_select): Call cleanup explicitly to avoid a race.
+ (select_stuff:~select_stuff): Call cleanup chain via cleanup method.
+ (fhandler_socket::select_read): Set *_ready when shutdown has been
+ called on the socket.
+ (fhandler_socket::select_write): Ditto.
+ (fhandler_socket::select_except): Ditto.
+
+ * winsup.h: Move NO_COPY to "COMMON" section.
+ * autoload.cc (wsock_started): Avoid initializing NO_COPY value.
+ * sigproc.cc: Remove initialization from NO_COPY variables.
+ (sigproc_init): Initialize sig_loop_wait here, rather than via
+ initialization.
+ (subproc_init): Initialize proc_loop_wait here, rather than via
+ initialization.
+
+Thu Aug 30 10:19:00 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * select.cc (select_read): Add setting read_ready flag.
+ (select_write): Add setting write_ready flag.
+
+Wed Aug 29 00:40:42 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Avoid splitting off leading '/' in path
+ component when building a symlink.
+
+Wed Aug 29 0:45:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * resource.cc (getrlimit): Return actual values on RLIMIT_STACK.
+
+Tue Aug 28 16:37:17 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dir.cc (rmdir): Report ENOENT when file doesn't exist rather than
+ ENOTDIR.
+
+Mon Aug 27 11:58:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * select.cc (cygwin_select): Ensure that arguments are zeroed on
+ timeout.
+ (select_stuff::wait): Ditto.
+
+2001-08-24 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * syscalls.cc (check_tty_fds): New function. Check whether there is a
+ fd referring to pty slave.
+ (setsid): Don't detach console if the process has a pty slave.
+
+Fri Aug 24 8:54:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (free_addr_list): Add define for symmetry.
+ (free_hostent_ptr): Use free_addr_list to free h_addr_list element.
+
+Thu Aug 23 16:00:09 2001 Jason Tishler <jason@tishler.net>
+
+ * net.cc (dup_addr_list): New static function.
+ (dup_hostent_ptr): Use dup_addr_list instead of dup_char_list in order
+ to handle embedded null characters.
+
+Wed Aug 22 22:23:14 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.cc (dtable::dup2): Allow extension of fd table by dup2.
+ * syscalls.cc: Minor code cleanup.
+ (fpathconf): Check for bad fd before doing anything else.
+ * termios.cc (tcsetattr): Don't convert to new termios if bad fd.
+ (tcgetattr): Minor debugging tweak.
+
+Wed Aug 22 23:41:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_inet_ntoa): Rearrange previous patch to use
+ thread local buffer space when compiled thread safe.
+ (cygwin_getprotobyname): Ditto.
+ (cygwin_getprotobynumber): Ditto.
+ (cygwin_getservbyname): Ditto.
+ (cygwin_getservbyport): Ditto.
+ (cygwin_gethostbyname): Ditto.
+ (cygwin_gethostbyaddr): Ditto. Move near to cygwin_gethostbyname.
+ * thread.h (struct _winsup_t): Add pointers for above used buffer space.
+ * passwd.cc (getpwduid): Remove initializing passwd.
+ (setpwent): Ditto.
+ (endpwent): Ditto.
+ (setpassent): Ditto.
+
+Wed Aug 22 13:41:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * smallprint.c (console_printf): New function.
+ * dcrt0.cc (dll_crt0_1): Use console_printf for debugging output.
+ * debug.cc (debug_mark_closed): New function.
+ (close_handle): Use debug_mark_closed.
+ * debug.h: Declare new functions.
+ * dtable.cc (dtable::build_fhandler): Remove unneeded extern.
+ * spawn.cc: Cosmetic changes.
+ * winsup.h: Define NO_COPY for C files, too. Declare a global.
+
+Wed Aug 22 17:31:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (free_char_list): New static function.
+ (dup_char_list): Ditto.
+ (free_protoent_ptr): Ditto.
+ (dup_protoent_ptr): Ditto.
+ (free_servent_ptr): Ditto.
+ (dup_servent_ptr): Ditto.
+ (free_hostent_ptr): Ditto.
+ (dup_hostent_ptr): Ditto.
+ (cygwin_inet_ntoa): Use local static buffer to allow propagating of
+ the result to child processes.
+ (cygwin_getprotobyname): Ditto.
+ (cygwin_getprotobynumber): Ditto.
+ (cygwin_getservbyname): Ditto.
+ (cygwin_getservbyport): Ditto.
+ (cygwin_gethostbyname): Ditto.
+ (cygwin_gethostbyaddr): Ditto.
+
+Mon Aug 20 11:56:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (init_cheap): Allocate cygheap in shared memory for Windows NT.
+
+Thu Aug 16 09:38:59 2001 Jason Tishler <jason@tishler.net>
+
+ * fhandler_socket.cc (fhandler_socket::create_secret_event): Relax
+ security of secret_event so AF_UNIX socket clients can connect to
+ servers even if running under a different user account.
+ (fhandler_socket::check_peer_secret_event): Ditto.
+
+Thu Aug 16 16:26:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * resource.cc (getrlimit): Return getdtablesize () as current limit
+ on RLIMIT_NOFILE.
+ * syscalls.cc (getdtablesize): Return OPEN_MAX if current dtable size
+ is less than OPEN_MAX, the current dtable size otherwise.
+ * sysconf.cc (sysconf): Return getdtablesize () on _SC_OPEN_MAX.
+
+Thu Aug 16 16:17:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * resource.cc (getrlimit): Return OPEN_MAX as current limit
+ on RLIMIT_NOFILE.
+ * syscalls.cc (getdtablesize): Return OPEN_MAX.
+ * sysconf.cc (sysconf): Return OPEN_MAX on _SC_OPEN_MAX.
+ * include/limits.h (OPEN_MAX): Define as 256.
+
+Wed Aug 15 12:43:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * times.cc (utimes): Revert previous change. Just open the
+ file using FILE_WRITE_ATTRIBUTES instead of GENERIC_WRITE
+ on NT/W2K.
+
+Wed Aug 15 12:18:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (set_nt_attribute): Return always -1 in case of
+ a failure.
+ * times.cc (utimes): On NTFS with ntsec ON, change the file's
+ security descriptor temporarily to acquire write access if
+ opening the file failed.
+
+Wed Aug 15 9:42:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::is_nonblocking): New method.
+ (fhandler_base::set_nonblocking): Ditto.
+ * fhandler.h (fhandler_base): Declare new methods `is_nonblocking' and
+ `set_nonblocking'.
+ * fhandler_socket.cc (fhandler_socket::ioctl): Use `set_nonblocking'.
+ * fhandler_tty.cc (fhandler_pty_master::process_slave_output):
+ Use `is_nonblocking'.
+ (fhandler_tty_slave::read): Ditto.
+ (fhandler_tty_slave::ioctl): Use `set_nonblocking'.
+ (fhandler_pty_master::ioctl): Ditto.
+ * net.cc (cygwin_sendto): Fallback to winsock 1 functionality
+ in case of nonblocking IO.
+ (cygwin_recvfrom): Ditto.
+ (cygwin_recv): Ditto.
+ (cygwin_send): Ditto.
+ * syscalls.cc (_read): Use `is_nonblocking'.
+
+Tue Aug 14 11:05:26 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump API version.
+
+2001-08-14 Egor Duda <deo@logos-m.ru>
+
+ * spawn.cc (spawn_guts): Enable appropriate privilege before
+ loading user's registry hive.
+
+Mon Aug 13 22:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::fcntl): Use new O_NONBLOCK_MASK define.
+ * fhandler.h: Move definitions of O_NOSYMLINK, O_DIROPEN and
+ OLD_O_NDELAY from winsup.h to here. Add O_NONBLOCK_MASK define.
+ * fhandler_socket.cc (fhandler_socket::close): Add hack to allow
+ a graceful shutdown even if shutdown() hasn't been called by the
+ application. Add debug output.
+ (fhandler_socket::ioctl): Set fhandler's NONBLOCK flag according
+ to FIONBIO setting.
+ (fhandler_socket::fcntl): Use new O_NONBLOCK_MASK define. Actually
+ set `request' before using it.
+ * fhandler_tty.cc: Use new O_NONBLOCK_MASK define throughout.
+ (fhandler_tty_slave::ioctl): Set fhandler's NONBLOCK flag according
+ to FIONBIO setting.
+ (fhandler_pty_master::ioctl): Ditto.
+ * net.cc (wsock_event::prepare): Compare WSACreateEvent return code
+ with `WSA_INVALID_EVENT' according to MSDN.
+ * syscalls.cc (_read): Use new O_NONBLOCK_MASK define.
+
+Wed Aug 8 15:24:59 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/wchar.h: Define __need_wint_t.
+
+Wed Aug 8 11:46:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (alloc_sd): Revert to setting inheritance attribute for
+ permissions given to directories. Never set inheritance on NULL ACE.
+
+Tue Aug 7 18:11:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (alloc_sd): Don't set FILE_DELETE_CHILD for group
+ if S_ISVTX attribute is given.
+ * dir.cc (mkdir): Allow immediate setting of S_ISUID, S_ISGID and
+ S_ISVTX attribute.
+ * syscalls.cc (_open): Ditto.
+
+Tue Aug 7 16:24:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (mkdir): Set security attributes correctly for
+ CreateDirectoryA () call if ntsec is on. Don't call
+ set_file_attributes () then.
+ * fhandler.cc (fhandler_base::open): Ditto for CreateFileA () call.
+ * path.cc (symlink): Ditto.
+ * security.cc (set_security_attribute): New function.
+ * security.h: Add declaration for `allow_ntea' and
+ `set_security_attribute'.
+
+Tue Aug 7 10:54:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (class grp_check): New class. Make `group_state'
+ a member of class grp_check.
+ (read_etc_group): Free former allocated memory on reread.
+ * passwd.cc (class pwd_check): New class Make `passwd_state'
+ a member of class pwd_check.
+ (read_etc_passwd): Free former allocated memory on reread.
+
+Tue Aug 7 01:13:58 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_console.cc (get_tty_stuff): Don't initialize shared memory
+ console area if it is already initialized.
+
+ * fhandler_termios.cc (fhandler_termios::tcsetpgrp): Augment debugging
+ info.
+
+Mon Aug 6 19:58:43 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cygheap_root::set): Avoid treating '/' specially.
+
+ * fhandler.cc (fhandler_base::fcntl): Only set specific O_NDELAY style
+ flag passed in from application.
+ * fhandler_socket.cc (fhandler_socket::fcntl): Ditto.
+ * fhandler.h: Set constant for future use.
+ * winsup.h: Define OLD_O_NDELAY only for old programs.
+ * include/cygwin/version.h: Define
+ CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK.
+
+Sat Aug 4 16:52:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, change check for running under Windows NT to 'iswinnt'.
+ * dcrt0.cc (set_os_type): Set 'iswinnt' appropriately.
+ * cygheap.cc (init_cheap): Revert to using VirtualAlloc for allocating
+ cygheap.
+ (cygheap_setup_for_child_cleanup): New function. Standard function to
+ call after calling CreateProcess to cleanup cygheap info passed to
+ child.
+ (cygheap_fixup_in_child): Copy cygheap from shared memory into
+ allocated space under Windows 9x or if can't relocate shared space
+ under NT.
+ * cygheap.h: Declare new function.
+ * spawn.cc (spawn_guts): Use cygheap_fixup_in_child.
+ * fork.cc (fork_parent): Ditto.
+ * winsup.h: Declare iswinnt.
+
+2001-08-04 Egor Duda <deo@logos-m.ru>
+
+ * dtable.cc (dtable::release): Avoid messing with console when
+ closing socket.
+
+Fri Aug 3 14:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_accept): Allow NULL peer and len parameters.
+ * include/cygwin/socket.h: Define socklen_t as int.
+
+Fri Aug 3 13:04:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (fchdir): Set the fhandler's path to absolute value to ensure
+ changing to the correct directory even if the fhandler originally
+ points to a relative path.
+
+Thu Aug 2 17:59:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (set_file_attribute): Clean up. Don't call
+ `set_nt_attribute' when ntsec isn't set.
+
+Sat Jul 28 22:30:55 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dcrt0.cc (alloc_stack_hard_way): Make half-hearted attempt to deal
+ with growing stack under Windows 95.
+
+Fri Jul 27 12:36:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Add install-lib and install-headers.
+
+Fri Jul 27 12:28:12 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din: Export sys_errlist, sys_nerr.
+ * include/cygwin/version.h: Bump minor version number.
+
+Fri 27 Jul 2001 10:29:00 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (get_user_primary_group): Fix compiler warning.
+ (alloc_sd): Add DELETE permission for user when S_IWUSR is given.
+
+Thu Jul 26 16:43:39 2001 Pieter de Visser <pieterdv@knoware.nl>
+
+ * thread.cc (__pthread_equal): Invert return value so that true is
+ returned when threads are equal.
+
+Thu Jul 26 15:50:38 2001 Charles Wilson <cwilson@ece.gatech.edu>
+ Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din: Export __signgam.
+ * include/cygwin/version.h: Bump minor version number.
+
+Thu Jul 26 15:19:50 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, reorganize header file inclusion to put security.h prior to
+ fhandler.h.
+ * fhandler.h (fhandler_base::get_inheritance): New method.
+ * fhandler_socket.cc (fhandler_socket::create_secret_event): Use proper
+ close-on-exec inheritance when creating.
+ (fhandler_socket::check_peer_secret_event): Create handle as
+ non-inheritable.
+
+2001-07-25 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * syscalls.cc (setsid): Detach process from its console if the current
+ controlling tty is the console and already closed.
+ * dtable.h (class dtable): Add members to count descriptors referring
+ to the console.
+ * dtable.cc (dtable::dec_console_fds): New function to detach process
+ from its console.
+ (dtable::release): Decrement the counter of console descriptors.
+ (dtable::build_fhandler): Increment it.
+ * exception.cc (ctrl_c_handler): Send SIGTERM to myself when catch
+ CTRL_SHUTDOWN_EVENT.
+
+Tue 24 Jul 2001 02:28:00 PM Trevor Forbes <t4bs@hotmail.com>
+
+ * thread.cc (verifyable_object_isvalid): Don't validate
+ PTHREAD_MUTEX_INITIALIZER pointer as it will cause an exception
+ in IsBadWritePtr() when running GDB.
+
+Wed 25 Jul 2001 23:46:00 Corinna Vinschen <corinna@vinschen.de>
+
+ * localtime.c: Changed whole file to become C++ clean. Rename to
+ localtime.cc.
+ * localtime.cc (tzload): Preserve errno.
+
+Fri 20 Jul 2001 11:15:50 PM EDT Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cygheap_fixup_in_child): Attempt Win95 workaround.
+ * dtable.cc (dtable::dup_worker): Add debugging output.
+ (dtable::vfork_child_dup): Correctly set close_on_exec.
+ * fhandler.cc (fhandler_base::fork_fixup): Don't mess with handle if
+ there is no need to get it from the parent.
+ * fhandler_tty.cc (fhandler_tty_common::close): Add debugging output.
+
+Fri 20 Jul 2001 09:15:00 Mark Bradshaw <bradshaw@staff.crosswalk.com>
+
+ * dir.cc (readdir): Protect FindNextFileA against INVALID_HANDLE_VALUE.
+
+Wed 18 Jul 2001 01:00:47 PM EDT Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (_cmalloc): Use correct constants for size calculation.
+ * dcrt0.cc (dll_crt0_1): Move uid initialization earlier.
+ * fork.cc (fork_parent): Move cygheap_setup_in_child to just prior to
+ CreateProcess so that all contents of cygheap are copied.
+ * spawn.cc (spawn_guts): Ditto.
+
+Wed 18 Jul 2001 12:54:17 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (get_user_groups): Call Net function with NULL server
+ name under specific error conditions.
+ (is_group_member): Ditto.
+ (get_user_local_groups): Ditto.
+ (get_user_primary_group): Ditto.
+
+Wed 18 Jul 2001 11:56:00 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (_unlink): Explicitly check for non-existant file.
+
+Tue 17 Jul 2001 10:19:00 Corinna Vinschen <corinna@vinschen.de>
+
+ * delqueue.h: Remove obsolete file.
+
+Mon 16 Jul 2001 10:47:17 PM EDT Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h: Bump magic number.
+ (class child_info): Add an element.
+ * cygheap.cc (init_cheap): Allocate cygwin heap in shared memory area.
+ (cygheap_fixup_in_child): Map cygwin heap, passed from parent via
+ shared memory into correct address.
+ (cygheap_setup_for_child): New function.
+ * cygheap.h: Declare new functions.
+ * dcrt0.cc (dll_crt0_1): Accommodate new cygheap_fixup_in_child
+ arguments. Avoid protecting subproc_ready unless it is spawn/nowait.
+ * fork.cc (fork_parent): Use new cygheap_setup_for_child function to
+ setup cygwin heap info. Close passed cygheap shared memory handle.
+ * spawn.cc (spawn_guts): Ditto. Also, reorganize to avoid
+ synchronization between parent and child in non-P_OVERLAY case.
+ * sigproc.cc (wait_sig): Only signal subproc_ready when execing.
+
+Mon 16 Jul 2001 15:21:00 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc: Add missing Copyright date 2001.
+
+Mon 16 Jul 2001 00:11:00 Corinna Vinschen <corinna@vinschen.de>
+
+ Change well_known_admin_sid to well_known_admins_sid throughout.
+ * sec_acl.cc (setacl): Never set DELETE permission. Set
+ FILE_DELETE_CHILD only on readable and executable directories.
+ * sec_helper.cc: Add constructor for `well_known_null_sid'.
+ * security.cc (get_nt_attribute): Set S_ISVTX for directories if
+ FILE_WRITE_DATA and FILE_EXECUTE but not FILE_DELETE_CHILD is set.
+ Add evaluation of S_ISVTX, S_ISGID and S_ISUID from NULL ACE.
+ (alloc_sd): Never set DELETE permission. Set FILE_DELETE_CHILD
+ only on readable and executable directories.
+ Add creation of NULL ACE for S_ISVTX, S_ISGID and S_ISUID permissions.
+ * security.h: Add extern declaration for `well_known_null_sid'.
+
+Fri 13 Jul 2001 08:08:49 PM EDT Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (stat_worker): Simplify previous change.
+
+Fri Jul 13 13:13:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_unlink): Correct (?) logic which determines when
+ to report an access violation and when to queue file for eventual
+ deletion.
+ (stat_worker): Check for invalid buf argument.
+
+Tue Jul 10 23:01:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (fhandler_disk_file::mmap): Try to open file mappings
+ by a unified name when running under 9x/ME. If that failes, create
+ the file mapping using the unified name.
+
+Mon Jul 9 10:43:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * uinfo.cc (internal_getlogin): Add pointer check.
+
+Mon Jul 9 10:05:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (alloc_sd): Don't set inheritance attribute for
+ permissions given to directories.
+
+Thu Jun 28 22:19:08 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_dsp.cc (fhandler_dev_dsp::ioctl): Return 0 for success.
+
+Wed Jun 27 22:19:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Add signal protection here since
+ retrieving info about remote shares can take some time.
+
+Wed Jun 27 23:30:00 2001 Robert Collins <rbtcollins@hotmail.com>
+ Christopher Faylor <cgf@cygnus.com>
+
+ Change check_null_empty_path* to check_null_empty_str* throughout.
+ * path.h (check_null_empty_str_errno): Convert to a function prototype.
+ * path.cc (check_null_empty_str): Move to miscfuncs.cc.
+ * miscfuncs.cc (check_null_empty_str_errno): New function.
+ (__check_null_invalid_struct): Ditto.
+ (__check_null_invalid_struct_errno): Ditto.
+ (check_null_empty_str): Change from VirtualQuery to IsBadWritePtr.
+ * thread.cc (check_valid_pointer): Ditto.
+ * resource.cc (getrlimit): Use check_null_invalid_struct macro for
+ checking validity of pointer.
+ (setrlimit): Ditto.
+
+Tue Jun 26 16:59:16 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Don't rely on exactly 3
+ characters being read for executable test since we could be checking
+ for less than that.
+ * syscalls.cc (stat_worker): Try opening the file the "correct" way
+ first so that #! processing can potentially happen. If that fails,
+ then use "query open" method.
+
+ * spawn.cc (spawn_guts): Delay processing of signal until after we've
+ notified parent about reparenting.
+
+Tue Jun 26 10:47:24 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * mmap.cc: Clean up *ResourceLock calls throughout.
+
+Tue Jun 26 22:10:00 2001 Robert Collins rbtcollins@hotmail.com
+
+ * thread.cc (pthread_cond::TimedWait): Check for WAIT_TIMEOUT as well
+ as WAIT_ABANDONED.
+ (__pthread_cond_timedwait): Calculate a relative wait from the abstime
+ parameter.
+
+Sun Jun 24 17:38:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (interrupt_setup): Move actions from setup_handler to
+ here.
+ (setup_handler): Move actions after a successful interrupt to
+ interrupt_setup.
+ * fork.cc (vfork): Augment debugging output.
+ * sigproc.cc (proc_subproc): Ditto.
+ * spawn.cc (spawn_guts): Ditto. Correctly fill out progname when spawn
+ NO_WAIT. Call signal handler when a signal arrives.
+ * sigproc.h: Declare a function.
+
+Fri Jun 22 16:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h class fhandler_socket): Declare new method
+ `set_close_on_exec'.
+ * fhandler_socket.cc (fhandler_socket::set_close_on_exec):
+ New method.
+
+Fri Jun 22 16:12:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_tape.cc (fhandler_dev_tape::tape_erase): Set size
+ parameter to value expected by GetTapeParameters().
+
+Thu Jun 21 22:01:39 2001 Marius Gedminas <mgedmin@delfi.lt>
+
+ * fhandler_console.cc (fhandler_console::read): Detect AltGr more
+ robustly on WinNT.
+
+2001-06-22 Robert Collins <rbbtcollins@hotmail.com>
+
+ * thread.cc (__pthread_cond_timedwait): Lock the waiting mutex before
+ the condition protect mutex to avoid deadlocking. (Found by Greg Smith).
+ (__pthread_cond_wait): Ditto.
+
+2001-06-30 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.cc (fhandler_base::open): Work around windows bug when
+ CreateFile() with dwDesiredAccess == 0 called on remote share returns
+ valid handle even if file doesn't exist.
+
+2001-06-20 Egor Duda <deo@logos-m.ru>
+
+ * fhandler_socket.cc (fhandler_socket::signal_secret_event): New
+ function.
+ * fhandler.h: Declare it.
+ * fhandler_socket.cc (fhandler_socket::create_secret_event): Don't
+ signal secret event immediately.
+ (fhandler_socket::check_peer_secret_event): Do it after peer event
+ was opened.
+ * net.cc (cygwin_connect): Or if socket is non-blocking.
+ (cygwin_accept): Ditto.
+
+Mon Jun 18 17:09:25 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_tty.cc (fhandler_tty_slave::init): Revert 2001-06-16 change.
+
+ * fork.cc (fork_copy): Print more debugging info.
+ (fork_parent): Change order of arguments to accomdate buggy gcc.
+ (fork): Ditto.
+
+Sun Jun 17 18:54:46 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_unlink): Reorganize to try harder to delete file with
+ DeleteFile and to recover more gracefully if FILE_FLAG_DELETE_ON_CLOSE
+ doesn't work properly.
+
+Sat Jun 16 13:06:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (sig_handle_tty_stop): Reset PID_STOPPED if not
+ actually stopping.
+ * fhandler_console.cc (fhandler_console::fixup_after_fork): Don't set
+ controlling terminal if just inheriting a handle.
+ (fhandler_console::fixup_after_exec): Ditto.
+ * fhandler_tty.cc (fhandler_tty_slave::init): Ditto.
+ * signal.cc (kill_worker): Set appropriate errno if proc_exists
+ determines that process does not really exist.
+
+Fri Jun 15 14:34:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Deal more robustly with foo/ behavior.
+
+Fri Jun 15 11:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_tape.cc (fhandler_dev_tape::tape_status): Set size
+ parameter to value expected by GetTapeParameters().
+
+Thu Jun 14 20:19:46 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Properly set executable bits
+ for directory when !ntsec && !ntea. Also move common code prior to
+ call to get_attributes.
+
+Fri June 15 09:25:00 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond::Signal): Release the condition access
+ variable correctly.
+
+2001-06-14 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.cc (fhandler_base::open): Set win32 access flags to 0, when
+ requested.
+ * fhandler.h: New status flag FH_QUERYOPEN.
+ (fhandler::get_query_open): New function.
+ (fhandler::set_query_open): Ditto.
+ * syscalls.cc (stat_worker): Request query-only open mode.
+
+2001-06-12 Egor Duda <deo@logos-m.ru>
+
+ * environ.cc (set_file_api_mode): New function. Move setting
+ of file APIs mode (OEM/ANSI) here.
+ (codepage_init): From here.
+ * winsup.h (set_file_api_mode): Declare it.
+ * fork.cc (fork_child): Set file APIs mode in forkee.
+
+Mon Jun 11 14:19:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * pinfo.cc: Use autoloaded ToolHelp functions throughout for Win9x.
+ * autoload.cc: Autoload ToolHelp functions.
+
+ * sigproc.cc (proc_subproc): Incorporate SIGCHLD == SIG_IGN special
+ handling of zombie processes. Ensure that zombie processes which are
+ at the end of the zombie array are properly cleaned up.
+
+Mon Jun 11 11:18:56 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (chdir): Fix call to path_conv constructor so that it REALLY
+ doesn't check for the null/non-empty path.
+
+Sun Jun 10 23:34:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::update_fs_info): Don't consider remote drives to
+ be NTFS. Set root_dir before invoking GetDriveType (from Kazuhiro
+ Fujieda <fujieda@jaist.ac.jp>). Eliminate extra checks for rootdir.
+
+Sun Jun 10 20:19:47 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (chdir): Pre-check path for validity before eating trailing
+ space. Then, ensure that path_conv doesn't check the path for validity
+ again.
+
+Sun Jun 10 12:56:00 2001 Christopher Faylor <cgf@redhat.com>
+
+ * exceptions.cc (sigdelayed): Ensure that signal is cleared as
+ the last operation or suffer races.
+ * sigproc.cc (proc_subproc): Deal with zombie array overflow.
+
+Sun Jun 10 11:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din: Add fchdir symbols.
+ * path.cc (chdir): Guard against invalid parameter.
+ (fchdir): New function.
+ * include/cygwin/version.h: Bump API minor version to 40.
+ * uinfo.cc (internal_getlogin): Remove unused variable.
+
+Sat Jun 9 23:20:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (seteuid): Set environment variables USERNAME and
+ USERDOMAIN before impersonation to workaround a LookupAccountSid()
+ misbehaviour.
+ * uinfo.cc (internal_getlogin): Revert most of the previous change.
+ Don't set environment variables USERNAME and USERDOMAIN. That's
+ the job of seteuid() now. Try to get logon server from Lsa
+ only if logon server isn't already known.
+
+Thu Jun 7 15:54:32 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (pthread_cond::Broadcast): Don't print error messages on
+ invalid mutexs - user programs are allowed to call
+ pthread_cond_broadcast like that.
+ (__pthread_cond_timedwait): Initialise themutex properly.
+ (__pthread_cond_wait): Initialise themutex properly.
+
+Tue Jun 5 19:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_console.cc (fhandler_console::dup): Allocate space for
+ savebuf on Cygwin heap.
+ (fhandler_console::char_command): Ditto. Use correct values for size.
+
+2001-06-05 Egor Duda <deo@logos-m.ru>
+
+ * security.h (NTWriteEA): Change prototype.
+ * ntea.cc (NTReadEA): Don't check for global ntea setting, now
+ it's caller responsibility.
+ (NTWriteEA): Ditto.
+ * security.cc (get_file_attribute): Read attribute from EA only
+ if 'ntea' is enabled.
+ (set_file_attribute): Ditto.
+ * path.h: (class path_conv): Add members to store file system
+ information.
+ (path_conv::get_drive_type): New function.
+ * syscalls.cc (stat_worker): Use it.
+ * path.cc (path_conv::update_fs_info): New functions.
+ (path_conv::check): Get file system information from device where
+ file resides. On NTFS, try to read symlink contents from EA.
+ (get_symlink_ea): New function.
+ (set_symlink_ea): Ditto.
+ (symlink): Store symlink in extended attribute, if possible.
+
+Tue Jun 5 11:18:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Always reset file position
+ to original value after checking for executable magic.
+
+Mon Jun 4 16:21:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.h (cygheap_user::cygheap_user): Initialize token to
+ INVALID_HANDLE_VALUE.
+ * uinfo.cc (uinfo_init): Close token handle if needed.
+
+Sun Jun 3 20:52:13 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (normalize_posix_path): Revert .. check removed by previous
+ changes.
+ * cygheap.h: Temporarily declare path_prefix_p here.
+
+Mon Jun 4 0:14:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (wsock_event): Add destructor.
+
+Sun Jun 3 09:49:55 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * dlfcn.cc (dlclose): Do not call FreeLibrary if the symbol to close
+ was obtained by dlopen(NULL,...).
+
+Sat Jun 2 23:11:52 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (sleep): Try to be a little more accomodating of signal
+ arrival. Ensure that the signal handler is called.
+
+Sat Jun 2 14:07:28 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (cygheap_root::cygheap_root): Remove constructor.
+ (cygheap_root::~cygheap_root): Remove destructor.
+ (cygheap_root::operator =): Remove.
+ (cygheap_root::set): New method.
+ * cygheap.h (cygheap_root): Reflect above changes. Store root info in
+ mount-like structure.
+ (cygheap_root:posix_ok): New method.
+ (cygheap_root::ischroot_native): Ditto.
+ (cygheap_root::unchroot): Ditto.
+ (cygheap_root::exists): Ditto.
+ (cygheap_root::posix_length): Ditto.
+ (cygheap_root::posix_path): Ditto.
+ (cygheap_root::native_length): Ditto.
+ (cygheap_root::native_path): Ditto.
+ * dir.cc (opendir): Remove special chroot test.
+ * path.cc (path_prefix_p): Remove front end.
+ (normalize_posix_path): Reorganize chroot tests to accommodate new
+ convention of allowing paths using posix chroot prefix.
+ (path_conv::check): Pass a "already ran normalize" option to
+ conv_to_win32_path. Return if there is an error from this function.
+ (mount_info::conv_to_win32_path): Add extra argument. Don't call
+ normalize_posix_path if caller has already done so. Substitute chroot
+ setting, if any, for root translation. Add chroot checking to final
+ output step.
+ * shared_info (mount_info): Accommodate additional argument to
+ conv_to_win32_path.
+ * syscalls.cc (chroot): Store both normalized posix path and native
+ path in chroot.
+
+Fri Jun 1 10:57:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (chdir): Really make sure that isspace gets only an unsigned
+ char.
+
+Fri Jun 1 13:45:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (_rename): Handle the case that `foo' is renamed to
+ `bar' while `bar.lnk' is an existing shortcut-symlink.
+
+Thu May 31 15:57:57 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Avoid clearing S_IFMT bits
+ since we've already pre-cleared everything anyway.
+
+Wed May 30 23:51:32 2001 Earnie Boyd <earnie_boyd@yahoo.com>
+
+ * path.cc (chdir): Always send unsigned chars to isspace since newlib's
+ isspace doesn't deal well with "negative" chars.
+
+Wed May 30 23:51:32 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_disk_file::open): Propagate remote status of
+ file garnered from path_conv. Move #! checking to fstat.
+ (fhandler_disk_file::fstat): Reorganize st_mode setting to eliminate
+ duplication. Move check for #! here from fhandler::open.
+
+ * fhandler.h (fhandler_base::isremote): New method.
+ (fhandler_base::set_isremote): Ditto.
+ (fhandler_base::set_execable_p): Also record "don't care if executable
+ state".
+ (fhandler_base::dont_care_if_execable): New method.
+ * path.cc (path_conv::check): Clear new flags. Appropriately set
+ vol_flags, drive_type, and is_remote_drive.
+ * path.h: Add new flags and methods for manipulating them.
+ * syscalls.cc (_unlink): Use isremote() to determine if a path is
+ remote rather than calling GetDriveType.
+ (stat_worker): Ditto.
+ * security.cc (get_file_attribute): Or attribute with result of
+ NTReadEA to be consistent with get_nt_attribute.
+
+Tue May 29 19:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * sec_helper.cc (cygsid::getfrompw): Change parameter to `const'.
+ (cygsid::getfromgr): Ditto.
+ * security.cc: Use `sys_mbstowcs' and `sys_wcstombs' throughout.
+ (extract_nt_dom_user): Try to get user and domain from SID in
+ pw->pw_gecos first.
+ * security.h (class cygsid): Change parameter of getfrompw() and
+ getfromgr() to `const'.
+ * uinfo.cc (internal_getlogin): Change order for evaluating user
+ information in winNT case. Drop usage of NetWkstaUserGetInfo().
+
+Mon May 28 21:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * shortcut.c (check_shortcut): Treat only Cygwin shortcuts as symlinks.
+
+Fri May 25 11:07:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (symlink_info::check): Correctly set 'ext_tacked_on'. Use
+ this to determine if user specified 'foo.lnk' explicitly. Reorganize
+ slightly to get rid of one goto.
+
+Fri May 25 10:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (symlink_info::check): Add a check to return correctly
+ if incoming `*.lnk' file is not a symlink.
+
+Thu May 24 15:46:50 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (slash_drive_prefix_p): Remove.
+ (mount_info::slash_drive_to_win32_path): Ditto.
+ (mount_info::conv_to_win32_path): Remove slash drive prefix check.
+ (mount_info::add_item): Ditto.
+ (mount_info::del_item): Ditto.
+ * shared_info.h (mount_info): Remove slash_drive_to_win32_path
+ declaration.
+
+Thu May 24 01:17:33 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (handle_exceptions): Bump repeat count for debugging
+ kick out.
+
+ * fhandler.h (fhandler_dev_dsp): Add a fixup_after_exec.
+ * fhandler_dsp.cc (class Audio): Add TOT_BLOCK_SIZE to enum.
+ (operator new): New.
+ (bigwavebuffer): Declare using TOT_BLOCK_SIZE to avoid buffer overruns.
+ (Audio::Audio): Optimize slightly.
+ (fhandler_dev_dsp::open): Allocate s_audio using static buffer.
+ (fhandler_dev_dsp::fixup_after_exec): New function. Ditto.
+
+Wed May 23 17:45:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (seteuid): Restrict overriding external provided
+ user tokens to ntsec. Don't test external tokens for primary
+ group to evaluate if it should be overridden. Restrict creating
+ internal tokens to ntsec.
+
+Wed May 23 10:11:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (chown_worker): Don't check for ENOSYS.
+
+Tue May 22 12:20:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * signal.cc (sleep): Protect with sigframe.
+
+Tue May 22 17:58:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (get_file_attribute): Don't set errno.
+
+Mon May 21 15:08:00 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Allow --enable-newvfork to turn NEWVFORK on and off.
+ * configure: Regenerate.
+
+Mon May 21 11:46:01 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump minor version number.
+
+Sun May 20 13:26:25 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_dsp.cc: Reformat to GNU standards.
+ (s_audio): Change to a pointer throughout.
+ (fhandler_dev_dsp::open): Initialize s_audio, if required.
+
+Sat May 19 23:40:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add load statements for `LookupAccountNameW',
+ `LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory',
+ `LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum',
+ `NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and
+ `NtCreateToken'.
+ * ntdll.h: Add declaration for `NtCreateToken'.
+ * sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid',
+ `well_known_network_sid', `well_known_batch_sid',
+ `well_known_interactive_sid', `well_known_service_sid' and
+ `well_known_authenticated_users_sid'.
+ (cygsid::string): Define as const method.
+ (cygsid::get_sid): Set psid to NO_SID on error.
+ (cygsid::getfromstr): Ditto.
+ (cygsid::getfrompw): Simplify.
+ (cygsid::getfromgr): Check for gr == NULL.
+ (legal_sid_type): Move to security.h.
+ (set_process_privilege): Return -1 on error, otherwise 0 or 1 related
+ to previous privilege setting.
+ * security.cc (extract_nt_dom_user): Remove `static'.
+ (lsa2wchar): New function.
+ (open_local_policy): Ditto.
+ (close_local_policy): Ditto.
+ (get_lsa_srv_inf): Ditto.
+ (get_logon_server): Ditto.
+ (get_logon_server_and_user_domain): Ditto.
+ (get_user_groups): Ditto.
+ (is_group_member): Ditto.
+ (get_user_local_groups): Ditto.
+ (sid_in_token_groups): Ditto.
+ (get_user_primary_group): Ditto.
+ (get_group_sidlist): Ditto.
+ (get_system_priv_list): Ditto.
+ (get_priv_list): Ditto.
+ (get_dacl): Ditto.
+ (create_token): Ditto.
+ (subauth): Return immediately if SE_TCB_NAME can't be assigned.
+ Change all return statements in case of error to jumps to `out'
+ label. Add `out' label to support cleanup.
+ * security.h: Add extern declarations for `well_known_local_sid',
+ `well_known_dialup_sid', `well_known_network_sid',
+ `well_known_batch_sid', `well_known_interactive_sid',
+ `well_known_service_sid' and `well_known_authenticated_users_sid'.
+ Add extern declarations for functions `create_token',
+ `extract_nt_dom_user' and `get_logon_server_and_user_domain'.
+ (class cygsid): Add method `assign'. Change operator= to call new
+ `assign' method. Add `debug_print' method.
+ (class cygsidlist): New class.
+ (legal_sid_type): Moved from sec_helper.cc to here.
+ * spawn.cc (spawn_guts) Revert reversion of previous patch.
+ Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'
+ again.
+ * syscalls.cc (seteuid): Rearranged. Call `create_token' now when
+ needed. Call `subauth' if `create_token' fails. Try setting token
+ owner and primary group only if token was not explicitely created
+ by `create_token'.
+ * uinfo.cc (internal_getlogin): Try harder to generate correct user
+ information. Especially don't trust return value of `GetUserName'.
+
+Sat May 19 21:16:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fork.cc (fork_parent): Move atforkprepare call here.
+ (fork): From here.
+
+Sat May 19 18:35:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add missing load statement for `CancelIo'.
+
+Sat May 19 01:22:43 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * grp.cc (read_etc_group): Don't copy mutex on fork.
+ * pwd.cc (read_etc_passwd): Ditto.
+ * autoload.cc (LoadDLLfuncEx): Use LoadDLLprime to initialize DLL
+ specific area.
+
+Fri May 18 10:31:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (wsock_event::wait): Explicitely cancel IO when a signal
+ arrived to avoid data loss. Fallback to blocking IO when canceling
+ fails.
+
+Thu May 17 15:29:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (cygwin_set_impersonation_token): Never destroy
+ previous token object.
+ (subauth): Create token source with well defined identifier.
+
+Wed May 16 23:27:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * uinfo.cc (uinfo_init): Just set user token to INVALID_HANDLE_VALUE.
+ Token value is already invalid at that point.
+
+Wed May 16 21:34:00 2001 Fred Yankowski <fred@ontosys.com>
+
+ * net.cc (errmap): Add missing mapping from WSAEINTR to EINTR.
+
+Wed May 16 09:20:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * sec_helper.cc (legal_sid_type): Fix conditional. Change to
+ inline function.
+
+Wed May 16 01:01:48 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * autoload.h: Eliminate.
+ * autoload.cc: Pull in autoload.h. Eliminate many macros. Rewrite to
+ avoid necessity of initialization routines. Just use a standard one.
+ (wsock_init): New function. Moved from net.cc.
+ * net.cc (wsock_init): Move to autoload.cc.
+ (wsadata): Make global.
+ * dtable.cc (dtable::build_fhandler): Use more reliable method for
+ checking if net stuff has been loaded.
+
+Tue May 15 19:52:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fork.cc (fork): Eliminate superfluous call to getuid().
+ * security.h: New define `NO_SID'. Remove declarations of functions
+ moved to methods into class cygsid.
+ (class cygsid): Declare new methods `getfromstr', `get_sid',
+ `getfrompw', `getfromgr', `get_rid', `get_uid', `get_gid', `string'
+ and new constructors and operators =, == and !=.
+ Declare new global cygsids `well_known_XXX_sid' substituting the
+ corresponding `get_XXX_sid' functions. Remove declarations of
+ these functions.
+ * sec_helper.cc (well_known_admin_sid): New global variable.
+ (well_known_system_sid): Ditto
+ (well_known_creator_owner_sid): Ditto
+ (well_known_world_sid): Ditto
+ (cygsid::string): New method, substituting `convert_sid_to_string_sid'.
+ (cygsid::get_sid): New method, substituting `get_sid'.
+ (cygsid::getfromstr): New method, substituting
+ `convert_string_sid_to_sid'.
+ (cygsid::getfrompw): New method, substituting `get_pw_sid'.
+ (cygsid::getfromgr): New method, substituting `get_gr_sid'.
+ (cygsid::get_id): New method, substituting `get_id_from_sid'.
+ (get_admin_sid): Eliminated.
+ (get_system_sid): Ditto.
+ (get_creator_owner_sid): Ditto.
+ (get_world_sid): Ditto.
+ * grp.cc: Use new cygsid methods and well known sids throughout.
+ * registry.cc: Ditto.
+ * sec_acl.cc: Ditto.
+ * security.cc: Ditto.
+ * shared.cc: Ditto.
+ * syscalls.cc (seteuid): Ditto. Eliminate redundant conditional.
+ * uinfo.cc (internal_getlogin): Ditto.
+ * spawn.cc (spawn_guts) Revert previous patch.
+
+Tue May 15 10:20:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::ioctl): Convert s_addr
+ field to host byte order before comparing with INADDR_LOOPBACK.
+
+Tue May 15 9:03:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add autoload statements for ws2_32 functions
+ `WSACloseEvent', `WSACreateEvent', `WSAGetOverlappedResult',
+ `WSARecv', `WSARecvFrom', `WSASend', `WSASendTo' and `WSASetEvent',
+ `WSAWaitForMultipleEvents'.
+ * net.cc: Define wsock_evt.
+ (wsock_event): New class.
+ (cygwin_sendto): Use overlapped socket io if available.
+ (cygwin_recvfrom): Ditto.
+ (cygwin_recv): Ditto.
+ (cygwin_send): Ditto.
+ * security.cc (subauth): Set Win32 error to 0 to safely ask for the
+ error code of dynamically loaded function `LsaRegisterLogonProcess'.
+
+Mon May 14 15:37:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * errno.cc (_sys_errlist): Add missing commas.
+
+Mon May 14 16:13:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (subauth): Check if Secur32.dll could be loaded.
+
+Sun May 13 22:49:04 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Revert allow_ntsec check so that volume
+ info is always retrieved and isdisk setting is properly set.
+
+Sun May 13 14:02:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_tty.cc (fhandler_tty_common::dup): Preserve O_NOCTTY when
+ duping a filehandle.
+
+Sat May 12 18:19:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (rmdir): Rearrange slightly to allow removing directories
+ even when R/O attribute is set.
+
+Fri May 11 16:53:38 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * external.cc (fillout_pinfo): Use correct pids.
+ * path.cc (mount_info::conv_to_win32_path): Correct test for whether to
+ include a slash.
+
+Fri May 11 01:04:17 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (handle_exceptions): Don't print message when executing
+ from a cygwin program.
+
+2001-05-10 Egor Duda <deo@logos-m.ru>
+ Christopher Faylor <cgf@redhat.com>
+
+ * environ.cc (winenv): Always add SYSTEMDRIVE and SYSYEMROOT to
+ win32-style environment if they don't already exist.
+
+2001-05-10 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * path.cc (mount_info::conv_to_win32_path): Treat UNC paths the same as
+ paths including `:' or `\'.
+
+Wed May 9 14:46:32 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.h (fhandler_termios::echo_erase): Declare new method.
+ * fhandler_termios.cc (fhandler_termios::echo_erase): New method for
+ echoing erase characters.
+ (fhandler_termios::line_edit): Check the echo flag before echoing
+ control characters (from Kazuhiro Fujieda <fujieda@jaist.ac.jp>).
+
+Wed May 9 10:43:30 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/pthread.h: Remove C++ comment.
+
+Tue May 8 11:09:59 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (_cfree): Add regparm attribute.
+ (_crealloc): Ditto.
+
+ * dcrt0.cc (dll_crt0_1): Default to always checking for executable for now.
+
+ * dtable.cc (dtable::not_open): Move method.
+ * dtable.h (dtable): Here.
+
+ * exceptions.cc (ctrl_c_handler): Don't expect process group leader to
+ handle a signal if it doesn't exist.
+
+ * fhandler.h (fhandler_base): Make openflags protected.
+
+ * localtime.c (tzsetwall): Check for __CYGWIN__ as well as __WIN32__.
+
+ * path.cc (path_conv::check): Add some comments. Change strcat to assignment.
+
+ * lib/_cygwin_S_IEXEC.cc (_cygwin_bob__): Eliminate.
+
+ * fhandler_tty.cc (fhandler_console::dup): Set controlling terminal if necessary.
+ * fhandler_tty.cc (fhandler_tty_slave::dup): Ditto.
+
+Mon May 7 21:33:17 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/sys/file.h: Revert special X_OK usage. Just make it a
+ constant.
+
+Sun May 6 17:05:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.h (pthread_cond): New element cond_access to allow atomic
+ broadcasts.
+ * thread.cc (pthread_cond::pthread_cond): Initialise cond_access.
+ (pthread_cond::~pthread_cond): Destroy cond_access.
+ (pthread_cond::Broadcast): Use cond_access.
+ (pthread_cond::Signal): Use cond_access.
+ (pthread_cond_wait): Use cond_access.
+ (pthread_cond_timedwait): Use cond_access.
+
+Sun May 6 11:55:40 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * string.h (cygwin_strchr): Make 'static inline' so that things will
+ still work when optimized.
+
+Sat May 5 01:04:11 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (handle_exceptions): Vastly increase test for exception
+ loop guard variable.
+
+Fri May 4 22:23:33 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (stack_info): Add some controls.
+ (stack_info::init): Add extra arguments to control method of
+ initialization.. If we have a known good frame, set things up so that
+ this frame is not skipped the first time through. Record whether
+ caller cares about arguments or not.
+ (stack_info::walk): Don't store arguments if they're unwanted.
+ (stackdump): Add isexception parameter for use when called by exception
+ handler.
+ (cygwin_stackdump): Accommodate extra argument to stackdump.
+ (handle_exceptions): Ditto.
+ (sig_handle): Ditto.
+ (interrupt_on_return): Accommodate extra arguments to stack walk
+ initialization.
+
+Fri May 4 21:05:20 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * localtime.c: Revert exclusion of windows.h.
+
+Fri May 4 17:03:16 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * string.h: Fix last-minute typo.
+
+Fri May 4 16:49:34 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * pinfo.h: Correctly set __SIGOFFSET.
+
+ * path.cc (hash_path_name): Avoid calling library functions for simple
+ copying of characters.
+
+ * shortcut.c: Use WIN32_LEAN_AND_MEAN.
+ * smallprint.c: Ditto.
+
+ * environ.cc (getwinenv): Minor clarity fix.
+
+ * localtime.c: No need to include windows.h
+
+ * string.h: New file.
+
+Fri May 4 16:37:30 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (ctrl_c_handler): Always send signal to process if it
+ has no tty.
+
+2001-05-04 Egor Duda <deo@logos-m.ru>
+
+ * fhandler_socket.cc (set_connect_secret): Use /dev/urandom to
+ generate secret cookie.
+
+Thu May 3 16:37:55 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/pthread.h (pthread_cleanup_push): Eliminate space preceding
+ arguments.
+ (pthread_cleanup_pop): Ditto.
+
+Thu May 3 18:16:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (wsock_init): Rename `was_in_progress' to `wsock_started'
+ for clearness.
+
+Thu May 3 10:44:16 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (handle_exceptions): Break out of "loop" if the
+ debugger doesn't seem to be attaching to our process.
+
+Wed May 2 20:18:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Use new definition of LoadDLLinitfunc throughout.
+ Redefine wrapper for wsock32.dll and ws2_32.dll.
+ (std_dll_init): New function.
+ * autoload.h: Rename LoadDLLinitfunc to LoadDLLinitfuncdef.
+ Add new defines LoadDLLinitfunc and LoadDLLstdfunc.
+ * net.cc (wsock_init): Add guard variable handling. Take care
+ to call WSAStartup only once. Load WSAStartup without using
+ autoload wrapper to eliminate recursion. Eliminate FIONBIO
+ and srandom stuff.
+
+Tue May 1 01:26:15 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (mount_info::conv_to_win32_path): More path tweaking.
+
+Tue May 1 00:34:46 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (mount_info::conv_to_win32_path): Fix debugging output to
+ avoid a SIGSEGV. Avoid double backslashes in middle of filename.
+
+Mon Apr 30 21:51:14 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (mkrelpath): New function.
+ (mount_info::conv_to_win32_path): Eliminate now-unneeded relative path
+ name arg and processing.
+ (path_conv::check): Accommodate relative path names again. Accommodate
+ one extra argument in mount_info::conv_to_win32_path. Tack trailing
+ slash on end of relative path as a side effect, like before.
+ * shared_info.h (mount_info::conv_to_win32_path): Reflect new argument
+ ordering.
+
+Mon Apr 30 22:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add LoadDLLinitfunc for secur32.dll.
+ Add LoadDLLfuncEx statements for AllocateLocallyUniqueId@4,
+ DuplicateTokenEx@24, LsaNtStatusToWinError@4,
+ LsaDeregisterLogonProcess@4, LsaFreeReturnBuffer@4,
+ LsaLogonUser@56, LsaLookupAuthenticationPackage@12,
+ LsaRegisterLogonProcess@12,
+ * environ.cc: Add extern declaration for `subauth_id'.
+ (subauth_id_init): New function for setting `subauth_id'.
+ (struct parse_thing): Add entry for `subauth_id'.
+ * fork.cc (fork_parent): Call `RevertToSelf' and
+ `ImpersonateLoggedOnUser' instead of `seteuid'.
+ * security.cc: Define global variable `subauth_id'.
+ (extract_nt_dom_user): New function.
+ (cygwin_logon_user): Call `extract_nt_dom_user' now.
+ (str2lsa): New static function.
+ (str2buf2lsa): Ditto.
+ (str2buf2uni): Ditto.
+ (subauth): Ditto.
+ * security.h: Add prototype for `subauth'.
+ * spawn.cc (spawn_guts): Use cygheap->user.token only if impersonated.
+ Use `cygsid' type. Remove impersonation before allowing access to
+ workstation/desktop to everyone. Call `RevertToSelf' and
+ `ImpersonateLoggedOnUser' instead of `seteuid'.
+ * syscalls.cc (seteuid): Rearranged to allow using subauthentication
+ to retrieve user tokens when needed.
+
+Mon Apr 30 20:26:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * uinfo.cc (internal_getlogin): Formatting change.
+
+Mon Apr 30 19:58:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc: Eliminate MAX_DOMAIN_NAME define.
+ (read_etc_group): Substitute MAX_DOMAIN_NAME by
+ INTERNET_MAX_HOST_NAME_LENGTH.
+ * passwd.cc (parse_pwd): Don't force pw_name to be lower case.
+ * sec_helper.cc: Substitute MAX_USER_NAME by UNLEN,
+ MAX_COMPUTERNAME_LENGTH by INTERNET_MAX_HOST_NAME_LENGTH throughout.
+ (lookup_name): Slight cleanup.
+ * security.cc (alloc_sd): Substitute MAX_USER_NAME by UNLEN.
+ * security.h: Define DEFAULT_UID as DOMAIN_USER_RID_ADMIN and
+ DEFAULT_GID as DOMAIN_ALIAS_RID_ADMINS.
+ * shared.cc (memory_init): Substitute MAX_USER_NAME by UNLEN.
+ * thread.h: Ditto.
+ * uinfo.cc (internal_getlogin): Substitute MAX_USER_NAME by UNLEN.
+ Substitute MAX_COMPUTERNAME_LENGTH and MAX_HOST_NAME by
+ INTERNET_MAX_HOST_NAME_LENGTH.
+ * winsup.h: Include lmcons.h. Eliminate MAX_USER_NAME and
+ MAX_HOST_NAME. Move DEFAULT_UID and DEFAULT_GID to security.h.
+
+Mon Apr 30 12:35:40 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Don't use path_flags when converting to
+ MS-DOS syntax unless parsing tail of path component. Stop parsing path
+ when we reach the 'root' of the path. Correctly copy tail to path
+ component.
+
+Sun Apr 29 22:28:06 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (INIT_EXCEPTION_HANDLER): Eliminate.
+ (init_exceptions): Just use init_exception_handler.
+ (open_stackdumpfile): New function.
+ (stack_info::first_time): Eliminate.
+ (stack_info::init): Set up fields to avoid "first_time" consideration.
+ (stack_info::walk): Remove "first_time" consideration.
+ (stackdump): Change arguments to accept initial frame pointer and open
+ stack file flag.
+ (stack): Eliminate.
+ (cygwin_stackdump): Use stackdump() rather than stack().
+ (try_to_debug): Remove all synchronization logic. Just keep looping in
+ exception handler until debugger notices us. Return 1 if successfully
+ started debugger.
+ (handle_exceptions): Just return if we know that we're debugging.
+ Reorganize to avoid creating a stackdump file if we are starting a
+ debugger. Return from exception handler if debugger started
+ successfully.
+ (sig_handle): Create a stackdump only if debugger wasn't started.
+ * winsup.h (try_to_debug): Add an argument.
+
+Sun Apr 29 21:41:25 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (symlink_info::check): Remove extra arguments, move
+ functionality back to path_conv::check. Clear symlink bit from pflags
+ argument before detecting if this is a symlink.
+ (path_conv::check): Convert posix path here instead of
+ symlink_info::check. Only grab volflags when using ntsec.
+ (symlink_info::check_case): Just replace appropriate part of input
+ path.
+
+Sat Apr 28 19:36:13 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, change 'tty_attached' to 'real_tty_attached', for clarity.
+ Throughout, change 'OutputStopped' to 'output_stopped', for
+ consistency.
+ * dtable.cc (stdio_init): Set controlling tty if not set by stdio
+ opens.
+ * exceptions.cc (ctrl_c_handler): Avoid special pgid checking if no tty
+ is associated with the process.
+ (Suggested by Tim Baker <dbaker@direct.ca>)
+ * external.cc (fillout_pinfo): Return actual tty number for ctty.
+ * fhandler_console.cc (get_tty_stuff): Set ctty when shared memory is
+ allocated. Accept flags input from open().
+ (set_console_ctty): New function.
+ (fhandler_console::open): Pass flags to get_tty_stuff and rely on this
+ function to set the ctty, if appropriate.
+ * fhandler_termios.cc (fhandler_termios::set_ctty): Move to tty_min
+ class.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Use tc field to access
+ set_ctty().
+ * tty.h (TTY_CONSOLE): Move to include/sys/cygwin.h.
+ (tty_min): Add set_ctty class here.
+ * include/sys/cygwin.h (TTY_CONSOLE): New home here.
+
+ * path.cc (symlink_info): Make contents an actual buffer. Pass more
+ flags to case_check.
+ (path_conv::check): Reorganize to do parsing based on posix path rather
+ than native path.
+ (symlink_info::check): Expect posix path as input. Translate to native
+ path here. Accept path_conv flags. Stop parsing if not a symlink
+ regardless of whether previous path was a symlink.
+
+2001-04-27 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * thread.cc (thread_init_wrapper): Use _REENT_INIT to initialize the
+ reent structure of newlib.
+
+Fri Apr 27 14:02:24 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.h (sig_send): Add exception parameter to sig_send.
+ * sigproc.cc (sig_send): Ditto. Use it when setting frame info.
+ * exceptions.cc (handle_exceptions): Use exception flag when calling
+ sig_send.
+
+2001-04-27 Egor Duda <deo@logos-m.ru>
+
+ * tty.cc (tty::make_pipes): Set to_slave pipe mode to nonblocking.
+ * fhandler_tty.cc (fhandler_pty_master::accept_input): If pipe buffer
+ is full, give slave a chance to read data.
+
+2001-04-26 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * security.cc (alloc_sd): Add unrelated ACCESS_ALLOWED_ACE behind
+ the `everyone' ACE.
+
+Wed Apr 25 15:07:37 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.h [sigthread]: Add exception field.
+ [sigframe::~sigframe]: Clear exception field.
+ [sigframe::set]: Set exception field from caller.
+ * sigproc.cc (sig_send): Set exception field when frame pointer is
+ passed in.
+ * exceptions.cc (interrupt_on_return): Always treat exception as
+ interruptible.
+
+2001-04-25 Egor Duda <deo@logos-m.ru>
+
+ * cygwin.din: Export asctime_r, ctime_r, gmtime_r, localtime_r
+ * include/cygwin/version.h: Bump CYGWIN_VERSION_API_MINOR to 39
+
+Wed Apr 25 10:57:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump minor version number.
+ * childinfo.h: Bump child structure magic number.
+
+2001-04-25 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * uinfo.cc (internal_getlogin): Return pointer to struct passwd.
+ (uinfo_init): Accommodate the above change.
+ * syscalls.cc (seteuid): Ditto.
+
+Tue Apr 25 11:08:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16.
+ * cygheap.cc: Include security.h.
+ * grp.cc (internal_getgrent): New function.
+ (getgroups): Rearranged using `internal_getgrent' and the new
+ `cygsid' class.
+ * passwd.cc (internal_getpwent): New function.
+ * sec_acl.cc: Use new `cygsid' class throughout.
+ (acl_access): Use `internal_getgrent' instead of `getgrent'.
+ * sec_helper.cc: Use new `cygsid' class throughout.
+ (get_id_from_sid): Use `internal_getgrent' instead of `getgrent'.
+ Use `internal_getpwent' instead of `getpwent'.
+ * security.cc: Use new `cygsid' class throughout.
+ * security.h: Move `MAX_SID_LEN' from winsup.h to here.
+ Add extern declarations for `internal_getgrent' and `internal_getpwent'.
+ (class cygsid): New class.
+ * shared.cc (sec_user): Use new `cygsid' class.
+ * syscalls.cc (seteuid): Try to set owner to user and primary group to
+ current group in impersonation token before performing impersonation.
+ (setegid): Try to set primary group in process token to the new group
+ if ntsec is on.
+ * uinfo.cc (internal_getlogin): Use new `cygsid' class.
+ Try to set owner to user and primary group to current group in process
+ token if the process has been started from a non cygwin process.
+ (uinfo_init): Set primary group only if the process has been started
+ from a non cygwin process.
+ * winsup.h: Move define for `MAX_SID_LEN' to security.h.
+
+Mon Apr 16 23:20:00 2001 Andy Younger <andylyounger@hotmail.com>
+
+ * fhandler_dsp.cc: Improved handling of 8 bit playback modes.
+ Put in mock support for SNDCTL_DSP_SETFRAGMENT.
+
+Tue Apr 24 23:51:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * passwd.cc (getpwnam_r): Add pw_passwd handling as well.
+ (getpwuid_r): Ditto.
+
+Tue Apr 24 23:43:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * passwd.cc (getpwnam_r): Use correct offsets into buffer.
+ Copy pw_gecos field as well.
+ (getpwuid_r): Ditto.
+
+2001-04-24 Egor Duda <deo@logos-m.ru>
+
+ * dlmalloc.c: New file. Port of Doug Lea's malloc
+ * dlmalloc.h: Ditto.
+ * Makefile.in: Add support for MALLOC_DEBUG
+ * config.h.in: Ditto.
+ * winsup.h: Ditto.
+ * configure.in: Add --enable-malloc-debugging option.
+ * configure: Regenerate.
+ * debug.h: Include declarations for debugging malloc.
+ * tty.cc (grantpt): Fix definition.
+ (unlockpt): Ditto.
+
+Mon Apr 23 22:00:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Remove trailing underscore from fhandler_base and friends, throughout.
+ * fhandler.h (fhandler_base::set_open_status): New method. Stores
+ original open status.
+ (fhandler_base::get_open_status): New method. Retrieves original open
+ status.
+ (fhandler_base::reset_to_open_binmode): New method.
+ * fhandler.cc (fhandler_base::open): Save open status.
+ (fhandler_base::init): Ditto.
+ * fhandler_clipboard.cc (fhandler_clipboard::open): Ditto.
+ * fhandler_console.cc (fhandler_console::open): Ditto.
+ * fhandler_dsp.cc (fhandler_dsp::open): Ditto.
+ * fhandler_dev_mem.cc (fhandler_dev_mem::open): Ditto.
+ * fhandler_dev_random.cc (fhandler_dev_random::open): Ditto.
+ * fhandler_serial.cc (fhandler_serial::open): Ditto.
+ * fhandler_tty_slave.cc (fhandler_tty_slave::open): Ditto.
+ * fhandler_tty_master.cc (fhandler_tty_master::open): Ditto.
+ * fhandler_dev_zero.cc (fhandler_dev_zero::open): Ditto.
+ * syscalls.cc (setmode): Rework so that 0 mode value causes reversion
+ to open state.
+
+ * fhandler_tty_slave.cc (fhandler_tty_slave::read): Use correct
+ multiplier when converting from deciseconds to milliseconds.
+
+Mon Apr 23 13:28:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.h (fhandler_base::clear_r_binary): New method.
+ (fhandler_base::clear_w_binary): New method.
+ * syscalls.cc (setmode): Accept 0 as mode value. Resets text/binary
+ behavior for fd to default.
+
+Mon Apr 23 12:46:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * net.cc [errmap]: Add '0' condition.
+ (find_winsock_errno): Don't translate no error to EPERM.
+
+Sun Apr 22 20:48:24 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump Cygwin version and API version.
+
+Mon Apr 23 9:27:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (MTinterface::Init): Always initialise per process variables.
+
+Sun Apr 22 19:18:18 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * features.h: Reinstate as wrapper for sys/features.h.
+
+Mon Apr 23 0:10:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (alloc_sd): Reformat comment.
+ * shared.cc: Drop function declarations already in security.h.
+
+Sun Apr 22 12:17:57 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * shortcut.c (check_shortcut): Close input file handle before
+ returning.
+ * path.cc (check_sysfile): Ditto.
+ (symlink_info::check): Rely on opened file handle being closed by
+ symlink checking routines. Set ext_tacked_on when .lnk is detected.
+
+Sat Apr 21 19:26:05 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * thread.cc (MTinterface::Init): Remove accidentally checked in code.
+
+Sun Apr 22 00:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * passwd.cc (getpwuid): Check for thread cancellation.
+ (getpwuid_r): Ditto.
+ (getpwname): Ditto.
+ (getpwnam_r): Ditto.
+ * thread.h (pthread_mutex): New constructors for pshared operation.
+ (MTinterface): Associative array for pshared mutex's.
+ * thread.cc (MTinterface::Init): Initailize pshared mutex array.
+ (pthread_cond::BroadCast): Implementation notes.
+ (pthread_cond::TimedWait): Remove use of SignalObjectAndWait on non-NT systems.
+ (pthread_mutex::pthread_mutex(unsigned short)): New function.
+ (pthread_mutex::pthread_mutex (pthread_mutex_t *, pthread_mutexattr *)):New function.
+ (pthread_mutex::pthread_mutex(pthread_mutexattr *)): Fail on pshared mutex's.
+ (__pthread_mutex_getpshared): New function.
+ (__pthread_join): Check for thread cancellation.
+ (__pthread_cond_timedwait): Support pshared mutex's.
+ (__pthread_cond_wait): Ditto.
+ (__pthread_condattr_setpshared): Error on PROCESS_SHARED requests.
+ (__pthread_mutex_init): Support pshared mutex's.
+ (__pthread_mutex_getprioceiling): Ditto.
+ (__pthread_mutex_lock): Ditto.
+ (__pthread_mutex_trylock): Ditto.
+ (__pthread_mutex_unlock): Ditto.
+ (__pthread_mutex_destroy): Ditto.
+ (__pthread_mutex_setprioceiling): Ditto.
+ (__pthread_mutexattr_setpshared): Support PTHREAD_PROCESS_PSHARED requests.
+
+Fri Apr 20 19:38:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.din: Add *scanf and *scan_r functions.
+
+Fri Apr 20 22:25:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (set_process_privileges): Swap out.
+ * sec_helper.cc (set_process_privilege): Rename from
+ `set_process_privileges'. Takes the privilege to enable or disable
+ as parameter now.
+ * security.h: Add prototype for `set_process_privileges'.
+
+2001-04-19 Egor Duda <deo@logos-m.ru>
+
+ * path.cc (path_conv::check): Always initialize member variables.
+
+Fri Apr 20 12:27:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/sys/file.h: More cleanup for X_OK.
+
+Fri Apr 20 11:48:45 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/sys/file.h: Move X_OK protection earlier.
+
+ * dtable.cc (dtable::vfork_child_fixup): Avoid closing already closed
+ handles.
+
+Fri Apr 20 16:29:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (getgroups): Change so that SIDs get compared instead
+ of strings to SIDs.
+
+Fri Apr 20 14:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in: Add object files `sec_helper.cc' and `sec_acl.cc'.
+ * security.cc: Swap out several functions.
+ * sec_acl.cc: New file. Move Sun compatibel ACL functions from
+ `security.cc' to here.
+ * sec_helper.cc: New file. Move security helper functions from
+ `security.cc' to here.
+ * security.h: Changed to accommodate the above changes.
+
+Fri Apr 20 14:12:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc: Replace `group_in_memory_p' by `group_state'.
+ Eliminate group_sem throughout.
+ (enum grp_state): New enumeration type.
+ (read_etc_group): Make race safe.
+ * security.cc: Eliminate group_sem throughout.
+
+Thu Apr 19 9:40:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Drop usage of the same memory area if the same
+ region of the same file is mapped twice.
+
+Wed Apr 18 16:53:54 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, change fdtab references to cygheap->fdtab.
+ * child_info.h (cygheap_exec_info): Eliminate special fdtab stuff.
+ * spawn.cc (spawn_guts): Ditto.
+ * cygheap.cc (cygheap_init): Initialize fdtab, if appropriate.
+ * cygheap.h (CYGHEAPSIZE): Include size of init_cygheap.
+ (_cmalloc_entry): Include fdtab here.
+ * dtable.h (dtable): Declare/define new methods.
+ * dtable.cc (dtable::vfork_child_fixup): New method.
+ (dtable::fixup_after_exec): Remove unneeded extra arguments.
+ * dcrt0.cc (dll_crt0_1): Ditto.
+
+ * environ.cc (getwinenv): Use case sensitive comparison.
+ (winenv): Make a copy of environment cache to avoid realloc problems
+ when duplicate environment variables exist in the environment. (From
+ Egor Duda)
+
+ * net.cc (cygwin_socket): Revert Apr 14 change.
+
+ * include/sys/file.h: Protect against previous X_OK definition.
+
+Tue Apr 17 12:18:28 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * passwd.cc: Eliminate passwd_sem throughout.
+ * security.cc: Ditto.
+
+Tue Apr 17 12:18:28 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygwin.din: Export New functions.
+ * passwd.cc (read_etc_passwd): Make race safe.
+ (getpwuid_r): New function.
+ (getpwnam_r): New function.
+
+2001-04-18 Egor Duda <deo@logos-m.ru>
+
+ * grp.cc (getgroups): Avoid crash if passwd field if /etc/group is
+ empty.
+
+Tue Apr 17 19:05:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.h (path_conv::add_ext_from_sym): Declare.
+ * path.cc (path_conv::add_ext_from_sym): Convert to pure inline method.
+
+Tue Apr 17 18:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (windows_device_names): Add missing NULL element.
+
+Tue Apr 17 12:14:54 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (windows_device_names): Move dsp to proper location.
+
+Tue Apr 17 13:44:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (path_conv::check): Set case_clash even if pcheck_case
+ is set to PCHECK_ADJUST when a case clash is given for the last
+ component in path.
+ (symlink_info::case_check): Ditto.
+ * syscalls.cc (_rename): Avoid overwriting an already existing file
+ if a case clash is given even if pcheck_case is set to PCHECK_ADJUST.
+
+Tue Apr 17 2:07:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * config.h.in: Turn off VFORK again.
+
+Mon Apr 16 23:45:24 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.h (cwdstuff): Move class.
+ * cygheap.h (cwdstuff): To here.
+ (init_cygheap): Add cwd field.
+ * child_info.h (cygheap_exec_info): Eliminate cwd stuff.
+ (child_info_spawn): Ditto.
+ * dcrt0.cc (dll_crt0_1): Remove cygcwd.fixup_after_exec call. Convert
+ cygcwd reference to cygheap->cwd.
+ * path.cc: Ditto, throughout.
+ (cwdstuff::copy): Eliminate.
+ (cwdstuff::fixup_after_exec): Ditto.
+ * spawn.cc (spawn_guts): Eliminate call to cygcwd.copy.
+
+ * fhandler.h (FH_OSS_DSP): Move into "fast" device category.
+
+Mon Apr 16 19:19:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc: Move fh_paging_file from some functions to be
+ a global static variable.
+ (class mmap_record): Add `devtype_' member to remember
+ the device type of the file. Add declaration for methods
+ `get_device', `alloc_fh' and `free_fh'.
+ (mmap_record::mmap_record): Initialize `devtype_' correctly.
+ (mmap_record::alloc_fh): New method.
+ (mmap_record::free_fh): Ditto.
+ (munmap): Use new mmap_record::alloc_fh and mmap_record::free_fh
+ methods to create a correct fhandler.
+ (msync): Ditto.
+ (fixup_mmaps_after_fork): Ditto.
+
+Mon Apr 16 16:01:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (getgroups): If `allow_ntsec' is set, use the process token
+ information to evaluate the groups list.
+
+Mon Apr 16 00:08:02 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * features.h: Remove this file as it is now being supplied by newlib.
+
+Sun Apr 15 23:23:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * autoload.cc: Add winmm functions needed by fhandler_dsp.cc.
+
+Sun Apr 15 22:53:52 2001 Andy Younger <andylyounger@hotmail.com>
+
+ * fhandler_dsp.cc: New file. Implements OSS like /dev/dsp.
+ * include/sys/soundcard.h: New file. User land includes for OSS
+ /dev/dsp.
+ * fhandler.h: Add new class fhandler_dev_dsp and a FH_OSS_DSP
+ definition.
+ * dtable.cc (dtable::build_fhandler): Allow creation of the /dev/dsp
+ device.
+ * path.cc (windows_device_names): Add /dev/dsp into list of device
+ names.
+ * Makefile.in (DLL_OFILES): Add fhandler_dsp.o.
+
+Sun Apr 15 16:36:27 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * uname.c (uname): Default n in in86 to 6 if Windows returns > 6.
+
+Sun Apr 15 15:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (add_ext_from_sym): Redefine to call `add_ext_from_sym_'.
+ (add_ext_from_sym_): New inline function.
+
+Sat Apr 14 19:23:52 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * config.h.in: Turn on VFORK by default.
+
+Sat Apr 14 18:04:35 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * net.cc (cygwin_socket): Set SO_LINGER to small value so closed UNIX
+ domain sockets will not stay around.
+
+Sat Apr 14 18:01:43 2001 Pierre A. Humblet <Pierre.Humblet@ieee.org>
+
+ * select.cc (socket_cleanup): Set SO_LINGER to small value so closed
+ dummy sockets do not stay around. Use correct value for second argument
+ to shutdown.
+
+Sat Apr 14 17:04:00 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.h (MTinterface): Add threadcount.
+ * thread.cc (MTinterface::Init): Set threadcount to 1.
+ (__pthread_create): Increment threadcount.
+ (__pthread_exit): Decrement threadcount and call exit() from the last thread.
+
+Fri Apr 13 11:34:24 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * fork.cc (fork_child): Call the __pthread_atforkchild function.
+ (fork_parent): Call the __pthread_atforkparent function.
+ * cygwin.din: Export pthread_atfork.
+ * thread.h (callback): New class.
+ (MTinterface): Use it.
+ * thread.cc (__pthread_atforkprepare): New function.
+ (__pthread_atforkparent): New function.
+ (__pthread_atforkchild): New function.
+ (__pthread_atfork): New function.
+ * pthread.cc (pthread_atfork): New function.
+
+Fri Apr 13 9:52:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (add_ext_from_sym): New define evaluating `known'suffix'.
+ (path_conv::check): Use add_ext_from_sym throughout.
+
+Thu Apr 12 23:19:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (mkdir): Check for case clash.
+ * environ.cc: Add extern declaration for `pcheck_case'.
+ (check_case_init): New function.
+ (struct parse_thing): Add "check_case" option.
+ * errno.cc (_sys_nerrlist): Add text for ECASECLASH.
+ (strerror): Add case branch for ECASECLASH.
+ * fhandler.cc (fhandler_disk_file::open): Check for case clash.
+ * path.cc: Add global variable `pcheck_case'.
+ (struct symlink_info): Add member `case_clash' and method `case_check'.
+ (path_prefix_p_): Call `pathnmatch' instead of `strncasematch'.
+ (pathnmatch): New funtion.
+ (pathmatch): Ditto.
+ (path_conv::check): Add handling for case checking.
+ (symlink): Check for case clash.
+ (symlink_info::check): Add parameter for case checking.
+ Handle case checking.
+ (symlink_info::case_check): New method.
+ (chdir): Don't use unconverted path if pcheck_case==PCHECK_STRICT.
+ * path.h: Add extern declarations for `pathmatch' and
+ `pathnmatch'.
+ (enum case_checking): New enumeration type describing
+ the case checking behaviour of path conversion routines.
+ (class path_conv): Add member `case_clash'.
+ * syscalls.cc (_link): Check for case clash.
+
+Thu Apr 12 12:49:53 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (mkfifo): New function stub.
+
+2001-04-12 Robert Collins <rbtcollins@hotmail.com>
+
+ * configure.in: Remove PTH_ALLOW.
+ * cygwin.din: Remove @PTH_ALLOW@ prefixes to pthread functions. Add
+ new pthread exports.
+ * pthread.cc: New wrapper functions for the above new exports.
+ * sched.cc (valid_sched_parameters): New function.
+ (sched_setparam): Use it.
+ (sched_set_thread_priority): New function. Used by pthread_sched*.
+ * thread.cc (pthread_key_destructor::InsertAfter): New function.
+ (pthread_key_destructor::UnlinkNext): New function.
+ (pthread_key_destructor::Next): New function.
+ (pthread_key_destructor_list::Insert): New function.
+ (pthread_key_destructor_list::Remove): New function.
+ (pthread_key_destructor_list::Pop): New function.
+ (pthread_key_destructor::pthread_key_destructor): New function.
+ (pthread_key_destructor_list::IterateNull): New function.
+ (MTinterface::Init): Initialise new member.
+ (pthread::pthread): Initialise new members.
+ (pthread::create): Copy new attributes. Set the new thread priority.
+ (pthread_attr::pthread_attr): Initialise new members.
+ (pthread_key::pthread_key): Setup destructor function.
+ (pthread_key::~pthread_key): Remove destructor function.
+ (pthread_mutexattr::pthread_mutexattr): New function.
+ (pthread_mutexattr::~pthread_mutexattr): New function.
+ (__pthread_once): New function.
+ (__pthread_cleanup): New function.
+ (__pthread_cancel): New function.
+ (__pthread_setcancelstate): New function.
+ (__pthread_setcanceltype): New function.
+ (__pthread_testcancel): New function.
+ (__pthread_attr_getinheritsched): New function.
+ (__pthread_attr_getschedparam): New function.
+ (__pthread_attr_getschedpolicy): New function.
+ (__pthread_attr_getscope): New function.
+ (__pthread_attr_setinheritsched): New function.
+ (__pthread_attr_setschedparam): New function.
+ (__pthread_attr_setschedpolicy): New function.
+ (__pthread_attr_setscope): New function.
+ (__pthread_exit): Call any key destructors on thread exit.
+ (__pthread_join): Use the embedded attr values.
+ (__pthread_detach): Use the embedded attr values.
+ (__pthread_getconcurrency): New function.
+ (__pthread_getschedparam): New function.
+ (__pthread_key_create): Pass the destructor on object creation.
+ (__pthread_key_delete): Correct incorrect prototype.
+ (__pthread_setconcurrency): New function.
+ (__pthread_setschedparam): New function.
+ (__pthread_cond_timedwait): Support static mutex initialisers.
+ (__pthread_cond_wait): Ditto.
+ (__pthread_mutex_getprioceiling): New function.
+ (__pthread_mutex_lock): Support static mutex initialisers.
+ (__pthread_mutex_trylock): Ditto.
+ (__pthread_mutex_unlock): Ditto.
+ (__pthread_mutex_destroy): Ditto.
+ (__pthread_mutex_setprioceiling): New function.
+ (__pthread_mutexattr_getprotocol): New function.
+ (__pthread_mutexattr_getpshared): New function.
+ (__pthread_mutexattr_gettype): New function.
+ (__pthread_mutexattr_init): New function.
+ (__pthread_mutexattr_destroy): New function.
+ (__pthread_mutexattr_setprotocol): New function.
+ (__pthread_mutexattr_setprioceiling): New function.
+ (__pthread_mutexattr_getprioceiling): New function.
+ (__pthread_mutexattr_setpshared): New function.
+ (__pthread_mutexattr_settype): New function. Remove stubs for non
+ MT_SAFE compilation.
+ * thread.h: Remove duplicate #defines. Add prototypes for new
+ functions in thread.cc.
+ (pthread_key_destructor): New class.
+ (pthread_key_destructor_list): New class.
+ (pthread_attr): Add new members.
+ (pthread): Remove members that are duplicated in the pthread_attr
+ class.
+ (pthread_mutex_attr): Add new members.
+ (pthread_once): New class.
+ * include/pthread.h: Add prototypes for new functions exported from
+ cygwin1.dll. Remove typedefs.
+ * include/sched.h: Add prototypes for new functions in sched.cc.
+ * include/cygwin/types.h: Add typedefs from pthread.h
+
+Tue Apr 10 22:02:53 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (struct symlink_info): Add extn and ext_tacked_on fields.
+ (path_conv::check): Only tack on extension if a known one didn't
+ already exist.
+ (suffix_scan::has): Return pointer to known extension.
+ (symlink_info::check): Record location of extension, if any.
+
+2001-04-09 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (class fhandler_socket): Add members and methods to
+ support secure connections on AF_UNIX sockets.
+ * fhandler_socket.cc (fhandler_socket::set_connect_secret): New method.
+ (fhandler_socket::get_connect_secret): Ditto.
+ (fhandler_socket::create_secret_event): Ditto.
+ (fhandler_socket::close_secret_event): Ditto.
+ (fhandler_socket::check_peer_secret_event): Ditto.
+ (fhandler_socket::fixup_after_fork): Duplicate secret event to child.
+ (fhandler_socket::dup): Copy address family.
+ (fhandler_socket::close): Close secret event.
+ * net.cc (get_inet_addr): Read secret cookie.
+ (cygwin_connect): Check if peer knows secret cookie value.
+ (cygwin_accept): Ditto. Copy address family to newly created socket.
+ (cygwin_bind): Generate and write secret cookie.
+ (wsock_init): Initialize random number generator.
+
+Sun Apr 8 20:40:58 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Put -lgcc last in list of libraries, since stdc++
+ library needs it.
+ * cygwin.din: Remove obsolete "__empty" export.
+ * exceptions.cc (call_signal_handler_now): Force inclusion of function
+ even when -finline-functions is specified.
+ * sigproc.h: Remove obsolete call_signal_handler declaration.
+
+Sun Apr 8 20:36:55 2001 Benjamin Riefenstahl <Benjamin.Riefenstahl@epost.de>
+
+ * fhandler_console.cc (cp_get_internal): New function.
+ (cp_convert): New function.
+ (con_to_str): New function.
+ (str_to_con): New function.
+ (fhandler_console::read): Replace OemToCharBuff with con_to_str.
+ (fhandler_console::write_normal): Replace CharToOemBuff with str_to_con.
+
+Thu Apr 5 22:41:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (stat_worker): Fix conditional which still allowed
+ successful stat'ing of non-existant files.
+
+Wed Apr 4 10:37:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h: Bump magic number for fork/exec/spawn.
+
+Tue Apr 3 20:06:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * errno.cc (errmap): Map ERROR_FILE_INVALID to ENXIO.
+
+Mon Apr 2 22:48:58 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygrun.c (main): Fix compiler warning.
+ * gmon.c (_mcleanup): Ditto.
+ * profil.c (profile_off): Ditto.
+
+ * net.cc (find_winsock_errno): New function.
+ (__set_winsock_errno): Use find_winsock_errno.
+ (cygwin_setsockopt): Detect SO_ERROR for debugging.
+ (cygwin_getsockopt): Ditto. Translate error when getsockopt returns
+ SO_ERROR.
+ * winsup.h: regparmize __set_winsock_errno.
+ * include/sys/strace.h: Document that strace functions can't use
+ regparm.
+
+2001-04-02 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * fhandler.cc (fhandler_disk_file::open): Avoid checking a magic
+ number of a directory.
+
+Mon Apr 2 00:24:08 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * shared_info.h (mount_info): Remove mnt_ elements.
+ * thread.h (struct _winsup_t): Add mnt_ elements.
+ * path.cc (fillout_mntent): Use mnt_ elements from reent_winsup ().
+
+Sun Apr 1 20:10:34 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (sigframe::call_signal_handler): Return value of
+ call_signal_handler_now.
+ * sigproc.h (sigframe): Use constructor.
+ * syscalls.cc (_read): Correct errno test prior to calling signal
+ handler.
+
+Sun Apr 1 00:38:06 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (sigframe::call_signal_handler): Move outside of "C"
+ block or some compilers will complain.
+
+Sun Apr 1 00:24:14 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (call_signal_handler_now): Rename from
+ call_signal_handler to avoid C++ confusion.
+
+Sun Apr 1 00:08:15 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (fillout_mntent): Always remove drive root directories from
+ future consideration by "/cygdrive" reporting.
+ (cygdrive_getmnt): Avoid reporting removable drives or drives with no
+ media mounted.
+
+Sat Mar 31 21:56:19 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * thread.h (struct _winsup_t): Remove obsolete elements. Add
+ available_drives element.
+ * path.cc (mount_info::getmntent): Report "/cygdrive" drives when
+ mounted drives are exhausted.
+ (fillout_mntent): New function.
+ (mount_item::getmntent): Use fillout_mntent.
+ (cygdrives_mntent): New function. Returns next available "/cygdrive".
+ (setmntent): Initialize available "/cygdrives".
+ * syscalls.cc: Remove some if 0'ed code.
+ * times.cc (timezone): Use more descriptive variable name.
+
+Sat Mar 31 18:59:52 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.h (class sigframe): Implement 'unregister()' method.
+ (sigframe::~sigframe): Use unregister method.
+ (sigframe::call_signal_handler): Declare new method.
+ * exceptions.cc (sigframe::call_signal_handler): New method.
+ Unregisters current sigframe before calling signal handler.
+ (setup_handler): Clear waiting threads prior to arming signal_arrived.
+ * syscalls.cc (_read): Change goto to loop. Recalculate sigframe
+ inside of loop so that constructor is called when appropriate.
+ * wait.cc (wait4): Ditto.
+
+ * signal.cc: Change "sig" to "signal" in debugging messages throughout.
+ * sigproc.cc: Ditto.
+
+Sat Mar 31 17:12:08 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_serial.cc (fhandler_serial::raw_write): Close protected
+ handles with ForceCloseHandle or suffer spurious warnings.
+
+Sat Mar 31 16:23:32 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler.cc (fhandler_base::read): Remove special handling of CTRL-Z.
+
+Sat Mar 31 11:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (class fhandler_console): Add members `insert_mode'.
+ * fhandler_console.cc (fhandler_console::dup): Duplicate `insert_mode'.
+ (fhandler_console::fhandler_console): Initialize `insert_mode'.
+ (fhandler_console::char_command): Add terminal capabilities
+ "enter insert mode" = \E[4h and "exit insert mode" = \E[4l.
+ Care for insert mode on terminal capability "repeat char" = \E[x;yb.
+ (fhandler_console::write_normal): Care for insert mode before writing
+ to the console.
+ (array keytable): Add keymapping for modified cursor and control
+ block keys (xterm like).
+
+Fri Mar 30 13:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (class fhandler_console): Add members `savebufsiz' and
+ `savebuf' to allow save/restore of screen.
+ * fhandler_console.cc (fhandler_console::dup): Duplicate `savebufsiz'
+ and `savebuf'.
+ (fhandler_console::fhandler_console): Initialize `savebufsiz' and
+ `savebuf'.
+ (fhandler_console::char_command): Add terminal capabilities
+ "save screen content" = \E[?47h and "restore screen content" = \E[?47l.
+
+Wed Mar 28 19:28:50 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (chdir): Eat trailing whitespace on input path.
+
+Tue Mar 27 22:38:42 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * lib/_cygwin_S_IEXEC.c: Remove "const" from globals or they never seem
+ to be defined. Wrap definitions in extern "C". Include winsup.h to
+ assure proper definitions.
+
+ * dcrt0.cc (dll_crt0_1): Call stdio_init after premain run so that
+ binmode.o, etc., will control default stdio settings.
+ * dtable.cc (dtable::init_std_file_from_handle): Allow __fmode to force
+ binmode/textmode settings. Default pipes to binmode.
+
+Tue Mar 27 11:31:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Fix conditional for previous patch.
+
+Mon Mar 26 18:48:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Outflank copy-on-write problem on 9x by
+ setting access mode to FILE_MAP_READ when read access is requested.
+
+Sun Mar 25 20:12:21 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dlfcn.cc (check_access): Eliminate.
+ (check_path_access): Use passed in path_conv buf.
+ (get_full_path_of_dll): Use passed in name buf to avoid a static. Rip
+ out most of the path checking since LoadLibrary will do all of this
+ automatically.
+ (dlopen): Set errno when appropriate (may not be compliant?).
+ * environ.cc (posify): Don't pass in "native" path if it seems to
+ actually be posix.
+
+Thursday Mar 22 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * fhandler.h (fhandler_dev_clipboard): Extend to support writing.
+ * fhandler_clipboard.cc (fhandler_dev_clipboard::fhandler_dev_clipboard):
+ Initialize new fields. Open clipboard here.
+ (fhandler_dev_clipboard::dup): New method.
+ (fhandler_dev_clipboard::open): Accommodate new fields. Register
+ clipboard here, if appropriate.
+ (set_clipboard): New function. Moves buffer to clipboard.
+ (fhandler_dev_clipboard::write): Truly implement clipboard writing.
+ (fhandler_dev_clipboard::read): Reimplement to allow successive reads.
+ (fhandler_dev_clipboard::lseek): Truly implement seeks in clipboard.
+ (fhandler_dev_clipboard::close): Clear out new fields. Support
+ sequential reads and sequential writes. Support for binary data via a
+ native clipboard format.
+
+2001-03-22 Egor Duda <deo@logos-m.ru>
+
+ * fhandler_console.cc (fhandler_console::set_default_attr): Update
+ console color attributes on tty reset.
+
+Wed Mar 21 22:12:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * autoload.cc (kernel32_init): New function for kernel32 autoload
+ initialization.
+ (SignalObjectAndWait): Add conditional load of this function when it is
+ available.
+
+2001-03-21 Robert Collins <rbtcollins@hotmail.com>
+
+ * sched.cc: New file. Implement sched*.
+ * include/sched.h: New file. User land includes for sched*.
+ * Makefile.in: Add sched.o
+ * cygwin.din: Add exports for sched*.
+
+Tue Mar 20 14:48:46 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.cc: Guard against new winsock.h/winsock2.h warnings when
+ mixing winsock*.h and sys/types.h.
+ * fhandler_socket.cc: Ditto.
+ * net.cc: Ditto.
+ * select.cc: Ditto.
+ * exceptions.cc: Remove unneeded define.
+
+Mon Mar 19 17:43:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (interruptible): Update debugging output.
+ (setup_handler): Ensure that wait_sig loop wakes up when we punt on
+ sending a signal.
+ * poll.cc (poll): Add signal guard here.
+
+2001-03-19 Egor Duda <deo@logos-m.ru>
+
+ * tty.h (tty::create_inuse): Add new parameter to allow non-
+ inheritable 'inuse' events.
+ * tty.cc (tty::create_inuse): Use new parameter.
+ * fhandler_tty.cc (fhandler_tty_master::init): Ditto.
+ * fhandler_tty.cc (fhandler_pty_master::open): Ditto.
+ * fhandler_tty.cc (fhandler_tty_master::init): Create master_alive
+ event.
+ * tty.cc (tty_list::terminate): Close master_alive event.
+ * fhandler_tty.cc (fhandler_tty_common::close): Send EOF to slaves
+ when master side is closed.
+
+Mon Mar 19 14:32:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (map::get_list_by_fd): Avoid calling `get_namehash' when
+ file descriptor is -1.
+
+Sat Mar 17 18:30:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (check_posix_perm): New static function.
+ (fpathconf): Add _PC_POSIX_PERMISSIONS and _PC_POSIX_SECURITY
+ support.
+ (pathconf): Ditto.
+ * include/cygwin/version.h: Bump API minor number to 37.
+
+2001-03-18 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (fhandler_tty_slave): Declare new methods.
+ * select.cc (fhandler_tty_slave::select_read): New method.
+ * select.cc (fhandler_tty_slave::ready_for_read): Ditto.
+ * select.cc (verify_tty_slave): New function.
+ * fhandler_termios.cc (fhandler_termios::line_edit): Empty input
+ buffer on signal.
+ * fhandler_tty.cc (fhandler_tty_slave::read): Check for input data
+ after reading from pipe. Reset event if input pipe is empty.
+ * tty.h (class tty): Allow creating events with manual reset.
+ * tty.cc (tty::get_event): Use manual_reset flag.
+ * tty.cc (tty::common_init): Create input_available_event with
+ manual reset.
+
+Sat Mar 17 21:48:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * external.cc (fillout_pinfo): Match windows pid, as well as cygwin pid
+ when passed in pid. Don't prematurely break when searching for a pid.
+
+ * thread.h (_winsup_t): Eliminate unneeded field.
+
+Sat Mar 17 20:46:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (get_95_ifconf): Use strcasematch instead of strcasecmp.
+ * syscalls.cc (_unlink): Ditto.
+ (_rename): Ditto.
+
+Sat Mar 17 12:43:15 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (suffix_scan::next): Avoid searching for foo.lnk twice when
+ input is "foo".
+
+Sat Mar 17 18:10:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_socket): Set protocol to 0 when address family is
+ AF_UNIX to avoid WSAEPROTONOSUPPORT error.
+
+Sat Mar 17 09:51:32 2001 Mathew Brozowski <brozow@tavve.com>
+
+ * net.cc (cygwin_socket): Pass protocol parameter to socket call.
+
+Sat Mar 17 02:05:38 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dir.cc (readdir): Use strcasematch for consistency.
+ * path.cc (symlink_info): Eliminate known_suffix.
+ (path_conv::check): Always copy ext_here to end of buffer, if found.
+ (suffix_scan): Eliminate ext_here, add suffixes_start.
+ (suffix_scan::has): Eliminate an argument. Reorganize. Always return
+ pointer to end of input path.
+ (suffix_scan::next): Take a second pass through the suffix list looking
+ for .lnk.
+ (symlink_info::check): Eliminate known_suffix usage.
+
+Sat Mar 17 00:10:52 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (stat_dev): Give devices full read/write by default.
+
+Saturday Mar 17 3:45 2001 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (MTinterface::CreateCond): Check for null attr pointer.
+
+Fri Mar 16 21:13:23 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_termios.cc (fhandler_termios::line_edit): Don't accept input
+ when a signal is sent or we'll end up in an EOF/signal race.
+
+Fri Mar 16 20:25:40 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc: Translate scan states from defines to enums.
+ (suffix_scan): Rename state to nextstate for clarity.
+ (lnk_match): Change to allow multiple states to indicate that a .lnk
+ has been matched.
+ (suffix_scan::has): Eliminate a goto. Handle .lnk as a special case,
+ since a .lnk may also need to be tacked on the end of a .lnk.
+ (suffix_scan::next): Don't increment next state. Set it specifically.
+ Recognize new .lnk states.
+
+Saturday Mar 17 01:19 2001 Robert Collins rbtcollins@hotmail.com
+
+ * cygwin.din: Export the new functions.
+ * pthread.cc (pthread_cond_*): Add wrapper functions that call
+ __pthread_cond* functions.
+ * thread.cc (__pthread_cond_*): Implement the pthread_cond* functions.
+ * thread.h: Add new class entries and prototypes for __pthread_cond*
+ functions.
+ * include/pthread.h: user land header prototypes for pthread_cond*
+ functions and related defines.
+
+Wed Mar 14 16:30:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * environ.cc (parse_options): Use strtok_r instead of strtok.
+ * security.cc (convert_string_sid_to_sid): Ditto.
+ (aclfromtext): Ditto. Fix buffer usage.
+
+Wed Mar 14 10:11:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (lnk_suffixes): Remove.
+ (class suffix_scan): Add `lnk_state' flag.
+ (suffix_scan::lnk_match): Return state of `lnk_state' now.
+ (suffix_scan::has): Changed behaviour if file has `.lnk' suffix.
+ (suffix_scan::next): Set `lnk_state' where appropriate.
+ (symlink_info::check): Fix a wrong `break'.
+ * syscalls.cc (chown_worker): Change debug statement to reflect
+ lchown fix.
+ (lchown): Call chown_worker with `PC_SYM_NOFOLLOW' instead of
+ `PC_SYM_IGNORE'.
+
+Tue Mar 13 13:52:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_disk_file::fstat): Add correct modes to
+ symlinks when stat'ing on FAT or FAT32 file systems.
+
+2001-03-12 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (fhandler_termios::fixup_after_exec): New function.
+ * fhandler_termios.cc (fhandler_termios::fixup_after_fork): New
+ function. Fixup output handle.
+ * fhandler_tty.cc (fhandler_tty_common::fixup_after_fork): Output
+ handle is now fixed up in fhandler_termios::fixup_after_fork().
+
+2001-03-12 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (fhandler_termios::fhandler_termios): Enable fixup
+ after fork.
+ * fhandler_console.cc (fhandler_console::fhandler_console): Fixup
+ after fork is now enabled in the base class constructor.
+
+Mon Mar 12 11:19:41 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * mkvers.sh: Include config.h so that DEBUGGING is correctly defined.
+
+Mon Mar 12 09:47:55 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * spawn.cc (spawn_guts): Don't set EXIT_REPARENTING if parent process
+ is not a cygwin process (suggested by Jason Gouger
+ <cygwin@jason-gouger.com>).
+
+Sun Mar 11 16:00:58 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h: Bump magic number for fork/exec/spawn.
+
+Sat Mar 10 20:54:47 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * autoload.cc (noload): Use proper method for multiline strings or
+ newer gcc's complain.
+ * exceptions.cc (unused_sig_wrapper): Ditto.
+ * fhandler.h (fhandler_base): Make get_io_handle and friends return
+ self.
+ * fhandler_tty.cc (fhandler_pty_common::close_on_exec): Accommodate
+ DEBUGGING flag to avoid spurious warnings when inheritance is set.
+
+Sat Mar 10 16:52:12 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * shortcut.c (PATH_ALL_EXEC): Add parentheses to avoid a compiler
+ warning.
+
+ * exceptions.cc (setup_handler): Clarify debugging message.
+ * sigproc.cc (proc_subproc): Remove PROC_CHILDSTOPPED test. It is
+ handled by normal PROC_CLEARWAIT case.
+ (wait_sig): Eliminate "dispatched" tracking. Remove __SIGCHILDSTOPPED
+ test. Decrement counter again before jumping out of
+ InterlockedDecrement loop so that subsequent InterlockedIncrement will
+ keep the counter at the correctly decremented value and also detect
+ when there are pending signals.
+ * sigproc.h: Remove __SIGCHILDSTOPPED element.
+ (procstuff): Remove PROC_CHILDSTOPPED element.
+
+Sat Mar 10 15:22:44 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_rename): Set errno to ENOENT when an old path doesn't
+ exist (from Kazuhiro Fujieda <fujieda@jaist.ac.jp>). Also set EACCES
+ when directory is not writable.
+
+Wed Mar 7 15:49:47 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_read): Change definition to return ssize_t to be
+ consistent with read.
+ (_write): Change definition to return ssize_t to be consistent with
+ write.
+
+Wed Mar 7 01:08:21 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * sigproc.h (sigthread): Declare new methods. Create new winapi_lock
+ field.
+ (sigframe:;set): Call get_winapi_lock after frame is set so that signal
+ handler thread knows not to call SuspendThread.
+ (sigframe::~sigframe): Release winapi_lock.
+ * exceptions.cc (sigthread::get_winapi_lock): New method.
+ (sigthread::release_winapi_lock): New method.
+ (setup_handler): Use get_winapi_lock to ensure that signalled thread is
+ not blocked in a Windows API.
+
+ * path.h (path_types): Avoid broken GCC warning.
+
+Tue Mar 6 14:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (suffix_scan::has): Change order of conditionals
+ to allow checking for .lnk suffixes even if in_suffixes is empty.
+
+Tue Mar 6 13:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.c (cygwin_premain0): Add missing parameter.
+ * binmode.c (cygwin_premain0): Ditto.
+ * textmode.c (cygwin_premain0): Ditto.
+
+Tue Mar 6 12:04:00 2001 Jason Tiller <jtiller@sjm.com>
+
+ * auto_load.cc: Add "GetKeyboardLayout" entry in the list of
+ Win32 User32.DLL exports to provide.
+ * fhandler.h (class fhandler_console): Add meta_mask private
+ member to remember which keystroke modifiers should generate
+ META.
+ * fhandler_console.cc (fhandler_console::read): Modify code that
+ tests a keystroke for a META-escaped key to use the 'meta_mask'
+ variable.
+ (fhandler_console::fhandler_console): Add definition for
+ variable "meta_mask" used to determine if a keystroke should be
+ preceded by META in the client console stream. Set meta_mask
+ based on whether or not user's keyboard language is English -
+ non-English keyboards pass AltGr (right <ALT>) unmolested,
+ whereas English keyboards now interpret left- and right-<ALT>
+ as META.
+
+Mon Mar 5 20:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/a.out.h: Add copyright hint.
+ * include/fcntl.h: Ditto.
+ * include/lastlog.h: Ditto.
+ * include/memory.h: Ditto.
+ * include/mntent.h: Ditto.
+ * include/paths.h: Ditto.
+ * include/poll.h: Ditto.
+ * include/syslog.h: Ditto.
+ * include/termio.h: Ditto.
+ * include/tzfile.h: Ditto.
+ * include/arpa/inet.h: Ditto.
+ * include/asm/byteorder.h: Ditto.
+ * include/asm/socket.h: Ditto.
+ * include/asm/types.h: Ditto.
+ * include/cygwin/if.h: Ditto.
+ * include/cygwin/mtio.h: Ditto.
+ * include/cygwin/rdevio.h: Ditto.
+ * include/cygwin/socket.h: Ditto.
+ * include/net/if.h: Ditto.
+ * include/netinet/in.h: Ditto.
+ * include/netinet/in_systm.h: Ditto.
+ * include/netinet/ip.h: Ditto.
+ * include/netinet/ip_icmp.h: Ditto.
+ * include/netinet/tcp.h: Ditto.
+ * include/sys/cdefs.h: Ditto.
+ * include/sys/cygwin.h: Ditto.
+ * include/sys/ioctl.h: Ditto.
+ * include/sys/mman.h: Ditto.
+ * include/sys/mount.h: Ditto.
+ * include/sys/mtio.h: Ditto.
+ * include/sys/procfs.h: Ditto.
+ * include/sys/resource.h: Ditto.
+ * include/sys/smallprint.h: Ditto.
+ * include/sys/socket.h: Ditto.
+ * include/sys/strace.h: Ditto.
+ * include/sys/syslog.h: Ditto.
+ * include/sys/sysmacros.h: Ditto.
+ * include/sys/termio.h: Ditto.
+ * include/sys/termios.h: Ditto.
+ * include/sys/uio.h: Ditto.
+ * include/sys/un.h: Ditto.
+ * include/sys/utsname.h: Ditto.
+ * include/sys/vfs.h: Ditto.
+ * include/sys/wait.h: Ditto.
+ * regexp/regerror.c: Ditto.
+ * regexp/regexp.h: Ditto.
+ * regexp/regmagic.h: Ditto.
+
+Mon Mar 5 01:25:03 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dlopen.c (dlopen): Return NULL when name is NULL (suggested by
+ chrisiasci@aol.com).
+
+ * cygwin.din: Add a new, internally used export -
+ _check_for_executable.
+ * dcrt0.cc (dll_crt0_1): Set _check_for_executable for older binaries.
+ Pass user_data to premain functions.
+ * fhandler.cc (fhandler_disk_file::open): Only check for executable if
+ the linked program is interested in the executable bit.
+ (fhandler_disk_file::check_execable_p): Delete.
+ * fhandler.h (executable_states): New enumeration of various states of
+ executable bit caring.
+ (fhandler_base::set_execable_p): New method.
+
+ * fhandler_termios.cc (fhandler_termios::line_edit): Flag when a signal
+ has been sent to the tty. Return -1 when this is so.
+ * fhandler_console.cc (fhandler_console::read): Return -1 when signal
+ sending character encountered.
+
+ * path.cc (path_conv::check): Record when path refers to a disk device.
+ Move executable extension check here.
+ (check_sysfile): Accommodate new EXEC path states.
+ (has_suffix): Remove.
+ (next_suffix): Remove.
+ (class suffix_scan): New clas.
+ (suffix_scan::has): New method.
+ (suffix_scan:next): New method.
+ (symlink_info::check): Use suffix_scan method to control for scanning
+ for suffixes.
+ * path.h (path_conv::exec_state): New method.
+ * perprocess.h: Make "C" friendly.
+ * include/cygwin/version.h: Define CYGWIN_VERSION_CHECK_FOR_S_IEXEC.
+ Bump CYGWIN_VERSION_API_MINOR.
+ * include/sys/cygwin.h: Change premain declarations.
+
+ * winsup.h: Move __cplusplus test to after builtin defines.
+
+2001-03-04 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (class fhandler_tty_common): New mutex and event to
+ syncronize input on master tty with slave tty.
+ * fhandler_tty.cc (fhandler_pty_master::accept_input): Use them to
+ syncronize with slave.
+ * fhandler_tty.cc (fhandler_tty_slave::read): Use input mutex and
+ event to syncronize with master. Do not limit amount of data read
+ from master to vmin value. Interrupt on signal and return already
+ read data, if any.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Handle input mutex and
+ event.
+ * fhandler_tty.cc (fhandler_tty_common::close): Ditto.
+ * fhandler_tty.cc (fhandler_tty_common::set_close_on_exec): Ditto.
+ * fhandler_tty.cc (fhandler_tty_common::fixup_after_fork): Ditto.
+ * fhandler_tty.cc (fhandler_tty_common::dup): Ditto.
+ * tty.h (tty::open_input_mutex): New function.
+ * tty.cc (tty::common_init): Create input mutex and event.
+
+Fri Mar 2 13:32:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (readdir): Fix creating path in symlink check.
+
+Fri Mar 2 12:33:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * dir.cc (readdir): Fix shortcut==symlink condition.
+ * environ.cc: Add extern decl for `allow_winsymlinks'.
+ (struct parse_thing): Add entry for `[no]winsymlinks'.
+ * path.cc (symlink): Change to be able to create both,
+ symlink==shortcut and symlink==systemfile, dependent of
+ the setting of `allow_winsymlinks'.
+ * security.cc (cygwin_logon_user): Add debug output.
+ * shortcut.c: Add defines from path.h.
+ (has_exec_chars): Copy from path.h.
+ (check_shortcut): Check for executable file condition if not a
+ shortcut.
+
+Thu Mar 1 21:06:07 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (sig_handle_tty_stop): Ignore attempts to suspend a
+ process if started by non-cygwin parent.
+
+Thu Mar 1 20:48:11 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * select.cc (peek_console): Don't report read_ready on mouse events
+ unless we are looking for mouse events.
+ * fhandler.h (fhandler_console::mouse_aware): New method.
+
+Wed Feb 28 15:10:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * uinfo.cc: Eliminate `#include <wchar.h>'.
+
+2001-02-28 Egor Duda <deo@logos-m.ru>
+
+ * fhandler_floppy.cc (fhandler_dev_floppy::lseek): Determine
+ drive geometry or partition size to allow seeking from the end of
+ raw floppy device. Don't allow positioning past the end of media or
+ to offsets bigger then max off_t.
+
+2001-02-27 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (class fhandler_console): Make all variables that
+ describe "state" of console to be members of fhandler_console.
+ default_color is now the color which is set when console recieves
+ reset command.
+ * fhandler_console.cc (fhandler_console::fhandler_console): Turn
+ mouse handling and raw keyboard mode off by default. Initialize
+ state information.
+ * fhandler.cc (fhandler_console::set_raw_win32_keyboard_mode): New
+ function.
+ * fhandler_console.cc (fhandler_console::set_default_attr): New
+ function. Reset console attributes to default values.
+ * fhandler_console.cc (fhandler_console::open): Reset attributes.
+ * fhandler_console.cc (fhandler_console::get_win32_attr): New function.
+ Calculate win32-style console attribute based on terminal attributes.
+ * fhandler_console.cc (fhandler_console::set_cursor_maybe): Use
+ member variable.
+ * fhandler_console.cc (fhandler_console::read): If in raw-win32
+ keyboard mode, encode win32 keyboard events in \033{x;y;z;t;u;wK
+ sequences.
+ * fhandler_console.cc (fhandler_console::dup): Copy all state
+ information to the dup()ed handle.
+ * fhandler_console.cc (fhandler_console::scroll_screen): Use current
+ fill-in attribute.
+ * fhandler_console.cc (fhandler_console::clear_screen): Ditto.
+ * fhandler_console.cc (fhandler_console::char_command): Check if we
+ saw '?' symbol by member variable. Set terminal attributes on \033[Xm
+ commands. \033[24m - turn off underline mode, \033[27m - turn off
+ reverse mode, \033[39m - restore default foreground color.
+ \033[49m - restore default background color. \033[2000h - turn on raw
+ keyboard mode, \033[2000l - turn off raw keyboard mode.
+ * fhandler_console.cc (fhandler_console::write): Set attribues to
+ default values on reset command.
+
+2001-02-26 Mike Simons <msimons@moria.simons-clan.com>
+
+ * times.cc (settimeofday): Replace function stub with working code.
+
+Mon Feb 26 10:42:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * strace.cc (strace::vprntf): Move prntf functionality to this function
+ adding an va_list interface to strace.
+ (strace::printf): Calls strace::vprntf now.
+ (strace_printf): New function providing an extern "C" interface to
+ trace output.
+ * include/sys/strace.h: Make plain C clean.
+ (class strace): Add `vprntf' method.
+
+Mon Feb 26 0:10:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * shortcut.c: Remove #include <sys/strace.h>.
+
+Sun Feb 25 10:32:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (symlink): Add a ".lnk" suffix regardless. Add a comment.
+
+Sun Feb 25 10:18:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * shortcut.c (check_shortcut): Change symlink condition.
+
+Fri Feb 23 10:42:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (fhandler_disk_file::mmap): Use `addr' correctly.
+ * fhandler_mem.cc (fhandler_dev_mem::mmap): Ditto.
+
+Thu Feb 22 17:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (symlink): Keep relative paths relative in the DOS
+ path inside of a shortcut. If that's impossible or the target
+ path is already absolute save an absolute path.
+
+Thu Feb 22 15:33:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygerrno.h: Revert previous patch.
+ * errno.cc: Ditto.
+ * dir.cc: Eliminate `dir_suffixes'.
+ (opendir): Remove usage of `dir_suffixes'.
+ (rmdir): Ditto.
+ * fhandler.cc (fhandler_disk_file::open): Remove usage of
+ `inner_suffixes'.
+ * path.cc: Rename `inner_suffixes' to `lnk_suffixes'.
+ (path_conv::check): Remove usage of `inner_suffixes'.
+ (symlink): Ditto.
+ (symlink_info::check): Handle checking for `.lnk' in path_conv
+ exclusively here.
+ (chdir): Remove usage of `dir_suffixes'.
+ * shortcut.c: Eliminate debug_printf lines.
+ (check_shortcut): Don't set error except on failing ReadFile.
+ * spawn.cc: Remove ".lnk" from `std_suffixes'.
+ * syscalls.cc (_unlink): Remove usage of `inner_suffixes'.
+ Remove ".lnk" from `stat_suffixes'.
+ (_rename): Add check for renaming a symlink to keep the ".lnk"
+ suffix after renaming.
+
+Thu Feb 22 13:38:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * shortcut.c: New file. Provides a C interface to reading of
+ Windows shortcuts to avoid compiler flag `-fvtable-thunks'.
+ * shortcut.h: Ditto.
+ * Makefile.in: Add shortcut.o to DLL_OFILES.
+ * cygerrno.h: Provide a C interface to `geterrno_from_win_error' for
+ using in shortcut.c.
+ * errno.cc (geterrno_from_win_error): Define as extern "C".
+ * path.cc (struct symlink_info): Remove methods `check_shortcut' and
+ `check_sysfile'.
+ (shortcut_header): Move to shortcut.c.
+ (shortcut_initalized): Ditto.
+ (create_shortcut_header): Ditto.
+ (cmp_shortcut_header): Ditto.
+ (symlink_info::check_shortcut): Ditto. Reorganize as a plain C function.
+ (symlink_info::check_sysfile): Redefine as a global function using the
+ same parameter list as `check_shortcut' for clearness.
+ (symlink_info::check): Change parameter list for calls to
+ `check_shortcut' and `check_sysfile'.
+
+Thu Feb 22 12:04:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_disk_file::open): Use `inner_suffixes' when
+ resolving real_path.
+ * path.cc (symlink): Ditto for win32_topath.
+
+Wed Feb 21 22:41:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in: Add `-lshell32 -luuid' to link pass for new-cygwin1.dll.
+ * autoload.cc: Add LoadDLLinitfunc for ole32.dll.
+ Add LoadDLLfuncEx statements for CoInitialize@4, CoUninitialize@0
+ and CoCreateInstance@20.
+ * dir.cc (dir_suffixes): New datastructure.
+ (readdir): Check for R/O *.lnk files to hide the suffix.
+ (opendir): Use `dir_suffixes' in path conversion.
+ (rmdir): Ditto.
+ * fhandler.cc (fhandler_disk_file::fstat): Add S_IFLNK flag
+ before calling `get_file_attribute'. Take FILE_ATTRIBUTE_READONLY
+ into account only if the file is no symlink.
+ * path.cc (inner_suffixes): New datastructure.
+ (SYMLINKATTR): Eliminated.
+ (path_conv::check): Use `inner_suffixes' on inner path components.
+ (shortcut_header): New global static variable.
+ (shortcut_initalized): Ditto.
+ (create_shortcut_header): New function.
+ (cmp_shortcut_header): Ditto.
+ (symlink): Create symlinks by creating windows shortcuts. Preserve
+ the old code.
+ (symlink_info::check_shortcut): New method.
+ (symlink_info::check_sysfile): Ditto.
+ (symlink_info::check): Check for shortcuts. Move code reading
+ old system attribute symlinks into symlink_info::check_sysfile().
+ (chdir): Use `dir_suffixes' in path conversion.
+ * security.cc (get_file_attribute): Check for S_IFLNK flag.
+ Force 0777 permissions then.
+ * spawn.cc (std_suffixes): Add ".lnk" suffix.
+ * syscalls.cc (_unlink): Use `inner_suffixes' in path conversion.
+ Check for shortcut symlinks to eliminate R/O attribute before
+ calling DeleteFile().
+ (stat_suffixes): Add ".lnk" suffix.
+ (stat_worker): Force 0777 permissions if file is a symlink.
+
+2001-02-21 Egor Duda <deo@logos-m.ru>
+
+ * sigproc.cc (getsem): Make semaphore always non-inheritable.
+
+Mon Feb 19 22:25:53 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * dcrt0.cc (locale_init): Remove.
+
+2001-02-15 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * cygwin.din: Export rand48 functions.
+ * thread.cc (MTinterface::Init): Remove the initialization of
+ `reent_data'.
+ * dcrt0.cc: Add the initalizer to the declaration of `reent_data'.
+ * include/cygwin/version.h: Bump CYGWIN_VERSION_API_MINOR to 35.
+
+2001-02-16 Egor Duda <deo@logos-m.ru>
+
+ * signal.cc (signal): Prohibit setting handlers for SIGKILL and
+ SIGSTOP
+ * signal.cc (sigaction): Ditto
+ * syscalls.cc (_lseek): Return EINVAL on invalid input
+
+Wed Feb 14 14:54:40 2001 Christophe Iasci <chrisiasci@aol.com>
+
+ * dlfcn.cc (dlopen): Do not call LoadLibrary with a NULL pointer, when
+ the library is not found
+
+2001-02-14 Egor Duda <deo@logos-m.ru>
+
+ * fhandler_console.cc (fhandler_console::char_command): Ignore unknown
+ rendition codes in \033[xx;yym control sequences
+
+Fri Feb 9 23:19:01 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fork.cc (fork_parent): Return EAGAIN when can't record pid.
+ * pinfo.h (pinfo::remember): Return value of call to proc_subproc.
+ * sigproc.cc (proc_subproc): Return error if can't record pid.
+
+Fri Feb 9 12:17:27 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (mknod): Add valid parameters.
+
+Thu Feb 8 22:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Check for reusing a mapping only on MAP_SHARED
+ and on MAP_PRIVATE|MAP_ANON in the special case of offset 0.
+
+Thu Feb 8 21:57:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (class list): Add member `hash'.
+ (list::list): Initialize `hash'.
+ (list::get_list_by_fd): Use filepath hash value to get the correct
+ mapping list if it's not an anonymous mapping.
+ (map::add_list): Initialize `hash' with filepath hash value.
+ (mmap): Check for reusing a mapping only on MAP_SHARED.
+
+Wed Feb 7 18:47:36 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * signal.cc (killpg): Correct first argument.
+
+Wed Feb 7 22:22:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Add LoadDLLinitfunc for iphlpapi.dll.
+ Add LoadDLLfuncEx statements for GetIfTable@12 and GetIpAddrTable@12.
+ * fhandler_socket.cc (fhandler_socket::ioctl): Move variable
+ definitions to the beginning of the function to allow better debugging.
+ Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU.
+ * net.cc: Include iphlpapi.h.
+ (get_2k_ifconf): Rewritten. Uses IP Helper API now.
+ (get_nt_ifconf): Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC
+ and SIOCGIFMTU.
+ (get_95_ifconf): Ditto. Renamed from `get_9x_ifconf'.
+ (get_ifconf): Name loopback `lo' instead of `lo0' as in Linux.
+ Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU.
+ Call `get_95_ifconf' only on Windows 95, `get_nt_ifconf' only
+ on Windows NT < Service Pack 3, `get_2k_ifconf otherwise.
+ * include/asm/socket.h: Add defines for SIOCGIFHWADDR, SIOCGIFMETRIC
+ and SIOCGIFMTU.
+ * include/cygwin/if.h: Add `ifr_hwaddr', `ifr_metric' and `ifr_mtu'.
+ (struct ifreq): Add `ifru_hwaddr'.
+
+Tue Feb 6 15:04:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (stat_worker): Add a check for the special case when
+ a process creates a file using mode 000 using ntsec.
+
+Mon Feb 5 17:00:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::open): Always add GENERIC_READ access
+ when opening raw disk devices.
+ * fhandler_floppy.cc (fhandler_dev_floppy::lseek): Implement bytewise
+ access.
+ * fhandler_raw.cc (fhandler_dev_raw::open): Always open raw disk device
+ binary.
+ (fhandler_dev_raw::raw_write): Don't drop read buffer content when
+ writing after read.
+
+Mon Feb 5 13:30:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap_record::fixup_map): New method to duplicate
+ the memory protection in a just forked child.
+ (mmap): Realign gran_len to page boundary only on anonymous
+ mapping before saving in the mmap_record.
+ (munmap): Cleanup code.
+ (msync): Ditto.
+ (fixup_mmaps_after_fork): Ditto. Call mmap_record::fixup_map now.
+
+Thu Feb 1 23:08:29 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (creturn): Correctly calculate cygheap_max.
+
+Wed Jan 31 10:04:58 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * shared.cc (shared_info::initialize): Reduce size of heap.
+
+Wed Jan 31 13:22:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/sys/resource.h: Fix typo.
+
+Wed Jan 31 13:20:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/sys/resource.h: Add RLIMIT_NLIMITS and RLIM_NLIMITS.
+
+Tue Jan 30 18:15:23 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump version to 1.3.0.
+
+Tue Jan 30 8:55:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * pinfo.cc (pinfo::init): Use INVALID_HANDLE_VALUE instead of
+ explicit cast (HANDLE) 0xffffffff.
+ * shared.cc (open_shared): Ditto.
+
+Mon Jan 29 17:15:22 2001 Bill Hegardt <bill@troyxcd.com>
+
+ * fhandler_serial.cc (raw_write): Use local copy of OVERLAPPED
+ structure instead of shared structure to fix a race condition between
+ read/write.
+
+Mon Jan 29 14:30:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Remove obsolete check for MAP_SHARED|MAP_ANON as
+ being invalid.
+
+Mon Jan 29 10:23:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap_record::find_empty): Fix loop condition.
+
+Sun Jan 28 19:40:40 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_link): Make sure that newpath does not exist. Set
+ errno if it does.
+
+Sun Jan 28 19:29:08 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (init_cheap): Don't specify a load address for the heap.
+ It doesn't work on #!*& Windows 9x.
+ (cygheap_init): Move GetUserName to memory_init.
+ * dcrt0.cc (dll_crt0_1): Call new memory_init functin, eliminate call
+ to heap_init.
+ * heap.cc (heap_init): Improve error output.
+ * heap.h: Correct some declarations.
+ * shared.cc (mount_table_init): Remove.
+ (memory_init): Renamed from shared_init. Reorganize to accommodate
+ strange Windows 9x problems with cygheap/heap interaction.
+ * shared_info.h: Rename shared_init to memory_init.
+
+Sun Jan 28 01:25:33 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump API version.
+
+Sun Jan 28 01:18:22 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * cygheap.cc (init_cheap): Move username initialization.
+ (cygheap_init): Here.
+ * shared_info.h (mount_info): Add a sys_mount_table_counter field.
+ (shared_info): Ditto.
+ * path.cc (mount_info::conv_to_win32_path): Check that our mount table
+ is in sync with the system mount table and reinitialize it if not.
+ (mount_info::add_reg_mount): Bump sys_mount_table counters if the
+ system mount table changes.
+ (mount_info::del_reg_mount): Ditto.
+ (mount_info::write_cygdrive_info_to_registry): Ditto.
+ (mount_info::remove_cygdrive_info_from_registry): Ditto.
+
+Sun Jan 28 00:28:30 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Throughout, change 'cygwin_shared.mount' to 'mount_table'.
+ * child_info.h (child_info): Move shared_h, console_h to cygheap. Add
+ mount_h.
+ * cygheap.h (init_cygheap): Add shared_h, console_h.
+ * cygheap.cc (init_cheap): Initialize heap at a fixed location after
+ the shared memory regions. Initialize cygheap->user name here.
+ * dcrt0.cc (dll_crt0_1): Call getpagesize () to initialize constants.
+ Remove cygheap_init since it is done in shared_init now.
+ (_dll_crt0): Initialize mount_h, remove shared_h and console_h
+ initialization.
+ * fhandler_console.cc (console_shared_h): Eliminate.
+ (get_tty_stuff): Use cygheap->console_h rather than console_shared_h.
+ * heap.cc (heap_init): Use page size constant calculated earlier in
+ initialization.
+ * shared.cc: Eliminate cygwin_shared_h. Add cygwin_mount_h.
+ (mount_table_init): New function for initializing a user mount table.
+ (open_shared_file_map): Use constant for shared memory region.
+ Initialize cygheap and mount table here.
+ (open_shared): Improve debugging output.
+ (shared_info::initialize): Eliminate call to mount.init.
+ (shared_terminate): Use cygheap->shared_h. Close cygwin_mount_h.
+ (open_shared_file_map): Eliminate.
+ * shared_info.h (mount_info): Add a version field.
+ (shared_align_past): New macro for calculating location for shared
+ memory regions.
+ * sigproc.cc (init_child_info): Eliminate shared_h, console_h.
+ * spawn.cc (spawn_guts): Pass on cygwin_mount_h iff not a different
+ user.
+ * syscalls.cc (system_info): New global holding system memory defaults.
+ (getpagesize): Use system_info.
+ * uinfo.cc (internal_getlogin): Only fill in user name if nonexistent.
+ * winsup.h: Declare system_info.
+
+ * passwd.cc (read_etc_passwd): Use cygheap->user.name () rather than
+ retrieving the name again.
+
+Sat Jan 27 10:18:02 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (path_conv::check): Detect when path has symlinks.
+ (symlink_info::check): Remove debugging stuff.
+ (chdir): Use posix'ized win32 path if cd'ed to a path using symlinks.
+
+Fri Jan 26 21:20:28 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * exceptions.cc (sigreturn): Call any pending signals prior to
+ resetting the signal mask so that stacked signals behave correctly.
+ (sigdelayed): Avoid a race where a signal could end up calling an
+ incorrect signal handler if two signals come in close together.
+
+Tue Jan 23 21:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (fhandler_disk_file::mmap): Call CreateFileMapping with
+ len != 0 only when performing an anonymous mapping.
+
+Mon Jan 22 15:35:28 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * path.h: Add a new constant.
+ * syscalls.cc (_read): Oscillate errno check.
+
+Mon Jan 22 15:27:12 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * include/cygwin/version.h: Bump API to reflect setlogmask.
+
+Sun Jan 21 22:40:25 2001 Jason Tishler <jt@dothill.com>
+
+ * cygwin.din: Add export for setlogmask().
+ * syslog.cc (setlogmask): New function.
+
+Thu Jan 18 10:27:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * resource.cc (setrlimit): Support RLIMIT_NOFILE.
+
+Wed Jan 17 23:23:12 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (setdtablesize): Call with amount to increment not total
+ amount. Return success or failure error code.
+
+Wed Jan 17 09:47:13 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * autoload.cc (LoadDLLinitfunc): Remove debugging statement.
+
+ * exceptions.cc (sig_handle_tty_stop): Move setting of PID_STOPPED to
+ earlier in interrupt.
+ (interrupt_setup): i.e., here.
+ (sig_handle): Don't queue multiple SIGSTOPS.
+ * fhandler.h (bg_check_types): Enumerate return value of bg_check for
+ clarity.
+ * signal.cc (kill_pgrp): Minor cleanup.
+ * fhandler_termios.cc (fhandler_termios::bg_check): Use enumerated type
+ for function return. Don't raise signal if a signal is already queued.
+ * fhandler_console.cc (fhandler_console::read): Use enumerated return
+ type for bg_check.
+ * select.cc: Ditto, throughout.
+ * read.cc: Ditto, throughout.
+ * termios.cc: Ditto, throughout.
+ (_read): YA interrupt detect simplification.
+ * wait.cc (wait4): Ditto.
+
+Wed Jan 17 10:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.cc (cygheap_user::~cygheap_user): Temporarily
+ disable free'ing memory.
+
+Tue Jan 16 18:01:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Initialize fh to avoid compiler warnings.
+
+Mon Jan 15 21:07:00 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * wait.cc (wait4): Rename variable for consistency. Allow restartable
+ signal behavior.
+
+Mon Jan 15 23:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap): Add more parameter checking. Change error output
+ in case of EINVAL. Treat mmapping /dev/zero like MAP_ANONYMOUS.
+
+Mon Jan 15 20:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc: include <unistd.h>. Define some bit operations for
+ the new page map.
+ (mmap_record): Change type of base_address_ to caddr_t.
+ Add map_map_ member. Add several methods to manipulate map_map_.
+ (mmap_record::alloc_map): New method.
+ (mmap_record::free_map): Ditto.
+ (mmap_record::find_empty): Ditto.
+ (mmap_record::map_map): Ditto.
+ (mmap_record::unmap_map): Ditto.
+ (list::add_record): Change return type to `mmap_record *'.
+ Allocate page map.
+ (list::match): New method.
+ (mmap): Partly rewritten to take care for the new page map. Add some
+ parameter checking.
+ (munmap): Ditto.
+
+Mon Jan 15 13:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * heap.cc (heap_init): Fix extern declaration of getpagesize.
+ * syscalls.cc (getpagesize): Fix another typo.
+
+Mon Jan 15 12:48:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (getpagesize): Save pagesize in global variable to
+ avoid calling GetSystemInfo too often.
+ * heap.cc (getpagesize): Eliminate.
+ (heap_init): Use getpagesize function from syscalls.cc.
+
+Mon Jan 15 11:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * sysconf.cc (sysconf): return `getpagesize ()' on _SC_PAGESIZE
+ request to avoid implementing the same twice.
+
+Sun Jan 14 14:07:50 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_read): Use more lightweight method for determining if
+ read has been interrupted by a signal.
+
+Fri Jan 12 00:35:15 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * debug.h: Add regparm attributes to some functions.
+
+ * signal.cc (sigaction): Don't treat SIGCONT specially.
+
+ * exceptions.cc (interrupt_setup): Save sa_flags of interrupted signal
+ for later use.
+ (sig_handler): Default any stopping signal to SIGSTOP.
+ (call_signal_handler): New function.
+ (sigdelayed0): New function.
+ * sigproc.cc (sigproc_init): Initialize SIGSTOP sigaction for special
+ behavior.
+ * sigproc.h: Define call_signal_handler.
+ * syscalls.cc (_read): Allow restartable signal behavior.
+
+Thu Jan 11 13:17:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_base): New method `fixup_mmap_after_fork'.
+ (fhandler_disk_file: Ditto.
+ (fhandler_dev_mem): Ditto.
+ * fhandler_mem.cc (fhandler_dev_mem::open): Set OBJ_INHERIT attribute
+ for device\physicalmemory handle.
+ (fhandler_dev_mem::mmap): Ditto.
+ * fhandler_mem.cc (fhandler_dev_mem::fixup_mmap_after_fork): New
+ method.
+ * mmap.cc (mmap_record): Add private `fdesc_' member. Change
+ constructor accordingly.
+ (get_fd): New method.
+ (mmap): Use new mmap_record constructor.
+ (fhandler_base::fixup_mmap_after_fork): New method.
+ (fhandler_disk_file::fixup_mmap_after_fork): Ditto.
+ (fixup_mmaps_after_fork): Call `fixup_mmap_after_fork' of appropriate
+ fhandler class.
+
+Wed Jan 10 22:08:30 2001 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
+
+ * sigproc.cc (wait_sig): Allow SIGCONT when stopped.
+
+Tue Jan 9 16:55:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ Patch suggested by René Møller Fonseca <fonseca@mip.sdu.dk>
+ * include/sys/socket.h: Change prototype to have 2nd parameter `const'.
+ * net.cc (cygwin_bind): Change 2nd parameter to `const'.
+
+Sun Jan 7 22:59:37 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * pinfo.cc (codepage_init): Move function.
+ * environ.cc (codepage_init): To here.
+ * exceptoins.cc (SIG_NONMASKABLE): Remove SIGCONT from consideration
+ since it is supposed to be maskable.
+ * signal.cc (sigaction): Ditto.
+ * sigproc.cc (wait_sig): Ditto.
+ * winsup.h: Eliminate global declaration of codepage_init.
+
+Thu Jan 5 9:33:00 2001 Corinna Vinschen <corinna@vinschen.de>
+
+ * resource.cc (getrlimit): Set errno on EFAULT instead of returning
+ it.
+ (setrlimit): Ditto.
+
+Thu Jan 5 3:38:00 2001 David Sainty <David.Sainty@optimation.co.nz>
+
+ * resource.cc (setrlimit): Prevent failing with an error when the
+ operation would not have changed anything.
+
+Thu Jan 4 10:29:54 2001 Earnie Boyd <earnie_boyd@yahoo.com>
+
+ * thread.cc: Need LONG_MAX definition.
+
+Wed Jan 3 13:47:23 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * thread.cc (MTinterface::CreateSemaphore): Correctly set semaphore
+ max.
+
+Wed Jan 3 09:44:51 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * fhandler_console.cc (fhandler_console::read): Restore missing test
+ for code page before doing OemToCharBuff.
+
+Wed Jan 3 09:20:20 2001 Jason Tishler <jt@dothill.com>
+
+ * include/cygwin/version.h: Fix typo in CYGWIN_VERSION_DLL_COMBINED
+ macro.
diff --git a/winsup/cygwin/cygmagic b/winsup/cygwin/cygmagic
new file mode 100755
index 000000000..5589b26f6
--- /dev/null
+++ b/winsup/cygwin/cygmagic
@@ -0,0 +1,20 @@
+#!/bin/sh
+file_magic=$1; shift
+gcc=$1; shift
+file=$1; shift
+trap "rm -f /tmp/$$.magic" 0 1 2 15
+cat <<EOF > $file_magic
+/* autogenerated - do not edit */
+#include "$file"
+EOF
+while [ -n "$1" ]; do
+ define=$1; shift
+ struct=$1; shift
+ sum=`$gcc -E $file | sed -n "/^$struct/,/^};/p" | sed -e 's/[ ]//g' -e '/^$/d' | sum | awk '{printf "0x%x", $1}'`
+ echo "#define $define $sum"
+ curr=`sed -n "s/^#[ ]*define CURR_$define[ ][ ]*\([^ ][^ ]*\)/\1/p" $file`
+ [ "$curr" == "$sum" ] || echo "*** WARNING WARNING WARNING WARNING WARNING ***
+*** $file: magic number for $define changed old $curr != new $sum
+*** WARNING WARNING WARNING WARNING WARNING ***" 1>&2
+done >> $file_magic
+exit 0
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
new file mode 100644
index 000000000..1ce4893d2
--- /dev/null
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -0,0 +1,857 @@
+/* fhandler_disk_file.cc
+
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/cygwin.h>
+#include <signal.h>
+#include "cygerrno.h"
+#include "perprocess.h"
+#include "security.h"
+#include "cygwin/version.h"
+#include "fhandler.h"
+#include "path.h"
+#include "dtable.h"
+#include "cygheap.h"
+#include "shared_info.h"
+#include "sigproc.h"
+#include "pinfo.h"
+#include <assert.h>
+
+#define _COMPILING_NEWLIB
+#include <dirent.h>
+
+static int
+num_entries (const char *win32_name)
+{
+ WIN32_FIND_DATA buf;
+ HANDLE handle;
+ char buf1[MAX_PATH];
+ int count = 0;
+
+ strcpy (buf1, win32_name);
+ int len = strlen (buf1);
+ if (len == 0 || isdirsep (buf1[len - 1]))
+ strcat (buf1, "*");
+ else
+ strcat (buf1, "/*"); /* */
+
+ handle = FindFirstFileA (buf1, &buf);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ return 0;
+ count ++;
+ while (FindNextFileA (handle, &buf))
+ {
+ if ((buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ count ++;
+ }
+ FindClose (handle);
+ return count;
+}
+
+int
+fhandler_disk_file::fstat (struct stat *buf, path_conv *pc)
+{
+ int res = -1;
+ int oret;
+ uid_t uid;
+ gid_t gid;
+ int open_flags = O_RDONLY | O_BINARY | O_DIROPEN;
+
+ if (!pc)
+ return fstat_helper (buf);
+
+ if ((oret = open (pc, open_flags, 0)))
+ /* ok */;
+ else
+ {
+ int ntsec_atts = 0;
+ /* If we couldn't open the file, try a "query open" with no permissions.
+ This will allow us to determine *some* things about the file, at least. */
+ set_query_open (TRUE);
+ if ((oret = open (pc, open_flags, 0)))
+ /* ok */;
+ else if (allow_ntsec && pc->has_acls () && get_errno () == EACCES
+ && !get_file_attribute (TRUE, get_win32_name (), &ntsec_atts, &uid, &gid)
+ && !ntsec_atts && uid == myself->uid && gid == myself->gid)
+ {
+ /* Check a special case here. If ntsec is ON it happens
+ that a process creates a file using mode 000 to disallow
+ other processes access. In contrast to UNIX, this results
+ in a failing open call in the same process. Check that
+ case. */
+ set_file_attribute (TRUE, get_win32_name (), 0400);
+ oret = open (pc, open_flags, 0);
+ set_file_attribute (TRUE, get_win32_name (), ntsec_atts);
+ }
+ }
+ if (oret)
+ {
+ res = fstat_helper (buf);
+ /* The number of links to a directory includes the
+ number of subdirectories in the directory, since all
+ those subdirectories point to it.
+ This is too slow on remote drives, so we do without it and
+ set the number of links to 2. */
+ /* Unfortunately the count of 2 confuses `find (1)' command. So
+ let's try it with `1' as link count. */
+ if (pc->isdir ())
+ buf->st_nlink = (pc->isremote ()
+ ? 1 : num_entries (pc->get_win32 ()));
+ close ();
+ }
+ else if (pc->exists ())
+ {
+ /* Unfortunately, the above open may fail if the file exists, though.
+ So we have to care for this case here, too. */
+ WIN32_FIND_DATA wfd;
+ HANDLE handle;
+ buf->st_nlink = 1;
+ if (pc->isdir () && pc->isremote ())
+ buf->st_nlink = num_entries (pc->get_win32 ());
+ buf->st_dev = FHDEVN (FH_DISK) << 8;
+ buf->st_ino = hash_path_name (0, pc->get_win32 ());
+ if (pc->isdir ())
+ buf->st_mode = S_IFDIR;
+ else if (pc->issymlink ())
+ buf->st_mode = S_IFLNK;
+ else if (pc->issocket ())
+ buf->st_mode = S_IFSOCK;
+ else
+ buf->st_mode = S_IFREG;
+ if (!pc->has_acls ()
+ || get_file_attribute (TRUE, pc->get_win32 (),
+ &buf->st_mode,
+ &buf->st_uid, &buf->st_gid))
+ {
+ buf->st_mode |= STD_RBITS | STD_XBITS;
+ if (!(pc->has_attribute (FILE_ATTRIBUTE_READONLY)))
+ buf->st_mode |= STD_WBITS;
+ if (pc->issymlink ())
+ buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
+ get_file_attribute (FALSE, pc->get_win32 (),
+ NULL, &buf->st_uid, &buf->st_gid);
+ }
+ if ((handle = FindFirstFile (pc->get_win32 (), &wfd))
+ != INVALID_HANDLE_VALUE)
+ {
+ /* This is for FAT filesystems, which don't support atime/ctime */
+ if (wfd.ftLastAccessTime.dwLowDateTime == 0
+ && wfd.ftLastAccessTime.dwHighDateTime == 0)
+ wfd.ftLastAccessTime = wfd.ftLastWriteTime;
+ if (wfd.ftCreationTime.dwLowDateTime == 0
+ && wfd.ftCreationTime.dwHighDateTime == 0)
+ wfd.ftCreationTime = wfd.ftLastWriteTime;
+
+ buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
+ buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
+ buf->st_ctime = to_time_t (&wfd.ftCreationTime);
+ buf->st_size = wfd.nFileSizeLow;
+ buf->st_blksize = S_BLKSIZE;
+ buf->st_blocks = ((unsigned long) buf->st_size +
+ S_BLKSIZE-1) / S_BLKSIZE;
+ FindClose (handle);
+ }
+ res = 0;
+ }
+
+ return res;
+}
+
+int
+fhandler_disk_file::fstat_helper (struct stat *buf)
+{
+ int res = 0; // avoid a compiler warning
+ BY_HANDLE_FILE_INFORMATION local;
+ save_errno saved_errno;
+
+ /* NT 3.51 seems to have a bug when attempting to get vol serial
+ numbers. This loop gets around this. */
+ for (int i = 0; i < 2; i++)
+ {
+ if (!(res = GetFileInformationByHandle (get_handle (), &local)))
+ break;
+ if (local.dwVolumeSerialNumber && (long) local.dwVolumeSerialNumber != -1)
+ break;
+ }
+ debug_printf ("%d = GetFileInformationByHandle (%s, %d)",
+ res, get_win32_name (), get_handle ());
+ if (res == 0)
+ {
+ /* GetFileInformationByHandle will fail if it's given stdin/out/err
+ or a pipe*/
+ DWORD lsize, hsize;
+
+ if (GetFileType (get_handle ()) != FILE_TYPE_DISK)
+ buf->st_mode = S_IFCHR;
+
+ lsize = GetFileSize (get_handle (), &hsize);
+ if (lsize == 0xffffffff && GetLastError () != NO_ERROR)
+ buf->st_mode = S_IFCHR;
+ else
+ buf->st_size = lsize;
+ /* We expect these to fail! */
+ buf->st_mode |= STD_RBITS | STD_WBITS;
+ buf->st_blksize = S_BLKSIZE;
+ buf->st_ino = get_namehash ();
+ syscall_printf ("0 = fstat (, %p)", buf);
+ return 0;
+ }
+
+ if (!get_win32_name ())
+ {
+ saved_errno.set (ENOENT);
+ return -1;
+ }
+
+ /* This is for FAT filesystems, which don't support atime/ctime */
+ if (local.ftLastAccessTime.dwLowDateTime == 0
+ && local.ftLastAccessTime.dwHighDateTime == 0)
+ local.ftLastAccessTime = local.ftLastWriteTime;
+ if (local.ftCreationTime.dwLowDateTime == 0
+ && local.ftCreationTime.dwHighDateTime == 0)
+ local.ftCreationTime = local.ftLastWriteTime;
+
+ buf->st_atime = to_time_t (&local.ftLastAccessTime);
+ buf->st_mtime = to_time_t (&local.ftLastWriteTime);
+ buf->st_ctime = to_time_t (&local.ftCreationTime);
+ buf->st_nlink = local.nNumberOfLinks;
+ buf->st_dev = local.dwVolumeSerialNumber;
+ buf->st_size = local.nFileSizeLow;
+
+ /* Allocate some place to determine the root directory. Need to allocate
+ enough so that rootdir can add a trailing slash if path starts with \\. */
+ char root[strlen (get_win32_name ()) + 3];
+ strcpy (root, get_win32_name ());
+
+ /* Assume that if a drive has ACL support it MAY have valid "inodes".
+ It definitely does not have valid inodes if it does not have ACL
+ support. */
+ switch (has_acls () ? GetDriveType (rootdir (root)) : DRIVE_UNKNOWN)
+ {
+ case DRIVE_FIXED:
+ case DRIVE_REMOVABLE:
+ case DRIVE_CDROM:
+ case DRIVE_RAMDISK:
+ /* Although the documentation indicates otherwise, it seems like
+ "inodes" on these devices are persistent, at least across reboots. */
+ buf->st_ino = local.nFileIndexHigh | local.nFileIndexLow;
+ break;
+ default:
+ /* Either the nFileIndex* fields are unreliable or unavailable. Use the
+ next best alternative. */
+ buf->st_ino = get_namehash ();
+ break;
+ }
+
+ buf->st_blksize = S_BLKSIZE;
+ buf->st_blocks = ((unsigned long) buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
+
+ buf->st_mode = 0;
+ /* Using a side effect: get_file_attibutes checks for
+ directory. This is used, to set S_ISVTX, if needed. */
+ if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ buf->st_mode = S_IFDIR;
+ else if (get_symlink_p ())
+ buf->st_mode = S_IFLNK;
+ else if (get_socket_p ())
+ buf->st_mode = S_IFSOCK;
+ if (get_file_attribute (has_acls (), get_win32_name (), &buf->st_mode,
+ &buf->st_uid, &buf->st_gid) == 0)
+ {
+ /* If read-only attribute is set, modify ntsec return value */
+ if ((local.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ && !get_symlink_p ())
+ buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+
+ if (!(buf->st_mode & S_IFMT))
+ buf->st_mode |= S_IFREG;
+ }
+ else
+ {
+ buf->st_mode |= STD_RBITS;
+
+ if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+ buf->st_mode |= STD_WBITS;
+ /* | S_IWGRP | S_IWOTH; we don't give write to group etc */
+
+ if (buf->st_mode & S_IFDIR)
+ buf->st_mode |= S_IFDIR | STD_XBITS;
+ else if (buf->st_mode & S_IFMT)
+ /* nothing */;
+ else if (get_socket_p ())
+ buf->st_mode |= S_IFSOCK;
+ else
+ switch (GetFileType (get_handle ()))
+ {
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_UNKNOWN:
+ buf->st_mode |= S_IFCHR;
+ break;
+ case FILE_TYPE_DISK:
+ buf->st_mode |= S_IFREG;
+ if (!dont_care_if_execable () && !get_execable_p ())
+ {
+ DWORD cur, done;
+ char magic[3];
+
+ /* First retrieve current position, set to beginning
+ of file if not already there. */
+ cur = SetFilePointer (get_handle(), 0, NULL, FILE_CURRENT);
+ if (cur != INVALID_SET_FILE_POINTER &&
+ (!cur ||
+ SetFilePointer (get_handle(), 0, NULL, FILE_BEGIN)
+ != INVALID_SET_FILE_POINTER))
+ {
+ /* FIXME should we use /etc/magic ? */
+ magic[0] = magic[1] = magic[2] = '\0';
+ if (ReadFile (get_handle (), magic, 3, &done, NULL) &&
+ has_exec_chars (magic, done))
+ set_execable_p ();
+ SetFilePointer (get_handle(), cur, NULL, FILE_BEGIN);
+ }
+ }
+ if (get_execable_p ())
+ buf->st_mode |= STD_XBITS;
+ break;
+ case FILE_TYPE_PIPE:
+ buf->st_mode |= S_IFSOCK;
+ break;
+ }
+ }
+
+ syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%d, st_mode=%p, st_ino=%d, sizeof=%d",
+ buf, buf->st_atime, buf->st_size, buf->st_mode,
+ (int) buf->st_ino, sizeof (*buf));
+
+ return 0;
+}
+
+fhandler_disk_file::fhandler_disk_file (DWORD devtype) :
+ fhandler_base (devtype)
+{
+}
+
+fhandler_disk_file::fhandler_disk_file () :
+ fhandler_base (FH_DISK)
+{
+}
+
+int
+fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
+{
+ if (real_path->case_clash && flags & O_CREAT)
+ {
+ debug_printf ("case clash detected");
+ set_errno (ECASECLASH);
+ return 0;
+ }
+
+ if (real_path->isbinary ())
+ {
+ set_r_binary (1);
+ set_w_binary (1);
+ }
+
+ set_has_acls (real_path->has_acls ());
+ set_isremote (real_path->isremote ());
+
+ if (real_path->isdir ())
+ flags |= O_DIROPEN;
+
+ int res = this->fhandler_base::open (real_path, flags, mode);
+
+ if (!res)
+ goto out;
+
+ /* This is for file systems known for having a buggy CreateFile call
+ which might return a valid HANDLE without having actually opened
+ the file.
+ The only known file system to date is the SUN NFS Solstice Client 3.1
+ which returns a valid handle when trying to open a file in a nonexistent
+ directory. */
+ if (real_path->has_buggy_open ()
+ && GetFileAttributes (win32_path_name) == (DWORD) -1)
+ {
+ debug_printf ("Buggy open detected.");
+ close ();
+ set_errno (ENOENT);
+ return 0;
+ }
+
+ if (flags & O_APPEND)
+ SetFilePointer (get_handle(), 0, 0, FILE_END);
+
+ set_symlink_p (real_path->issymlink ());
+ set_execable_p (real_path->exec_state ());
+ set_socket_p (real_path->issocket ());
+
+out:
+ syscall_printf ("%d = fhandler_disk_file::open (%s, %p)", res,
+ get_win32_name (), flags);
+ return res;
+}
+
+int
+fhandler_disk_file::close ()
+{
+ int res = this->fhandler_base::close ();
+ if (!res)
+ cygwin_shared->delqueue.process_queue ();
+ return res;
+}
+
+/*
+ * FIXME !!!
+ * The correct way to do this to get POSIX locking
+ * semantics is to keep a linked list of posix lock
+ * requests and map them into Win32 locks. The problem
+ * is that Win32 does not deal correctly with overlapping
+ * lock requests. Also another pain is that Win95 doesn't do
+ * non-blocking or non exclusive locks at all. For '95 just
+ * convert all lock requests into blocking,exclusive locks.
+ * This shouldn't break many apps but denying all locking
+ * would.
+ * For now just convert to Win32 locks and hope for the best.
+ */
+
+int
+fhandler_disk_file::lock (int cmd, struct flock *fl)
+{
+ int win32_start;
+ int win32_len;
+ DWORD win32_upper;
+ DWORD startpos;
+
+ /*
+ * We don't do getlck calls yet.
+ */
+
+ if (cmd == F_GETLK)
+ {
+ set_errno (ENOSYS);
+ return -1;
+ }
+
+ /*
+ * Calculate where in the file to start from,
+ * then adjust this by fl->l_start.
+ */
+
+ switch (fl->l_whence)
+ {
+ case SEEK_SET:
+ startpos = 0;
+ break;
+ case SEEK_CUR:
+ if ((off_t) (startpos = lseek (0, SEEK_CUR)) == (off_t)-1)
+ return -1;
+ break;
+ case SEEK_END:
+ {
+ BY_HANDLE_FILE_INFORMATION finfo;
+ if (GetFileInformationByHandle (get_handle(), &finfo) == 0)
+ {
+ __seterrno ();
+ return -1;
+ }
+ startpos = finfo.nFileSizeLow; /* Nowhere to keep high word */
+ break;
+ }
+ default:
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ /*
+ * Now the fun starts. Adjust the start and length
+ * fields until they make sense.
+ */
+
+ win32_start = startpos + fl->l_start;
+ if (fl->l_len < 0)
+ {
+ win32_start -= fl->l_len;
+ win32_len = -fl->l_len;
+ }
+ else
+ win32_len = fl->l_len;
+
+ if (win32_start < 0)
+ {
+ /* watch the signs! */
+ win32_len -= -win32_start;
+ if (win32_len <= 0)
+ {
+ /* Failure ! */
+ set_errno (EINVAL);
+ return -1;
+ }
+ win32_start = 0;
+ }
+
+ /*
+ * Special case if len == 0 for POSIX means lock
+ * to the end of the entire file (and all future extensions).
+ */
+ if (win32_len == 0)
+ {
+ win32_len = 0xffffffff;
+ win32_upper = wincap.lock_file_highword ();
+ }
+ else
+ win32_upper = 0;
+
+ BOOL res;
+
+ if (wincap.has_lock_file_ex ())
+ {
+ DWORD lock_flags = (cmd == F_SETLK) ? LOCKFILE_FAIL_IMMEDIATELY : 0;
+ lock_flags |= (fl->l_type == F_WRLCK) ? LOCKFILE_EXCLUSIVE_LOCK : 0;
+
+ OVERLAPPED ov;
+
+ ov.Internal = 0;
+ ov.InternalHigh = 0;
+ ov.Offset = (DWORD)win32_start;
+ ov.OffsetHigh = 0;
+ ov.hEvent = (HANDLE) 0;
+
+ if (fl->l_type == F_UNLCK)
+ {
+ res = UnlockFileEx (get_handle (), 0, (DWORD)win32_len, win32_upper, &ov);
+ }
+ else
+ {
+ res = LockFileEx (get_handle (), lock_flags, 0, (DWORD)win32_len,
+ win32_upper, &ov);
+ /* Deal with the fail immediately case. */
+ /*
+ * FIXME !! I think this is the right error to check for
+ * but I must admit I haven't checked....
+ */
+ if ((res == 0) && (lock_flags & LOCKFILE_FAIL_IMMEDIATELY) &&
+ (GetLastError () == ERROR_LOCK_FAILED))
+ {
+ set_errno (EAGAIN);
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ /* Windows 95 -- use primitive lock call */
+ if (fl->l_type == F_UNLCK)
+ res = UnlockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len,
+ win32_upper);
+ else
+ res = LockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len, win32_upper);
+ }
+
+ if (res == 0)
+ {
+ __seterrno ();
+ return -1;
+ }
+
+ return 0;
+}
+
+DIR *
+fhandler_disk_file::opendir (path_conv& real_name)
+{
+ DIR *dir;
+ DIR *res = NULL;
+ size_t len;
+
+ if (!real_name.isdir ())
+ set_errno (ENOTDIR);
+ else if ((len = strlen (real_name))> MAX_PATH - 3)
+ set_errno (ENAMETOOLONG);
+ else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
+ set_errno (ENOMEM);
+ else if ((dir->__d_dirname = (char *) malloc (len + 3)) == NULL)
+ {
+ free (dir);
+ set_errno (ENOMEM);
+ }
+ else if ((dir->__d_dirent =
+ (struct dirent *) malloc (sizeof (struct dirent))) == NULL)
+ {
+ free (dir->__d_dirname);
+ free (dir);
+ set_errno (ENOMEM);
+ }
+ else
+ {
+ strcpy (dir->__d_dirname, real_name.get_win32 ());
+ dir->__d_dirent->d_version = __DIRENT_VERSION;
+ cygheap_fdnew fd;
+ fd = this;
+ fd->set_nohandle (true);
+ dir->__d_dirent->d_fd = fd;
+ dir->__d_u.__d_data.__fh = this;
+ /* FindFirstFile doesn't seem to like duplicate /'s. */
+ len = strlen (dir->__d_dirname);
+ if (len == 0 || SLASH_P (dir->__d_dirname[len - 1]))
+ strcat (dir->__d_dirname, "*");
+ else
+ strcat (dir->__d_dirname, "\\*"); /**/
+ dir->__d_cookie = __DIRENT_COOKIE;
+ dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
+ dir->__d_position = 0;
+ dir->__d_dirhash = get_namehash ();
+
+ res = dir;
+ }
+
+ syscall_printf ("%p = opendir (%s)", res, get_name ());
+ return res;
+}
+
+struct dirent *
+fhandler_disk_file::readdir (DIR *dir)
+{
+ WIN32_FIND_DATA buf;
+ HANDLE handle;
+ struct dirent *res = NULL;
+
+ if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE
+ && dir->__d_position == 0)
+ {
+ handle = FindFirstFileA (dir->__d_dirname, &buf);
+ DWORD lasterr = GetLastError ();
+ dir->__d_u.__d_data.__handle = handle;
+ if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))
+ {
+ seterrno_from_win_error (__FILE__, __LINE__, lasterr);
+ return res;
+ }
+ }
+ else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
+ {
+ return res;
+ }
+ else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf))
+ {
+ DWORD lasterr = GetLastError ();
+ (void) FindClose (dir->__d_u.__d_data.__handle);
+ dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
+ /* POSIX says you shouldn't set errno when readdir can't
+ find any more files; so, if another error we leave it set. */
+ if (lasterr != ERROR_NO_MORE_FILES)
+ seterrno_from_win_error (__FILE__, __LINE__, lasterr);
+ syscall_printf ("%p = readdir (%p)", res, dir);
+ return res;
+ }
+
+ /* We get here if `buf' contains valid data. */
+ strcpy (dir->__d_dirent->d_name, buf.cFileName);
+
+ /* Check for Windows shortcut. If it's a Cygwin or U/WIN
+ symlink, drop the .lnk suffix. */
+ if (buf.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ {
+ char *c = dir->__d_dirent->d_name;
+ int len = strlen (c);
+ if (strcasematch (c + len - 4, ".lnk"))
+ {
+ char fbuf[MAX_PATH + 1];
+ strcpy (fbuf, dir->__d_dirname);
+ strcpy (fbuf + strlen (fbuf) - 1, dir->__d_dirent->d_name);
+ path_conv fpath (fbuf, PC_SYM_NOFOLLOW);
+ if (fpath.issymlink ())
+ c[len - 4] = '\0';
+ }
+ }
+
+ /* Compute d_ino by combining filename hash with the directory hash
+ (which was stored in dir->__d_dirhash when opendir was called). */
+ if (buf.cFileName[0] == '.')
+ {
+ if (buf.cFileName[1] == '\0')
+ dir->__d_dirent->d_ino = dir->__d_dirhash;
+ else if (buf.cFileName[1] != '.' || buf.cFileName[2] != '\0')
+ goto hashit;
+ else
+ {
+ char *p, up[strlen (dir->__d_dirname) + 1];
+ strcpy (up, dir->__d_dirname);
+ if (!(p = strrchr (up, '\\')))
+ goto hashit;
+ *p = '\0';
+ if (!(p = strrchr (up, '\\')))
+ dir->__d_dirent->d_ino = hash_path_name (0, ".");
+ else
+ {
+ *p = '\0';
+ dir->__d_dirent->d_ino = hash_path_name (0, up);
+ }
+ }
+ }
+ else
+ {
+ hashit:
+ ino_t dino = hash_path_name (dir->__d_dirhash, "\\");
+ dir->__d_dirent->d_ino = hash_path_name (dino, buf.cFileName);
+ }
+
+ dir->__d_position++;
+ res = dir->__d_dirent;
+ syscall_printf ("%p = readdir (%p) (%s)",
+ &dir->__d_dirent, dir, buf.cFileName);
+ return res;
+}
+
+off_t
+fhandler_disk_file::telldir (DIR *dir)
+{
+ return dir->__d_position;
+}
+
+void
+fhandler_disk_file::seekdir (DIR *dir, off_t loc)
+{
+ rewinddir (dir);
+ while (loc > dir->__d_position)
+ if (!readdir (dir))
+ break;
+}
+
+void
+fhandler_disk_file::rewinddir (DIR *dir)
+{
+ if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE)
+ {
+ (void) FindClose (dir->__d_u.__d_data.__handle);
+ dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
+ }
+ dir->__d_position = 0;
+}
+
+int
+fhandler_disk_file::closedir (DIR *dir)
+{
+ int res = 0;
+ if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE &&
+ FindClose (dir->__d_u.__d_data.__handle) == 0)
+ {
+ __seterrno ();
+ res = -1;
+ }
+ syscall_printf ("%d = closedir (%p)", res, dir);
+ return 0;
+}
+
+fhandler_cygdrive::fhandler_cygdrive (int unit) :
+ fhandler_disk_file (FH_CYGDRIVE), unit (unit), ndrives (0), pdrive (NULL)
+{
+}
+
+#define DRVSZ sizeof ("x:\\")
+void
+fhandler_cygdrive::set_drives ()
+{
+ const int len = 1 + 26 * DRVSZ;
+ win32_path_name = (char *) crealloc (win32_path_name, len);
+
+ ndrives = GetLogicalDriveStrings (len, win32_path_name) / DRVSZ;
+ pdrive = win32_path_name;
+}
+
+int
+fhandler_cygdrive::fstat (struct stat *buf, path_conv *pc)
+{
+ if (!iscygdrive_root ())
+ return fhandler_disk_file::fstat (buf, pc);
+ buf->st_mode = S_IFDIR | 0555;
+ if (!ndrives)
+ set_drives ();
+ buf->st_nlink = ndrives;
+ return 0;
+}
+
+DIR *
+fhandler_cygdrive::opendir (path_conv& real_name)
+{
+ DIR *dir;
+
+ dir = fhandler_disk_file::opendir (real_name);
+ if (dir && iscygdrive_root () && !ndrives)
+ set_drives ();
+
+ return dir;
+}
+
+struct dirent *
+fhandler_cygdrive::readdir (DIR *dir)
+{
+ if (!iscygdrive_root ())
+ return fhandler_disk_file::readdir (dir);
+ if (!pdrive || !*pdrive)
+ {
+ set_errno (ENMFILE);
+ return NULL;
+ }
+ if (GetFileAttributes (pdrive) == (DWORD) -1)
+ {
+ pdrive += DRVSZ;
+ return readdir (dir);
+ }
+ *dir->__d_dirent->d_name = cyg_tolower (*pdrive);
+ dir->__d_dirent->d_name[1] = '\0';
+ dir->__d_position++;
+ pdrive += DRVSZ;
+ syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
+ dir->__d_dirent->d_name);
+ return dir->__d_dirent;
+}
+
+off_t
+fhandler_cygdrive::telldir (DIR *dir)
+{
+ return fhandler_disk_file::telldir (dir);
+}
+
+void
+fhandler_cygdrive::seekdir (DIR *dir, off_t loc)
+{
+ if (!iscygdrive_root ())
+ return fhandler_disk_file::seekdir (dir, loc);
+
+ for (pdrive = win32_path_name, dir->__d_position = -1; *pdrive; pdrive += DRVSZ)
+ if (++dir->__d_position >= loc)
+ break;
+
+ return;
+}
+
+void
+fhandler_cygdrive::rewinddir (DIR *dir)
+{
+ if (!iscygdrive_root ())
+ return fhandler_disk_file::rewinddir (dir);
+ pdrive = win32_path_name;
+ dir->__d_position = 0;
+ return;
+}
+
+int
+fhandler_cygdrive::closedir (DIR *dir)
+{
+ if (!iscygdrive_root ())
+ return fhandler_disk_file::closedir (dir);
+ pdrive = win32_path_name;
+ return -1;
+}
diff --git a/winsup/cygwin/how-fhandlers-work.txt b/winsup/cygwin/how-fhandlers-work.txt
new file mode 100644
index 000000000..5e810a780
--- /dev/null
+++ b/winsup/cygwin/how-fhandlers-work.txt
@@ -0,0 +1,65 @@
+Copyright 2001 Red Hat Inc., Robert Collins
+
+fhandlers are the core mechanism by which cygwin provides a file descripter (fd)
+interface to things such as a random number generated, winsock sockets, raw disk
+devices, the clipboard, the console and so on. Under unix access to all such
+devices is via a combination of IOCTL's and open/close/read/write calls. Some
+special functions do exist - such as bind () and listen () for sockets, but
+these consistently operate on fd's. Under Win32 there are disparate interfaces
+that have little in common with each other. See for example Direct Sound and
+the Clipboard.
+
+The fhandler class provides all open,read,write,close, ioctl and fork()/exec()
+functionality for the fd interface. The base class operates on win32 backed
+files. The various derived classes utilise win32 primitives to provide their
+specific functionality.
+
+When a file is opened - not necesarily via open() a fd is assigned to it. The fd
+includes a pointer to the actual fhandler that operates this specific file. All
+file-oriented system calls then operate off this basic structure.
+
+For example, lets examine lseek ().
+
+extern "C" off_t
+_lseek (int fd, off_t pos, int dir)
+{
+ off_t res;
+ sigframe thisframe (mainthread);
+
+ if (dir != SEEK_SET && dir != SEEK_CUR && dir != SEEK_END)
+ {
+ set_errno (EINVAL);
+ res = -1;
+ }
+ else if (cygheap->fdtab.not_open (fd))
+ {
+ set_errno (EBADF);
+ res = -1;
+ }
+ else
+ {
+ res = cygheap->fdtab[fd]->lseek (pos, dir);
+ }
+ syscall_printf ("%d = lseek (%d, %d, %d)", res, fd, pos, dir);
+
+ return res;
+}
+
+The sigframe thisframe (mainthread); is signal related - see
+"how_signals_work.txt".
+
+The if, else if, else tests (in order)
+* the validity of the dir parameter,
+* is the fd being passed actually open? (cannot seek on a closed fd)
+* call the lseek virtual function in the associated fhandler.
+
+So as you can see, there is no code that attempts to understand the nature of
+the fhandler.
+
+fhandlers that make cross-function-call use of win32 objects that are not
+inheritable cross-process need to implement fixup-after-fork and recreate those
+objects. HANDLES can be inherited, but memory mapped regions (for example)
+cannot.
+
+For an example step-by-step to create a new fhandler, see
+../doc/fhandler-tut.txt
diff --git a/winsup/cygwin/newsym b/winsup/cygwin/newsym
new file mode 100755
index 000000000..688a8c6f8
--- /dev/null
+++ b/winsup/cygwin/newsym
@@ -0,0 +1,24 @@
+#!/bin/sh -x
+lib=$1; shift
+as=$1; shift
+ar=$1; shift
+ranlib=$1; shift
+rm -rf newsym.dir
+trap "rm -rf newsym.dir" 0 1 2 15
+mkdir newsym.dir
+while [ -n "$1" ]; do
+ newsym=$1; shift
+ oldsym=$1; shift
+ cat <<EOF > newsym.dir/$newsym.s
+ .section .idata$6
+ .extern __imp__$oldsym
+ .extern __head_cygwin1_dll
+ .section .text
+ .global _$newsym
+_$newsym:
+ jmp *__imp__$oldsym
+EOF
+ $as -o newsym.dir/$newsym.o newsym.dir/$newsym.s
+done
+$ar cru $lib newsym.dir/*.o
+$ranlib $lib
diff --git a/winsup/cygwin/regex/COPYRIGHT b/winsup/cygwin/regex/COPYRIGHT
new file mode 100644
index 000000000..30c1f7a48
--- /dev/null
+++ b/winsup/cygwin/regex/COPYRIGHT
@@ -0,0 +1,20 @@
+Copyright 1992, 1993, 1994, 1997 Henry Spencer. All rights reserved.
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it, subject
+to the following restrictions:
+
+1. The author is not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
diff --git a/winsup/cygwin/regex/cclass.h b/winsup/cygwin/regex/cclass.h
new file mode 100644
index 000000000..7ddb44afb
--- /dev/null
+++ b/winsup/cygwin/regex/cclass.h
@@ -0,0 +1,31 @@
+/* character-class table */
+static struct cclass {
+ const char *name;
+ const char *chars;
+ const char *multis;
+} cclasses[] = {
+ {"alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789", ""},
+ {"alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+ ""},
+ {"blank", " \t", ""},
+ {"cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
+ \25\26\27\30\31\32\33\34\35\36\37\177", ""},
+ {"digit", "0123456789", ""},
+ {"graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+ 0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ ""},
+ {"lower", "abcdefghijklmnopqrstuvwxyz",
+ ""},
+ {"print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+ 0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
+ ""},
+ {"punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ ""},
+ {"space", "\t\n\v\f\r ", ""},
+ {"upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ ""},
+ {"xdigit", "0123456789ABCDEFabcdef",
+ ""},
+ {NULL, 0, ""}
+};
diff --git a/winsup/cygwin/regex/cname.h b/winsup/cygwin/regex/cname.h
new file mode 100644
index 000000000..1000f603e
--- /dev/null
+++ b/winsup/cygwin/regex/cname.h
@@ -0,0 +1,102 @@
+/* character-name table */
+static struct cname {
+ const char *name;
+ char code;
+} cnames[] = {
+ {"NUL", '\0'},
+ {"SOH", '\001'},
+ {"STX", '\002'},
+ {"ETX", '\003'},
+ {"EOT", '\004'},
+ {"ENQ", '\005'},
+ {"ACK", '\006'},
+ {"BEL", '\007'},
+ {"alert", '\007'},
+ {"BS", '\010'},
+ {"backspace", '\b'},
+ {"HT", '\011'},
+ {"tab", '\t'},
+ {"LF", '\012'},
+ {"newline", '\n'},
+ {"VT", '\013'},
+ {"vertical-tab", '\v'},
+ {"FF", '\014'},
+ {"form-feed", '\f'},
+ {"CR", '\015'},
+ {"carriage-return", '\r'},
+ {"SO", '\016'},
+ {"SI", '\017'},
+ {"DLE", '\020'},
+ {"DC1", '\021'},
+ {"DC2", '\022'},
+ {"DC3", '\023'},
+ {"DC4", '\024'},
+ {"NAK", '\025'},
+ {"SYN", '\026'},
+ {"ETB", '\027'},
+ {"CAN", '\030'},
+ {"EM", '\031'},
+ {"SUB", '\032'},
+ {"ESC", '\033'},
+ {"IS4", '\034'},
+ {"FS", '\034'},
+ {"IS3", '\035'},
+ {"GS", '\035'},
+ {"IS2", '\036'},
+ {"RS", '\036'},
+ {"IS1", '\037'},
+ {"US", '\037'},
+ {"space", ' '},
+ {"exclamation-mark", '!'},
+ {"quotation-mark", '"'},
+ {"number-sign", '#'},
+ {"dollar-sign", '$'},
+ {"percent-sign", '%'},
+ {"ampersand", '&'},
+ {"apostrophe", '\''},
+ {"left-parenthesis", '('},
+ {"right-parenthesis", ')'},
+ {"asterisk", '*'},
+ {"plus-sign", '+'},
+ {"comma", ','},
+ {"hyphen", '-'},
+ {"hyphen-minus", '-'},
+ {"period", '.'},
+ {"full-stop", '.'},
+ {"slash", '/'},
+ {"solidus", '/'},
+ {"zero", '0'},
+ {"one", '1'},
+ {"two", '2'},
+ {"three", '3'},
+ {"four", '4'},
+ {"five", '5'},
+ {"six", '6'},
+ {"seven", '7'},
+ {"eight", '8'},
+ {"nine", '9'},
+ {"colon", ':'},
+ {"semicolon", ';'},
+ {"less-than-sign", '<'},
+ {"equals-sign", '='},
+ {"greater-than-sign", '>'},
+ {"question-mark", '?'},
+ {"commercial-at", '@'},
+ {"left-square-bracket", '['},
+ {"backslash", '\\'},
+ {"reverse-solidus", '\\'},
+ {"right-square-bracket", ']'},
+ {"circumflex", '^'},
+ {"circumflex-accent", '^'},
+ {"underscore", '_'},
+ {"low-line", '_'},
+ {"grave-accent", '`'},
+ {"left-brace", '{'},
+ {"left-curly-bracket", '{'},
+ {"vertical-line", '|'},
+ {"right-brace", '}'},
+ {"right-curly-bracket", '}'},
+ {"tilde", '~'},
+ {"DEL", '\177'},
+ {NULL, 0}
+};
diff --git a/winsup/cygwin/regex/engine.c b/winsup/cygwin/regex/engine.c
new file mode 100644
index 000000000..919fe3f64
--- /dev/null
+++ b/winsup/cygwin/regex/engine.c
@@ -0,0 +1,1019 @@
+/*
+ * The matching engine and friends. This file is #included by regexec.c
+ * after suitable #defines of a variety of macros used herein, so that
+ * different state representations can be used without duplicating masses
+ * of code.
+ */
+
+#ifdef SNAMES
+#define matcher smatcher
+#define fast sfast
+#define slow sslow
+#define dissect sdissect
+#define backref sbackref
+#define step sstep
+#define print sprint
+#define at sat
+#define match smat
+#endif
+#ifdef LNAMES
+#define matcher lmatcher
+#define fast lfast
+#define slow lslow
+#define dissect ldissect
+#define backref lbackref
+#define step lstep
+#define print lprint
+#define at lat
+#define match lmat
+#endif
+
+/* another structure passed up and down to avoid zillions of parameters */
+struct match {
+ struct re_guts *g;
+ int eflags;
+ regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
+ char *offp; /* offsets work from here */
+ char *beginp; /* start of string -- virtual NUL precedes */
+ char *endp; /* end of string -- virtual NUL here */
+ char *coldp; /* can be no match starting before here */
+ char **lastpos; /* [nplus+1] */
+ STATEVARS;
+ states st; /* current states */
+ states fresh; /* states for a fresh start */
+ states tmp; /* temporary */
+ states empty; /* empty set of states */
+};
+
+#include "engine.ih"
+
+#ifdef REDEBUG
+#define SP(t, s, c) print(m, t, s, c, stdout)
+#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2)
+#define NOTE(str) { if (m->eflags&REG_TRACE) printf("=%s\n", (str)); }
+#else
+#define SP(t, s, c) /* nothing */
+#define AT(t, p1, p2, s1, s2) /* nothing */
+#define NOTE(s) /* nothing */
+#endif
+
+/*
+ - matcher - the actual matching engine
+ == static int matcher(register struct re_guts *g, char *string, \
+ == size_t nmatch, regmatch_t pmatch[], int eflags);
+ */
+static int /* 0 success, REG_NOMATCH failure */
+matcher(g, string, nmatch, pmatch, eflags)
+register struct re_guts *g;
+char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
+{
+ register char *endp;
+ register int i;
+ struct match mv;
+ register struct match *m = &mv;
+ register char *dp;
+ const register sopno gf = g->firststate+1; /* +1 for OEND */
+ const register sopno gl = g->laststate;
+ char *start;
+ char *stop;
+
+ /* simplify the situation where possible */
+ if (g->cflags&REG_NOSUB)
+ nmatch = 0;
+ if (eflags&REG_STARTEND) {
+ start = string + pmatch[0].rm_so;
+ stop = string + pmatch[0].rm_eo;
+ } else {
+ start = string;
+ stop = start + strlen(start);
+ }
+ if (stop < start)
+ return(REG_INVARG);
+
+ /* prescreening; this does wonders for this rather slow code */
+ if (g->must != NULL) {
+ for (dp = start; dp < stop; dp++)
+ if (*dp == g->must[0] && stop - dp >= g->mlen &&
+ memcmp(dp, g->must, (size_t)g->mlen) == 0)
+ break;
+ if (dp == stop) /* we didn't find g->must */
+ return(REG_NOMATCH);
+ }
+
+ /* match struct setup */
+ m->g = g;
+ m->eflags = eflags;
+ m->pmatch = NULL;
+ m->lastpos = NULL;
+ m->offp = string;
+ m->beginp = start;
+ m->endp = stop;
+ STATESETUP(m, 4);
+ SETUP(m->st);
+ SETUP(m->fresh);
+ SETUP(m->tmp);
+ SETUP(m->empty);
+ CLEAR(m->empty);
+
+ /* this loop does only one repetition except for backrefs */
+ for (;;) {
+ endp = fast(m, start, stop, gf, gl);
+ if (endp == NULL) { /* a miss */
+ STATETEARDOWN(m);
+ return(REG_NOMATCH);
+ }
+ if (nmatch == 0 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* where? */
+ assert(m->coldp != NULL);
+ for (;;) {
+ NOTE("finding start");
+ endp = slow(m, m->coldp, stop, gf, gl);
+ if (endp != NULL)
+ break;
+ assert(m->coldp < m->endp);
+ m->coldp++;
+ }
+ if (nmatch == 1 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* oh my, he wants the subexpressions... */
+ if (m->pmatch == NULL)
+ m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
+ sizeof(regmatch_t));
+ if (m->pmatch == NULL) {
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ for (i = 1; i <= m->g->nsub; i++)
+ m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
+ if (!g->backrefs && !(m->eflags&REG_BACKR)) {
+ NOTE("dissecting");
+ dp = dissect(m, m->coldp, endp, gf, gl);
+ } else {
+ if (g->nplus > 0 && m->lastpos == NULL)
+ m->lastpos = (char **)malloc((g->nplus+1) *
+ sizeof(char *));
+ if (g->nplus > 0 && m->lastpos == NULL) {
+ free(m->pmatch);
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ NOTE("backref dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ }
+ if (dp != NULL)
+ break;
+
+ /* uh-oh... we couldn't find a subexpression-level match */
+ assert(g->backrefs); /* must be back references doing it */
+ assert(g->nplus == 0 || m->lastpos != NULL);
+ for (;;) {
+ if (dp != NULL || endp <= m->coldp)
+ break; /* defeat */
+ NOTE("backoff");
+ endp = slow(m, m->coldp, endp-1, gf, gl);
+ if (endp == NULL)
+ break; /* defeat */
+ /* try it on a shorter possibility */
+#ifndef NDEBUG
+ for (i = 1; i <= m->g->nsub; i++) {
+ assert(m->pmatch[i].rm_so == -1);
+ assert(m->pmatch[i].rm_eo == -1);
+ }
+#endif
+ NOTE("backoff dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ }
+ assert(dp == NULL || dp == endp);
+ if (dp != NULL) /* found a shorter one */
+ break;
+
+ /* despite initial appearances, there is no match here */
+ NOTE("false alarm");
+ start = m->coldp + 1; /* recycle starting later */
+ assert(start <= stop);
+ }
+
+ /* fill in the details if requested */
+ if (nmatch > 0) {
+ pmatch[0].rm_so = m->coldp - m->offp;
+ pmatch[0].rm_eo = endp - m->offp;
+ }
+ if (nmatch > 1) {
+ assert(m->pmatch != NULL);
+ for (i = 1; i < nmatch; i++)
+ if (i <= m->g->nsub)
+ pmatch[i] = m->pmatch[i];
+ else {
+ pmatch[i].rm_so = -1;
+ pmatch[i].rm_eo = -1;
+ }
+ }
+
+ if (m->pmatch != NULL)
+ free((char *)m->pmatch);
+ if (m->lastpos != NULL)
+ free((char *)m->lastpos);
+ STATETEARDOWN(m);
+ return(0);
+}
+
+/*
+ - dissect - figure out what matched what, no back references
+ == static char *dissect(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* == stop (success) always */
+dissect(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register sopno es; /* end sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register char *stp; /* string matched by it cannot pass here */
+ register char *rest; /* start of rest of string */
+ register char *tail; /* string unmatched by rest of RE */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *sep; /* end of string matched by subsubRE */
+ register char *oldssp; /* previous ssp */
+ register char *dp;
+
+ AT("diss", start, stop, startst, stopst);
+ sp = start;
+ for (ss = startst; ss < stopst; ss = es) {
+ /* identify end of subRE */
+ es = ss;
+ switch (OP(m->g->strip[es])) {
+ case OPLUS_:
+ case OQUEST_:
+ es += OPND(m->g->strip[es]);
+ break;
+ case OCH_:
+ while (OP(m->g->strip[es]) != O_CH)
+ es += OPND(m->g->strip[es]);
+ break;
+ }
+ es++;
+
+ /* figure out what it matched */
+ switch (OP(m->g->strip[ss])) {
+ case OEND:
+ assert(nope);
+ break;
+ case OCHAR:
+ sp++;
+ break;
+ case OBOL:
+ case OEOL:
+ case OBOW:
+ case OEOW:
+ break;
+ case OANY:
+ case OANYOF:
+ sp++;
+ break;
+ case OBACK_:
+ case O_BACK:
+ assert(nope);
+ break;
+ /* cases where length of match is hard to find */
+ case OQUEST_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ /* did innards match? */
+ if (slow(m, sp, rest, ssub, esub) != NULL) {
+ dp = dissect(m, sp, rest, ssub, esub);
+ assert(dp == rest);
+ } else /* no */
+ assert(sp == rest);
+ sp = rest;
+ break;
+ case OPLUS_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ ssp = sp;
+ oldssp = ssp;
+ for (;;) { /* find last match of innards */
+ sep = slow(m, ssp, rest, ssub, esub);
+ if (sep == NULL || sep == ssp)
+ break; /* failed or matched null */
+ oldssp = ssp; /* on to next try */
+ ssp = sep;
+ }
+ if (sep == NULL) {
+ /* last successful match */
+ sep = ssp;
+ ssp = oldssp;
+ }
+ assert(sep == rest); /* must exhaust substring */
+ assert(slow(m, ssp, sep, ssub, esub) == rest);
+ dp = dissect(m, ssp, sep, ssub, esub);
+ assert(dp == sep);
+ sp = rest;
+ break;
+ case OCH_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = ss + OPND(m->g->strip[ss]) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ if (slow(m, sp, rest, ssub, esub) == rest)
+ break; /* it matched all of it */
+ /* that one missed, try next one */
+ assert(OP(m->g->strip[esub]) == OOR1);
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ dp = dissect(m, sp, rest, ssub, esub);
+ assert(dp == rest);
+ sp = rest;
+ break;
+ case O_PLUS:
+ case O_QUEST:
+ case OOR1:
+ case OOR2:
+ case O_CH:
+ assert(nope);
+ break;
+ case OLPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_so = sp - m->offp;
+ break;
+ case ORPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_eo = sp - m->offp;
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+ }
+
+ assert(sp == stop);
+ return(sp);
+}
+
+/*
+ - backref - figure out what matched what, figuring in back references
+ == static char *backref(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst, sopno lev);
+ */
+static char * /* == stop (success) or NULL (failure) */
+backref(m, start, stop, startst, stopst, lev)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+sopno lev; /* PLUS nesting level */
+{
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *dp;
+ register size_t len;
+ register int hard;
+ register sop s;
+ register regoff_t offsave;
+ register cset *cs;
+
+ AT("back", start, stop, startst, stopst);
+ sp = start;
+
+ /* get as far as we can with easy stuff */
+ hard = 0;
+ for (ss = startst; !hard && ss < stopst; ss++)
+ switch (OP(s = m->g->strip[ss])) {
+ case OCHAR:
+ if (sp == stop || *sp++ != (char)OPND(s))
+ return(NULL);
+ break;
+ case OANY:
+ if (sp == stop)
+ return(NULL);
+ sp++;
+ break;
+ case OANYOF:
+ cs = &m->g->sets[OPND(s)];
+ if (sp == stop || !CHIN(cs, *sp++))
+ return(NULL);
+ break;
+ case OBOL:
+ if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOL:
+ if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OBOW:
+ if (( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp > m->beginp &&
+ !ISWORD(*(sp-1))) ) &&
+ (sp < m->endp && ISWORD(*sp)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOW:
+ if (( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp < m->endp && !ISWORD(*sp)) ) &&
+ (sp > m->beginp && ISWORD(*(sp-1))) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case O_QUEST:
+ break;
+ case OOR1: /* matches null but needs to skip */
+ ss++;
+ s = m->g->strip[ss];
+ do {
+ assert(OP(s) == OOR2);
+ ss += OPND(s);
+ } while (OP(s = m->g->strip[ss]) != O_CH);
+ /* note that the ss++ gets us past the O_CH */
+ break;
+ default: /* have to make a choice */
+ hard = 1;
+ break;
+ }
+ if (!hard) { /* that was it! */
+ if (sp != stop)
+ return(NULL);
+ return(sp);
+ }
+ ss--; /* adjust for the for's final increment */
+
+ /* the hard stuff */
+ AT("hard", sp, stop, ss, stopst);
+ s = m->g->strip[ss];
+ switch (OP(s)) {
+ case OBACK_: /* the vilest depths */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ if (m->pmatch[i].rm_eo == -1)
+ return(NULL);
+ assert(m->pmatch[i].rm_so != -1);
+ len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
+ assert(stop - m->beginp >= len);
+ if (sp > stop - len)
+ return(NULL); /* not enough left to match */
+ ssp = m->offp + m->pmatch[i].rm_so;
+ if (memcmp(sp, ssp, len) != 0)
+ return(NULL);
+ while (m->g->strip[ss] != SOP(O_BACK, i))
+ ss++;
+ return(backref(m, sp+len, stop, ss+1, stopst, lev));
+ break;
+ case OQUEST_: /* to null or not */
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp); /* not */
+ return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
+ break;
+ case OPLUS_:
+ assert(m->lastpos != NULL);
+ assert(lev+1 <= m->g->nplus);
+ m->lastpos[lev+1] = sp;
+ return(backref(m, sp, stop, ss+1, stopst, lev+1));
+ break;
+ case O_PLUS:
+ if (sp == m->lastpos[lev]) /* last pass matched null */
+ return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ /* try another pass */
+ m->lastpos[lev] = sp;
+ dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
+ if (dp == NULL)
+ return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ else
+ return(dp);
+ break;
+ case OCH_: /* find the right one, if any */
+ ssub = ss + 1;
+ esub = ss + OPND(s) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ dp = backref(m, sp, stop, ssub, esub, lev);
+ if (dp != NULL)
+ return(dp);
+ /* that one missed, try next one */
+ if (OP(m->g->strip[esub]) == O_CH)
+ return(NULL); /* there is none */
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ break;
+ case OLPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_so;
+ m->pmatch[i].rm_so = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_so = offsave;
+ return(NULL);
+ break;
+ case ORPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_eo;
+ m->pmatch[i].rm_eo = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_eo = offsave;
+ return(NULL);
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+
+ /* "can't happen" */
+ assert(nope);
+ /* NOTREACHED */
+ return((char *)NULL); /* dummy */
+}
+
+/*
+ - fast - step through the string at top speed
+ == static char *fast(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* where tentative match ended, or NULL */
+fast(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register states st = m->st;
+ register states fresh = m->fresh;
+ register states tmp = m->tmp;
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start-1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *coldp; /* last p after which no match was underway */
+
+ CLEAR(st);
+ SET1(st, startst);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ ASSIGN(fresh, st);
+ SP("start", st, *p);
+ coldp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+ if (EQ(st, fresh))
+ coldp = p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, fresh);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("aft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ assert(coldp != NULL);
+ m->coldp = coldp;
+ if (ISSET(st, stopst))
+ return(p+1);
+ else
+ return(NULL);
+}
+
+/*
+ - slow - step through the string more deliberately
+ == static char *slow(register struct match *m, char *start, \
+ == char *stop, sopno startst, sopno stopst);
+ */
+static char * /* where it ended */
+slow(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ register states st = m->st;
+ register states empty = m->empty;
+ register states tmp = m->tmp;
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start-1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *matchp; /* last p at which a match ended */
+
+ AT("slow", start, stop, startst, stopst);
+ CLEAR(st);
+ SET1(st, startst);
+ SP("sstart", st, *p);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ matchp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst))
+ matchp = p;
+ if (EQ(st, empty) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, empty);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("saft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ return(matchp);
+}
+
+
+/*
+ - step - map set of states reachable before char to set reachable after
+ == static states step(register struct re_guts *g, sopno start, sopno stop, \
+ == register states bef, int ch, register states aft);
+ == #define BOL (OUT+1)
+ == #define EOL (BOL+1)
+ == #define BOLEOL (BOL+2)
+ == #define NOTHING (BOL+3)
+ == #define BOW (BOL+4)
+ == #define EOW (BOL+5)
+ == #define CODEMAX (BOL+5) // highest code used
+ == #define NONCHAR(c) ((c) > CHAR_MAX)
+ == #define NNONCHAR (CODEMAX-CHAR_MAX)
+ */
+static states
+step(g, start, stop, bef, ch, aft)
+register struct re_guts *g;
+sopno start; /* start state within strip */
+sopno stop; /* state after stop state within strip */
+register states bef; /* states reachable before */
+int ch; /* character or NONCHAR code */
+register states aft; /* states already known reachable after */
+{
+ register cset *cs;
+ register sop s;
+ register sopno pc;
+ register onestate here; /* note, macros know this name */
+ register sopno look;
+ register long i;
+
+ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
+ s = g->strip[pc];
+ switch (OP(s)) {
+ case OEND:
+ assert(pc == stop-1);
+ break;
+ case OCHAR:
+ /* only characters can match */
+ assert(!NONCHAR(ch) || ch != (char)OPND(s));
+ if (ch == (char)OPND(s))
+ FWD(aft, bef, 1);
+ break;
+ case OBOL:
+ if (ch == BOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OEOL:
+ if (ch == EOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OBOW:
+ if (ch == BOW)
+ FWD(aft, bef, 1);
+ break;
+ case OEOW:
+ if (ch == EOW)
+ FWD(aft, bef, 1);
+ break;
+ case OANY:
+ if (!NONCHAR(ch))
+ FWD(aft, bef, 1);
+ break;
+ case OANYOF:
+ cs = &g->sets[OPND(s)];
+ if (!NONCHAR(ch) && CHIN(cs, ch))
+ FWD(aft, bef, 1);
+ break;
+ case OBACK_: /* ignored here */
+ case O_BACK:
+ FWD(aft, aft, 1);
+ break;
+ case OPLUS_: /* forward, this is just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case O_PLUS: /* both forward and back */
+ FWD(aft, aft, 1);
+ i = ISSETBACK(aft, OPND(s));
+ BACK(aft, aft, OPND(s));
+ if (!i && ISSETBACK(aft, OPND(s))) {
+ /* oho, must reconsider loop body */
+ pc -= OPND(s) + 1;
+ INIT(here, pc);
+ }
+ break;
+ case OQUEST_: /* two branches, both forward */
+ FWD(aft, aft, 1);
+ FWD(aft, aft, OPND(s));
+ break;
+ case O_QUEST: /* just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case OLPAREN: /* not significant here */
+ case ORPAREN:
+ FWD(aft, aft, 1);
+ break;
+ case OCH_: /* mark the first two branches */
+ FWD(aft, aft, 1);
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ break;
+ case OOR1: /* done a branch, find the O_CH */
+ if (ISSTATEIN(aft, here)) {
+ for (look = 1;
+ OP(s = g->strip[pc+look]) != O_CH;
+ look += OPND(s))
+ assert(OP(s) == OOR2);
+ FWD(aft, aft, look);
+ }
+ break;
+ case OOR2: /* propagate OCH_'s marking */
+ FWD(aft, aft, 1);
+ if (OP(g->strip[pc+OPND(s)]) != O_CH) {
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ }
+ break;
+ case O_CH: /* just empty */
+ FWD(aft, aft, 1);
+ break;
+ default: /* ooooops... */
+ assert(nope);
+ break;
+ }
+ }
+
+ return(aft);
+}
+
+#ifdef REDEBUG
+/*
+ - print - print a set of states
+ == #ifdef REDEBUG
+ == static void print(struct match *m, char *caption, states st, \
+ == int ch, FILE *d);
+ == #endif
+ */
+static void
+print(m, caption, st, ch, d)
+struct match *m;
+char *caption;
+states st;
+int ch;
+FILE *d;
+{
+ register struct re_guts *g = m->g;
+ register int i;
+ register int first = 1;
+
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ fprintf(d, "%s", caption);
+ if (ch != '\0')
+ fprintf(d, " %s", pchar(ch));
+ for (i = 0; i < g->nstates; i++)
+ if (ISSET(st, i)) {
+ fprintf(d, "%s%d", (first) ? "\t" : ", ", i);
+ first = 0;
+ }
+ fprintf(d, "\n");
+}
+
+/*
+ - at - print current situation
+ == #ifdef REDEBUG
+ == static void at(struct match *m, char *title, char *start, char *stop, \
+ == sopno startst, sopno stopst);
+ == #endif
+ */
+static void
+at(m, title, start, stop, startst, stopst)
+struct match *m;
+char *title;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ printf("%s %s-", title, pchar(*start));
+ printf("%s ", pchar(*stop));
+ printf("%ld-%ld\n", (long)startst, (long)stopst);
+}
+
+#ifndef PCHARDONE
+#define PCHARDONE /* never again */
+/*
+ - pchar - make a character printable
+ == #ifdef REDEBUG
+ == static char *pchar(int ch);
+ == #endif
+ *
+ * Is this identical to regchar() over in debug.c? Well, yes. But a
+ * duplicate here avoids having a debugging-capable regexec.o tied to
+ * a matching debug.o, and this is convenient. It all disappears in
+ * the non-debug compilation anyway, so it doesn't matter much.
+ */
+static char * /* -> representation */
+pchar(ch)
+int ch;
+{
+ static char pbuf[10];
+
+ if (isprint(ch) || ch == ' ')
+ sprintf(pbuf, "%c", ch);
+ else
+ sprintf(pbuf, "\\%o", ch);
+ return(pbuf);
+}
+#endif
+#endif
+
+#undef matcher
+#undef fast
+#undef slow
+#undef dissect
+#undef backref
+#undef step
+#undef print
+#undef at
+#undef match
diff --git a/winsup/cygwin/regex/engine.ih b/winsup/cygwin/regex/engine.ih
new file mode 100644
index 000000000..cc98334e7
--- /dev/null
+++ b/winsup/cygwin/regex/engine.ih
@@ -0,0 +1,35 @@
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === engine.c === */
+static int matcher(register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
+static char *dissect(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
+static char *backref(register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev);
+static char *fast(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
+static char *slow(register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
+static states step(register struct re_guts *g, sopno start, sopno stop, register states bef, int ch, register states aft);
+#define BOL (OUT+1)
+#define EOL (BOL+1)
+#define BOLEOL (BOL+2)
+#define NOTHING (BOL+3)
+#define BOW (BOL+4)
+#define EOW (BOL+5)
+#define CODEMAX (BOL+5) /* highest code used */
+#define NONCHAR(c) ((c) > CHAR_MAX)
+#define NNONCHAR (CODEMAX-CHAR_MAX)
+#ifdef REDEBUG
+static void print(struct match *m, char *caption, states st, int ch, FILE *d);
+#endif
+#ifdef REDEBUG
+static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst);
+#endif
+#ifdef REDEBUG
+static char *pchar(int ch);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
diff --git a/winsup/cygwin/regex/mkh b/winsup/cygwin/regex/mkh
new file mode 100755
index 000000000..252b246c7
--- /dev/null
+++ b/winsup/cygwin/regex/mkh
@@ -0,0 +1,76 @@
+#! /bin/sh
+# mkh - pull headers out of C source
+PATH=/bin:/usr/bin ; export PATH
+
+# egrep pattern to pick out marked lines
+egrep='^ =([ ]|$)'
+
+# Sed program to process marked lines into lines for the header file.
+# The markers have already been removed. Two things are done here: removal
+# of backslashed newlines, and some fudging of comments. The first is done
+# because -o needs to have prototypes on one line to strip them down.
+# Getting comments into the output is tricky; we turn C++-style // comments
+# into /* */ comments, after altering any existing */'s to avoid trouble.
+peel=' /\\$/N
+ /\\\n[ ]*/s///g
+ /\/\//s;\*/;* /;g
+ /\/\//s;//\(.*\);/*\1 */;'
+
+for a
+do
+ case "$a" in
+ -o) # old (pre-function-prototype) compiler
+ # add code to comment out argument lists
+ peel="$peel
+ "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);'
+ shift
+ ;;
+ -b) # funny Berkeley __P macro
+ peel="$peel
+ "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));'
+ shift
+ ;;
+ -s) # compiler doesn't like `static foo();'
+ # add code to get rid of the `static'
+ peel="$peel
+ "'/^static[ ][^\/]*[a-zA-Z0-9_)](.*)/s;static.;;'
+ shift
+ ;;
+ -p) # private declarations
+ egrep='^ ==([ ]|$)'
+ shift
+ ;;
+ -i) # wrap in #ifndef, argument is name
+ ifndef="$2"
+ shift ; shift
+ ;;
+ *) break
+ ;;
+ esac
+done
+
+if test " $ifndef" != " "
+then
+ echo "#ifndef $ifndef"
+ echo "#define $ifndef /* never again */"
+fi
+echo "/* ========= begin header generated by $0 ========= */"
+echo '#ifdef __cplusplus'
+echo 'extern "C" {'
+echo '#endif'
+for f
+do
+ echo
+ echo "/* === $f === */"
+ egrep "$egrep" $f | sed 's/^ ==*[ ]//;s/^ ==*$//' | sed "$peel"
+ echo
+done
+echo '#ifdef __cplusplus'
+echo '}'
+echo '#endif'
+echo "/* ========= end header generated by $0 ========= */"
+if test " $ifndef" != " "
+then
+ echo "#endif"
+fi
+exit 0
diff --git a/winsup/cygwin/regex/regcomp.c b/winsup/cygwin/regex/regcomp.c
new file mode 100644
index 000000000..34c1f2e5c
--- /dev/null
+++ b/winsup/cygwin/regex/regcomp.c
@@ -0,0 +1,1546 @@
+#include "winsup.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "regex.h"
+
+#include "utils.h"
+#include "regex2.h"
+
+#include "cclass.h"
+#include "cname.h"
+
+/*
+ * parse structure, passed up and down to avoid global variables and
+ * other clumsinesses
+ */
+struct parse {
+ char *next; /* next character in RE */
+ char *end; /* end of string (-> NUL normally) */
+ int error; /* has an error been seen? */
+ sop *strip; /* malloced strip */
+ sopno ssize; /* malloced strip size (allocated) */
+ sopno slen; /* malloced strip length (used) */
+ int ncsalloc; /* number of csets allocated */
+ struct re_guts *g;
+# define NPAREN 10 /* we need to remember () 1-9 for back refs */
+ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
+ sopno pend[NPAREN]; /* -> ) ([0] unused) */
+};
+
+#include "regcomp.ih"
+
+static char nuls[10]; /* place to point scanner in event of error */
+
+/*
+ * macros for use with parse structure
+ * BEWARE: these know that the parse structure is named `p' !!!
+ */
+#define PEEK() (*p->next)
+#define PEEK2() (*(p->next+1))
+#define MORE() (p->next < p->end)
+#define MORE2() (p->next+1 < p->end)
+#define SEE(c) (MORE() && PEEK() == (c))
+#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
+#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
+#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
+#define NEXT() (p->next++)
+#define NEXT2() (p->next += 2)
+#define NEXTn(n) (p->next += (n))
+#define GETNEXT() (*p->next++)
+#define SETERROR(e) seterr(p, (e))
+#define REQUIRE(co, e) ((co) || SETERROR(e))
+#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e))
+#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
+#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
+#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
+#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
+#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
+#define HERE() (p->slen)
+#define THERE() (p->slen - 1)
+#define THERETHERE() (p->slen - 2)
+#define DROP(n) (p->slen -= (n))
+
+#ifndef NDEBUG
+static int never = 0; /* for use in asserts; shuts lint up */
+#else
+#define never 0 /* some <assert.h>s have bugs too */
+#endif
+
+/*
+ - regcomp - interface for parser and compilation
+ = extern int regcomp(regex_t *, const char *, int);
+ = #define REG_BASIC 0000
+ = #define REG_EXTENDED 0001
+ = #define REG_ICASE 0002
+ = #define REG_NOSUB 0004
+ = #define REG_NEWLINE 0010
+ = #define REG_NOSPEC 0020
+ = #define REG_PEND 0040
+ = #define REG_DUMP 0200
+ */
+int /* 0 success, otherwise REG_something */
+regcomp(preg, pattern, cflags)
+regex_t *preg;
+const char *pattern;
+int cflags;
+{
+ struct parse pa;
+ register struct re_guts *g;
+ register struct parse *p = &pa;
+ register int i;
+ register size_t len;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&~REG_DUMP)
+#endif
+
+ cflags = GOODFLAGS(cflags);
+ if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
+ return(REG_INVARG);
+
+ if (cflags&REG_PEND) {
+ if (preg->re_endp < pattern)
+ return(REG_INVARG);
+ len = preg->re_endp - pattern;
+ } else
+ len = strlen((char *)pattern);
+
+ /* do the mallocs early so failure handling is easy */
+ g = (struct re_guts *)malloc(sizeof(struct re_guts) +
+ (NC-1)*sizeof(cat_t));
+ if (g == NULL)
+ return(REG_ESPACE);
+ p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
+ p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+ p->slen = 0;
+ if (p->strip == NULL) {
+ free((char *)g);
+ return(REG_ESPACE);
+ }
+
+ /* set things up */
+ p->g = g;
+ p->next = (char *)pattern; /* convenience; we do not modify it */
+ p->end = p->next + len;
+ p->error = 0;
+ p->ncsalloc = 0;
+ for (i = 0; i < NPAREN; i++) {
+ p->pbegin[i] = 0;
+ p->pend[i] = 0;
+ }
+ g->csetsize = NC;
+ g->sets = NULL;
+ g->setbits = NULL;
+ g->ncsets = 0;
+ g->cflags = cflags;
+ g->iflags = 0;
+ g->nbol = 0;
+ g->neol = 0;
+ g->must = NULL;
+ g->mlen = 0;
+ g->nsub = 0;
+ g->ncategories = 1; /* category 0 is "everything else" */
+ g->categories = &g->catspace[-(CHAR_MIN)];
+ (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+ g->backrefs = 0;
+
+ /* do it */
+ EMIT(OEND, 0);
+ g->firststate = THERE();
+ if (cflags&REG_EXTENDED)
+ p_ere(p, OUT);
+ else if (cflags&REG_NOSPEC)
+ p_str(p);
+ else
+ p_bre(p, OUT, OUT);
+ EMIT(OEND, 0);
+ g->laststate = THERE();
+
+ /* tidy up loose ends and fill things in */
+ categorize(p, g);
+ stripsnug(p, g);
+ findmust(p, g);
+ g->nplus = pluscount(p, g);
+ g->magic = MAGIC2;
+ preg->re_nsub = g->nsub;
+ preg->re_g = g;
+ preg->re_magic = MAGIC1;
+#ifndef REDEBUG
+ /* not debugging, so can't rely on the assert() in regexec() */
+ if (g->iflags&BAD)
+ SETERROR(REG_ASSERT);
+#endif
+
+ /* win or lose, we're done */
+ if (p->error != 0) /* lose */
+ regfree(preg);
+ return(p->error);
+}
+
+/*
+ - p_ere - ERE parser top level, concatenation and alternation
+ == static void p_ere(register struct parse *p, int stop);
+ */
+static void
+p_ere(p, stop)
+register struct parse *p;
+int stop; /* character this ERE should end at */
+{
+ register char c;
+ register sopno prevback = 0;
+ register sopno prevfwd = 0;
+ register sopno conc = 0;
+ register int first = 1; /* is this the first alternative? */
+
+ for (;;) {
+ /* do a bunch of concatenated expressions */
+ conc = HERE();
+ while (MORE() && (c = PEEK()) != '|' && c != stop)
+ p_ere_exp(p);
+ REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
+
+ if (!EAT('|'))
+ break; /* NOTE BREAK OUT */
+
+ if (first) {
+ INSERT(OCH_, conc); /* offset is wrong */
+ prevfwd = conc;
+ prevback = conc;
+ first = 0;
+ }
+ ASTERN(OOR1, prevback);
+ prevback = THERE();
+ AHEAD(prevfwd); /* fix previous offset */
+ prevfwd = HERE();
+ EMIT(OOR2, 0); /* offset is very wrong */
+ }
+
+ if (!first) { /* tail-end fixups */
+ AHEAD(prevfwd);
+ ASTERN(O_CH, prevback);
+ }
+
+ assert(!MORE() || SEE(stop));
+}
+
+/*
+ - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
+ == static void p_ere_exp(register struct parse *p);
+ */
+static void
+p_ere_exp(p)
+register struct parse *p;
+{
+ register char c;
+ register sopno pos;
+ register int count;
+ register int count2;
+ register sopno subno;
+ int wascaret = 0;
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+
+ pos = HERE();
+ switch (c) {
+ case '(':
+ REQUIRE(MORE(), REG_EPAREN);
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ if (!SEE(')'))
+ p_ere(p, ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ MUSTEAT(')', REG_EPAREN);
+ break;
+#ifndef POSIX_MISTAKE
+ case ')': /* happens only if no current unmatched ( */
+ /*
+ * You may ask, why the ifndef? Because I didn't notice
+ * this until slightly too late for 1003.2, and none of the
+ * other 1003.2 regular-expression reviewers noticed it at
+ * all. So an unmatched ) is legal POSIX, at least until
+ * we can get it fixed.
+ */
+ SETERROR(REG_EPAREN);
+ break;
+#endif
+ case '^':
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ wascaret = 1;
+ break;
+ case '$':
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ break;
+ case '|':
+ SETERROR(REG_EMPTY);
+ break;
+ case '*':
+ case '+':
+ case '?':
+ SETERROR(REG_BADRPT);
+ break;
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case '\\':
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = GETNEXT();
+ ordinary(p, c);
+ break;
+ case '{': /* okay as ordinary except if digit follows */
+ REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, c);
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ /* we call { a repetition if followed by a digit */
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit(PEEK2())) ))
+ return; /* no repetition, we're done */
+ NEXT();
+
+ REQUIRE(!wascaret, REG_BADRPT);
+ switch (c) {
+ case '*': /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ break;
+ case '+':
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ break;
+ case '?':
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, pos); /* offset slightly wrong */
+ ASTERN(OOR1, pos); /* this one's right */
+ AHEAD(pos); /* fix the OCH_ */
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case '{':
+ count = p_count(p);
+ if (EAT(',')) {
+ if (isdigit(PEEK())) {
+ count2 = p_count(p);
+ REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EAT('}')) { /* error heuristics */
+ while (MORE() && PEEK() != '}')
+ NEXT();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit(PEEK2())) ) )
+ return;
+ SETERROR(REG_BADRPT);
+}
+
+/*
+ - p_str - string (no metacharacters) "parser"
+ == static void p_str(register struct parse *p);
+ */
+static void
+p_str(p)
+register struct parse *p;
+{
+ REQUIRE(MORE(), REG_EMPTY);
+ while (MORE())
+ ordinary(p, GETNEXT());
+}
+
+/*
+ - p_bre - BRE parser top level, anchoring and concatenation
+ == static void p_bre(register struct parse *p, register int end1, \
+ == register int end2);
+ * Giving end1 as OUT essentially eliminates the end1/end2 check.
+ *
+ * This implementation is a bit of a kludge, in that a trailing $ is first
+ * taken as an ordinary character and then revised to be an anchor. The
+ * only undesirable side effect is that '$' gets included as a character
+ * category in such cases. This is fairly harmless; not worth fixing.
+ * The amount of lookahead needed to avoid this kludge is excessive.
+ */
+static void
+p_bre(p, end1, end2)
+register struct parse *p;
+register int end1; /* first terminating character */
+register int end2; /* second terminating character */
+{
+ register sopno start = HERE();
+ register int first = 1; /* first subexpression? */
+ register int wasdollar = 0;
+
+ if (EAT('^')) {
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ }
+ while (MORE() && !SEETWO(end1, end2)) {
+ wasdollar = p_simp_re(p, first);
+ first = 0;
+ }
+ if (wasdollar) { /* oops, that was a trailing anchor */
+ DROP(1);
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ }
+
+ REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
+}
+
+/*
+ - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
+ == static int p_simp_re(register struct parse *p, int starordinary);
+ */
+static int /* was the simple RE an unbackslashed $? */
+p_simp_re(p, starordinary)
+register struct parse *p;
+int starordinary; /* is a leading * an ordinary character? */
+{
+ register int c;
+ register int count;
+ register int count2;
+ register sopno pos;
+ register int i;
+ register sopno subno;
+# define BACKSL (1<<CHAR_BIT)
+
+ pos = HERE(); /* repetion op, if any, covers from here */
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+ if (c == '\\') {
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = BACKSL | (unsigned char)GETNEXT();
+ }
+ switch (c) {
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case BACKSL|'{':
+ SETERROR(REG_BADRPT);
+ break;
+ case BACKSL|'(':
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ /* the MORE here is an error heuristic */
+ if (MORE() && !SEETWO('\\', ')'))
+ p_bre(p, '\\', ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+ break;
+ case BACKSL|')': /* should not get here -- must be user */
+ case BACKSL|'}':
+ SETERROR(REG_EPAREN);
+ break;
+ case BACKSL|'1':
+ case BACKSL|'2':
+ case BACKSL|'3':
+ case BACKSL|'4':
+ case BACKSL|'5':
+ case BACKSL|'6':
+ case BACKSL|'7':
+ case BACKSL|'8':
+ case BACKSL|'9':
+ i = (c&~BACKSL) - '0';
+ assert(i < NPAREN);
+ if (p->pend[i] != 0) {
+ assert(i <= p->g->nsub);
+ EMIT(OBACK_, i);
+ assert(p->pbegin[i] != 0);
+ assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
+ assert(OP(p->strip[p->pend[i]]) == ORPAREN);
+ (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
+ EMIT(O_BACK, i);
+ } else
+ SETERROR(REG_ESUBREG);
+ p->g->backrefs = 1;
+ break;
+ case '*':
+ REQUIRE(starordinary, REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, (char)c); /* takes off BACKSL, if any */
+ break;
+ }
+
+ if (EAT('*')) { /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ } else if (EATTWO('\\', '{')) {
+ count = p_count(p);
+ if (EAT(',')) {
+ if (MORE() && isdigit(PEEK())) {
+ count2 = p_count(p);
+ REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EATTWO('\\', '}')) { /* error heuristics */
+ while (MORE() && !SEETWO('\\', '}'))
+ NEXT();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
+ return(1);
+
+ return(0);
+}
+
+/*
+ - p_count - parse a repetition count
+ == static int p_count(register struct parse *p);
+ */
+static int /* the value */
+p_count(p)
+register struct parse *p;
+{
+ register int count = 0;
+ register int ndigits = 0;
+
+ while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
+ count = count*10 + (GETNEXT() - '0');
+ ndigits++;
+ }
+
+ REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+ return(count);
+}
+
+/*
+ - p_bracket - parse a bracketed character list
+ == static void p_bracket(register struct parse *p);
+ *
+ * Note a significant property of this code: if the allocset() did SETERROR,
+ * no set operations are done.
+ */
+static void
+p_bracket(p)
+register struct parse *p;
+{
+ register cset *cs = allocset(p);
+ register int invert = 0;
+
+ /* Dept of Truly Sickening Special-Case Kludges */
+ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
+ EMIT(OBOW, 0);
+ NEXTn(6);
+ return;
+ }
+ if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
+ EMIT(OEOW, 0);
+ NEXTn(6);
+ return;
+ }
+
+ if (EAT('^'))
+ invert++; /* make note to invert set at end */
+ if (EAT(']'))
+ CHadd(cs, ']');
+ else if (EAT('-'))
+ CHadd(cs, '-');
+ while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
+ p_b_term(p, cs);
+ if (EAT('-'))
+ CHadd(cs, '-');
+ MUSTEAT(']', REG_EBRACK);
+
+ if (p->error != 0) /* don't mess things up further */
+ return;
+
+ if (p->g->cflags&REG_ICASE) {
+ register int i;
+ register int ci;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i) && isalpha(i)) {
+ ci = othercase(i);
+ if (ci != i)
+ CHadd(cs, ci);
+ }
+ if (cs->multis != NULL)
+ mccase(p, cs);
+ }
+ if (invert) {
+ register int i;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i))
+ CHsub(cs, i);
+ else
+ CHadd(cs, i);
+ if (p->g->cflags&REG_NEWLINE)
+ CHsub(cs, '\n');
+ if (cs->multis != NULL)
+ mcinvert(p, cs);
+ }
+
+ assert(cs->multis == NULL); /* xxx */
+
+ if (nch(p, cs) == 1) { /* optimize singleton sets */
+ ordinary(p, firstch(p, cs));
+ freeset(p, cs);
+ } else
+ EMIT(OANYOF, freezeset(p, cs));
+}
+
+/*
+ - p_b_term - parse one term of a bracketed character list
+ == static void p_b_term(register struct parse *p, register cset *cs);
+ */
+static void
+p_b_term(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register char c;
+ register char start, finish;
+ register int i;
+
+ /* classify what we've got */
+ switch ((MORE()) ? PEEK() : '\0') {
+ case '[':
+ c = (MORE2()) ? PEEK2() : '\0';
+ break;
+ case '-':
+ SETERROR(REG_ERANGE);
+ return; /* NOTE RETURN */
+ break;
+ default:
+ c = '\0';
+ break;
+ }
+
+ switch (c) {
+ case ':': /* character class */
+ NEXT2();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+ p_b_cclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+ break;
+ case '=': /* equivalence class */
+ NEXT2();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+ p_b_eclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+ break;
+ default: /* symbol, ordinary character, or range */
+/* xxx revision needed for multichar stuff */
+ start = p_b_symbol(p);
+ if (SEE('-') && MORE2() && PEEK2() != ']') {
+ /* range */
+ NEXT();
+ if (EAT('-'))
+ finish = '-';
+ else
+ finish = p_b_symbol(p);
+ } else
+ finish = start;
+/* xxx what about signed chars here... */
+ REQUIRE(start <= finish, REG_ERANGE);
+ for (i = start; i <= finish; i++)
+ CHadd(cs, i);
+ break;
+ }
+}
+
+/*
+ - p_b_cclass - parse a character-class name and deal with it
+ == static void p_b_cclass(register struct parse *p, register cset *cs);
+ */
+static void
+p_b_cclass(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register char *sp = p->next;
+ register struct cclass *cp;
+ register size_t len;
+ register const char *u;
+ register char c;
+
+ while (MORE() && isalpha(PEEK()))
+ NEXT();
+ len = p->next - sp;
+ for (cp = cclasses; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ break;
+ if (cp->name == NULL) {
+ /* oops, didn't find it */
+ SETERROR(REG_ECTYPE);
+ return;
+ }
+
+ u = cp->chars;
+ while ((c = *u++) != '\0')
+ CHadd(cs, c);
+ for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ MCadd(p, cs, u);
+}
+
+/*
+ - p_b_eclass - parse an equivalence-class name and deal with it
+ == static void p_b_eclass(register struct parse *p, register cset *cs);
+ *
+ * This implementation is incomplete. xxx
+ */
+static void
+p_b_eclass(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register char c;
+
+ c = p_b_coll_elem(p, '=');
+ CHadd(cs, c);
+}
+
+/*
+ - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
+ == static char p_b_symbol(register struct parse *p);
+ */
+static char /* value of symbol */
+p_b_symbol(p)
+register struct parse *p;
+{
+ register char value;
+
+ REQUIRE(MORE(), REG_EBRACK);
+ if (!EATTWO('[', '.'))
+ return(GETNEXT());
+
+ /* collating symbol */
+ value = p_b_coll_elem(p, '.');
+ REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
+ return(value);
+}
+
+/*
+ - p_b_coll_elem - parse a collating-element name and look it up
+ == static char p_b_coll_elem(register struct parse *p, int endc);
+ */
+static char /* value of collating element */
+p_b_coll_elem(p, endc)
+register struct parse *p;
+int endc; /* name ended by endc,']' */
+{
+ register char *sp = p->next;
+ register struct cname *cp;
+ register int len;
+
+ while (MORE() && !SEETWO(endc, ']'))
+ NEXT();
+ if (!MORE()) {
+ SETERROR(REG_EBRACK);
+ return(0);
+ }
+ len = p->next - sp;
+ for (cp = cnames; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ return(cp->code); /* known name */
+ if (len == 1)
+ return(*sp); /* single character */
+ SETERROR(REG_ECOLLATE); /* neither */
+ return(0);
+}
+
+/*
+ - othercase - return the case counterpart of an alphabetic
+ == static char othercase(int ch);
+ */
+static char /* if no counterpart, return ch */
+othercase(ch)
+int ch;
+{
+ assert(isalpha(ch));
+ if (isupper(ch))
+ return(tolower(ch));
+ else if (islower(ch))
+ return(toupper(ch));
+ else /* peculiar, but could happen */
+ return(ch);
+}
+
+/*
+ - bothcases - emit a dualcase version of a two-case character
+ == static void bothcases(register struct parse *p, int ch);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+bothcases(p, ch)
+register struct parse *p;
+int ch;
+{
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[3];
+
+ assert(othercase(ch) != ch); /* p_bracket() would recurse */
+ p->next = bracket;
+ p->end = bracket+2;
+ bracket[0] = ch;
+ bracket[1] = ']';
+ bracket[2] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+2);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - ordinary - emit an ordinary character
+ == static void ordinary(register struct parse *p, register int ch);
+ */
+static void
+ordinary(p, ch)
+register struct parse *p;
+register int ch;
+{
+ register cat_t *cap = p->g->categories;
+
+ if ((p->g->cflags&REG_ICASE) && isalpha(ch) && othercase(ch) != ch)
+ bothcases(p, ch);
+ else {
+ EMIT(OCHAR, (unsigned char)ch);
+ if (cap[ch] == 0)
+ cap[ch] = p->g->ncategories++;
+ }
+}
+
+/*
+ - nonnewline - emit REG_NEWLINE version of OANY
+ == static void nonnewline(register struct parse *p);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+nonnewline(p)
+register struct parse *p;
+{
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[4];
+
+ p->next = bracket;
+ p->end = bracket+3;
+ bracket[0] = '^';
+ bracket[1] = '\n';
+ bracket[2] = ']';
+ bracket[3] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+3);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - repeat - generate code for a bounded repetition, recursively if needed
+ == static void repeat(register struct parse *p, sopno start, int from, int to);
+ */
+static void
+repeat(p, start, from, to)
+register struct parse *p;
+sopno start; /* operand from here to end of strip */
+int from; /* repeated from this number */
+int to; /* to this number of times (maybe INFINITY) */
+{
+ register sopno finish = HERE();
+# define N 2
+# define INF 3
+# define REP(f, t) ((f)*8 + (t))
+# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
+ register sopno copy;
+
+ if (p->error != 0) /* head off possible runaway recursion */
+ return;
+
+ assert(from <= to);
+
+ switch (REP(MAP(from), MAP(to))) {
+ case REP(0, 0): /* must be user doing this */
+ DROP(finish-start); /* drop the operand */
+ break;
+ case REP(0, 1): /* as x{1,1}? */
+ case REP(0, N): /* as x{1,n}? */
+ case REP(0, INF): /* as x{1,}? */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start); /* offset is wrong... */
+ repeat(p, start+1, 1, to);
+ ASTERN(OOR1, start);
+ AHEAD(start); /* ... fix it */
+ EMIT(OOR2, 0);
+ AHEAD(THERE());
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case REP(1, 1): /* trivial case */
+ /* done */
+ break;
+ case REP(1, N): /* as x?x{1,n-1} */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start);
+ ASTERN(OOR1, start);
+ AHEAD(start);
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ copy = dupl(p, start+1, finish+1);
+ assert(copy == finish+4);
+ repeat(p, copy, 1, to-1);
+ break;
+ case REP(1, INF): /* as x+ */
+ INSERT(OPLUS_, start);
+ ASTERN(O_PLUS, start);
+ break;
+ case REP(N, N): /* as xx{m-1,n-1} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to-1);
+ break;
+ case REP(N, INF): /* as xx{n-1,INF} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to);
+ break;
+ default: /* "can't happen" */
+ SETERROR(REG_ASSERT); /* just in case */
+ break;
+ }
+}
+
+/*
+ - seterr - set an error condition
+ == static int seterr(register struct parse *p, int e);
+ */
+static int /* useless but makes type checking happy */
+seterr(p, e)
+register struct parse *p;
+int e;
+{
+ if (p->error == 0) /* keep earliest error condition */
+ p->error = e;
+ p->next = nuls; /* try to bring things to a halt */
+ p->end = nuls;
+ return(0); /* make the return value well-defined */
+}
+
+/*
+ - allocset - allocate a set of characters for []
+ == static cset *allocset(register struct parse *p);
+ */
+static cset *
+allocset(p)
+register struct parse *p;
+{
+ register int no = p->g->ncsets++;
+ register size_t nc;
+ register size_t nbytes;
+ register cset *cs;
+ register size_t css = (size_t)p->g->csetsize;
+ register int i;
+
+ if (no >= p->ncsalloc) { /* need another column of space */
+ p->ncsalloc += CHAR_BIT;
+ nc = p->ncsalloc;
+ assert(nc % CHAR_BIT == 0);
+ nbytes = nc / CHAR_BIT * css;
+ if (p->g->sets == NULL)
+ p->g->sets = (cset *)malloc(nc * sizeof(cset));
+ else
+ p->g->sets = (cset *)realloc((char *)p->g->sets,
+ nc * sizeof(cset));
+ if (p->g->setbits == NULL)
+ p->g->setbits = (uch *)malloc(nbytes);
+ else {
+ p->g->setbits = (uch *)realloc((char *)p->g->setbits,
+ nbytes);
+ /* xxx this isn't right if setbits is now NULL */
+ for (i = 0; i < no; i++)
+ p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+ }
+ if (p->g->sets != NULL && p->g->setbits != NULL)
+ (void) memset((char *)p->g->setbits + (nbytes - css),
+ 0, css);
+ else {
+ no = 0;
+ SETERROR(REG_ESPACE);
+ /* caller's responsibility not to do set ops */
+ }
+ }
+
+ assert(p->g->sets != NULL); /* xxx */
+ cs = &p->g->sets[no];
+ cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
+ cs->mask = 1 << ((no) % CHAR_BIT);
+ cs->hash = 0;
+ cs->smultis = 0;
+ cs->multis = NULL;
+
+ return(cs);
+}
+
+/*
+ - freeset - free a now-unused set
+ == static void freeset(register struct parse *p, register cset *cs);
+ */
+static void
+freeset(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ CHsub(cs, i);
+ if (cs == top-1) /* recover only the easy case */
+ p->g->ncsets--;
+}
+
+/*
+ - freezeset - final processing on a set of characters
+ == static int freezeset(register struct parse *p, register cset *cs);
+ *
+ * The main task here is merging identical sets. This is usually a waste
+ * of time (although the hash code minimizes the overhead), but can win
+ * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
+ * is done using addition rather than xor -- all ASCII [aA] sets xor to
+ * the same value!
+ */
+static int /* set number */
+freezeset(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register uch h = cs->hash;
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register cset *cs2;
+ register size_t css = (size_t)p->g->csetsize;
+
+ /* look for an earlier one which is the same */
+ for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
+ if (cs2->hash == h && cs2 != cs) {
+ /* maybe */
+ for (i = 0; i < css; i++)
+ if (!!CHIN(cs2, i) != !!CHIN(cs, i))
+ break; /* no */
+ if (i == css)
+ break; /* yes */
+ }
+
+ if (cs2 < top) { /* found one */
+ freeset(p, cs);
+ cs = cs2;
+ }
+
+ return((int)(cs - p->g->sets));
+}
+
+/*
+ - firstch - return first character in a set (which must have at least one)
+ == static int firstch(register struct parse *p, register cset *cs);
+ */
+static int /* character; there is no "none" value */
+firstch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ return((char)i);
+ assert(never);
+ return(0); /* arbitrary */
+}
+
+/*
+ - nch - number of characters in a set
+ == static int nch(register struct parse *p, register cset *cs);
+ */
+static int
+nch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ register int i;
+ register size_t css = (size_t)p->g->csetsize;
+ register int n = 0;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ n++;
+ return(n);
+}
+
+/*
+ - mcadd - add a collating element to a cset
+ == static void mcadd(register struct parse *p, register cset *cs, \
+ == register char *cp);
+ */
+static void
+mcadd(p, cs, cp)
+register struct parse *p;
+register cset *cs;
+register const char *cp;
+{
+ register size_t oldend = cs->smultis;
+
+ cs->smultis += strlen(cp) + 1;
+ if (cs->multis == NULL)
+ cs->multis = malloc(cs->smultis);
+ else
+ cs->multis = realloc(cs->multis, cs->smultis);
+ if (cs->multis == NULL) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
+ (void) strcpy(cs->multis + oldend - 1, cp);
+ cs->multis[cs->smultis - 1] = '\0';
+}
+
+/*
+ - mcinvert - invert the list of collating elements in a cset
+ == static void mcinvert(register struct parse *p, register cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mcinvert(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - mccase - add case counterparts of the list of collating elements in a cset
+ == static void mccase(register struct parse *p, register cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mccase(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - isinsets - is this character in any sets?
+ == static int isinsets(register struct re_guts *g, int c);
+ */
+static int /* predicate */
+isinsets(g, c)
+register struct re_guts *g;
+int c;
+{
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ register unsigned uc = (unsigned char)c;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc] != 0)
+ return(1);
+ return(0);
+}
+
+/*
+ - samesets - are these two characters in exactly the same sets?
+ == static int samesets(register struct re_guts *g, int c1, int c2);
+ */
+static int /* predicate */
+samesets(g, c1, c2)
+register struct re_guts *g;
+int c1;
+int c2;
+{
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ register unsigned uc1 = (unsigned char)c1;
+ register unsigned uc2 = (unsigned char)c2;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc1] != col[uc2])
+ return(0);
+ return(1);
+}
+
+/*
+ - categorize - sort out character categories
+ == static void categorize(struct parse *p, register struct re_guts *g);
+ */
+static void
+categorize(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register cat_t *cats = g->categories;
+ register int c;
+ register int c2;
+ register cat_t cat;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (cats[c] == 0 && isinsets(g, c)) {
+ cat = g->ncategories++;
+ cats[c] = cat;
+ for (c2 = c+1; c2 <= CHAR_MAX; c2++)
+ if (cats[c2] == 0 && samesets(g, c, c2))
+ cats[c2] = cat;
+ }
+}
+
+/*
+ - dupl - emit a duplicate of a bunch of sops
+ == static sopno dupl(register struct parse *p, sopno start, sopno finish);
+ */
+static sopno /* start of duplicate */
+dupl(p, start, finish)
+register struct parse *p;
+sopno start; /* from here */
+sopno finish; /* to this less one */
+{
+ register sopno ret = HERE();
+ register sopno len = finish - start;
+
+ assert(finish >= start);
+ if (len == 0)
+ return(ret);
+ enlarge(p, p->ssize + len); /* this many unexpected additions */
+ assert(p->ssize >= p->slen + len);
+ (void) memcpy((char *)(p->strip + p->slen),
+ (char *)(p->strip + start), (size_t)len*sizeof(sop));
+ p->slen += len;
+ return(ret);
+}
+
+/*
+ - doemit - emit a strip operator
+ == static void doemit(register struct parse *p, sop op, size_t opnd);
+ *
+ * It might seem better to implement this as a macro with a function as
+ * hard-case backup, but it's just too big and messy unless there are
+ * some changes to the data structures. Maybe later.
+ */
+static void
+doemit(p, op, opnd)
+register struct parse *p;
+sop op;
+size_t opnd;
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* deal with oversize operands ("can't happen", more or less) */
+ assert(opnd < 1<<OPSHIFT);
+
+ /* deal with undersized strip */
+ if (p->slen >= p->ssize)
+ enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */
+ assert(p->slen < p->ssize);
+
+ /* finally, it's all reduced to the easy case */
+ p->strip[p->slen++] = SOP(op, opnd);
+}
+
+/*
+ - doinsert - insert a sop into the strip
+ == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
+ */
+static void
+doinsert(p, op, opnd, pos)
+register struct parse *p;
+sop op;
+size_t opnd;
+sopno pos;
+{
+ register sopno sn;
+ register sop s;
+ register int i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ sn = HERE();
+ EMIT(op, opnd); /* do checks, ensure space */
+ assert(HERE() == sn+1);
+ s = p->strip[sn];
+
+ /* adjust paren pointers */
+ assert(pos > 0);
+ for (i = 1; i < NPAREN; i++) {
+ if (p->pbegin[i] >= pos) {
+ p->pbegin[i]++;
+ }
+ if (p->pend[i] >= pos) {
+ p->pend[i]++;
+ }
+ }
+
+ memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
+ (HERE()-pos-1)*sizeof(sop));
+ p->strip[pos] = s;
+}
+
+/*
+ - dofwd - complete a forward reference
+ == static void dofwd(register struct parse *p, sopno pos, sop value);
+ */
+static void
+dofwd(p, pos, value)
+register struct parse *p;
+register sopno pos;
+sop value;
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ assert(value < 1<<OPSHIFT);
+ p->strip[pos] = OP(p->strip[pos]) | value;
+}
+
+/*
+ - enlarge - enlarge the strip
+ == static void enlarge(register struct parse *p, sopno size);
+ */
+static void
+enlarge(p, size)
+register struct parse *p;
+register sopno size;
+{
+ register sop *sp;
+
+ if (p->ssize >= size)
+ return;
+
+ sp = (sop *)realloc(p->strip, size*sizeof(sop));
+ if (sp == NULL) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+ p->strip = sp;
+ p->ssize = size;
+}
+
+/*
+ - stripsnug - compact the strip
+ == static void stripsnug(register struct parse *p, register struct re_guts *g);
+ */
+static void
+stripsnug(p, g)
+register struct parse *p;
+register struct re_guts *g;
+{
+ g->nstates = p->slen;
+ g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+ if (g->strip == NULL) {
+ SETERROR(REG_ESPACE);
+ g->strip = p->strip;
+ }
+}
+
+/*
+ - findmust - fill in must and mlen with longest mandatory literal string
+ == static void findmust(register struct parse *p, register struct re_guts *g);
+ *
+ * This algorithm could do fancy things like analyzing the operands of |
+ * for common subsequences. Someday. This code is simple and finds most
+ * of the interesting cases.
+ *
+ * Note that must and mlen got initialized during setup.
+ */
+static void
+findmust(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register sop *scan;
+ sop *start = NULL;
+ register sop *newstart = NULL;
+ register sopno newlen;
+ register sop s;
+ register char *cp;
+ register sopno i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* find the longest OCHAR sequence in strip */
+ newlen = 0;
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OCHAR: /* sequence member */
+ if (newlen == 0) /* new sequence */
+ newstart = scan - 1;
+ newlen++;
+ break;
+ case OPLUS_: /* things that don't break one */
+ case OLPAREN:
+ case ORPAREN:
+ break;
+ case OQUEST_: /* things that must be skipped */
+ case OCH_:
+ scan--;
+ do {
+ scan += OPND(s);
+ s = *scan;
+ /* assert() interferes w debug printouts */
+ if (OP(s) != O_QUEST && OP(s) != O_CH &&
+ OP(s) != OOR2) {
+ g->iflags |= BAD;
+ return;
+ }
+ } while (OP(s) != O_QUEST && OP(s) != O_CH);
+ /* fallthrough */
+ default: /* things that break a sequence */
+ if (newlen > g->mlen) { /* ends one */
+ start = newstart;
+ g->mlen = newlen;
+ }
+ newlen = 0;
+ break;
+ }
+ } while (OP(s) != OEND);
+
+ if (g->mlen == 0) /* there isn't one */
+ return;
+
+ /* turn it into a character string */
+ g->must = malloc((size_t)g->mlen + 1);
+ if (g->must == NULL) { /* argh; just forget it */
+ g->mlen = 0;
+ return;
+ }
+ cp = g->must;
+ scan = start;
+ for (i = g->mlen; i > 0; i--) {
+ while (OP(s = *scan++) != OCHAR)
+ continue;
+ assert(cp < g->must + g->mlen);
+ *cp++ = (char)OPND(s);
+ }
+ assert(cp == g->must + g->mlen);
+ *cp++ = '\0'; /* just on general principles */
+}
+
+/*
+ - pluscount - count + nesting
+ == static sopno pluscount(register struct parse *p, register struct re_guts *g);
+ */
+static sopno /* nesting depth */
+pluscount(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+ register sop *scan;
+ register sop s;
+ register sopno plusnest = 0;
+ register sopno maxnest = 0;
+
+ if (p->error != 0)
+ return(0); /* there may not be an OEND */
+
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OPLUS_:
+ plusnest++;
+ break;
+ case O_PLUS:
+ if (plusnest > maxnest)
+ maxnest = plusnest;
+ plusnest--;
+ break;
+ }
+ } while (OP(s) != OEND);
+ if (plusnest != 0)
+ g->iflags |= BAD;
+ return(maxnest);
+}
diff --git a/winsup/cygwin/regex/regcomp.ih b/winsup/cygwin/regex/regcomp.ih
new file mode 100644
index 000000000..e16d5ab2f
--- /dev/null
+++ b/winsup/cygwin/regex/regcomp.ih
@@ -0,0 +1,48 @@
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === regcomp.c === */
+static void p_ere(register struct parse *p, int stop);
+static void p_ere_exp(register struct parse *p);
+static void p_str(register struct parse *p);
+static void p_bre(register struct parse *p, register int end1, register int end2);
+static int p_simp_re(register struct parse *p, int starordinary);
+static int p_count(register struct parse *p);
+static void p_bracket(register struct parse *p);
+static void p_b_term(register struct parse *p, register cset *cs);
+static void p_b_cclass(register struct parse *p, register cset *cs);
+static void p_b_eclass(register struct parse *p, register cset *cs);
+static char p_b_symbol(register struct parse *p);
+static char p_b_coll_elem(register struct parse *p, int endc);
+static char othercase(int ch);
+static void bothcases(register struct parse *p, int ch);
+static void ordinary(register struct parse *p, register int ch);
+static void nonnewline(register struct parse *p);
+static void repeat(register struct parse *p, sopno start, int from, int to);
+static int seterr(register struct parse *p, int e);
+static cset *allocset(register struct parse *p);
+static void freeset(register struct parse *p, register cset *cs);
+static int freezeset(register struct parse *p, register cset *cs);
+static int firstch(register struct parse *p, register cset *cs);
+static int nch(register struct parse *p, register cset *cs);
+static void mcadd(register struct parse *p, register cset *cs, register const char *cp);
+static void mcinvert(register struct parse *p, register cset *cs);
+static void mccase(register struct parse *p, register cset *cs);
+static int isinsets(register struct re_guts *g, int c);
+static int samesets(register struct re_guts *g, int c1, int c2);
+static void categorize(struct parse *p, register struct re_guts *g);
+static sopno dupl(register struct parse *p, sopno start, sopno finish);
+static void doemit(register struct parse *p, sop op, size_t opnd);
+static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
+static void dofwd(register struct parse *p, sopno pos, sop value);
+static void enlarge(register struct parse *p, sopno size);
+static void stripsnug(register struct parse *p, register struct re_guts *g);
+static void findmust(register struct parse *p, register struct re_guts *g);
+static sopno pluscount(register struct parse *p, register struct re_guts *g);
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
diff --git a/winsup/cygwin/regex/regerror.c b/winsup/cygwin/regex/regerror.c
new file mode 100644
index 000000000..4d14ab231
--- /dev/null
+++ b/winsup/cygwin/regex/regerror.c
@@ -0,0 +1,127 @@
+#include "winsup.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "regex.h"
+
+#include "utils.h"
+#include "regerror.ih"
+
+/*
+ = #define REG_OKAY 0
+ = #define REG_NOMATCH 1
+ = #define REG_BADPAT 2
+ = #define REG_ECOLLATE 3
+ = #define REG_ECTYPE 4
+ = #define REG_EESCAPE 5
+ = #define REG_ESUBREG 6
+ = #define REG_EBRACK 7
+ = #define REG_EPAREN 8
+ = #define REG_EBRACE 9
+ = #define REG_BADBR 10
+ = #define REG_ERANGE 11
+ = #define REG_ESPACE 12
+ = #define REG_BADRPT 13
+ = #define REG_EMPTY 14
+ = #define REG_ASSERT 15
+ = #define REG_INVARG 16
+ = #define REG_ATOI 255 // convert name to number (!)
+ = #define REG_ITOA 0400 // convert number to name (!)
+ */
+static struct rerr {
+ int code;
+ const char *name;
+ const char *explain;
+} rerrs[] = {
+ {REG_OKAY, "REG_OKAY", "no errors detected"},
+ {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
+ {REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
+ {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
+ {REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
+ {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
+ {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
+ {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
+ {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
+ {REG_EBRACE, "REG_EBRACE", "braces not balanced"},
+ {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
+ {REG_ERANGE, "REG_ERANGE", "invalid character range"},
+ {REG_ESPACE, "REG_ESPACE", "out of memory"},
+ {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
+ {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
+ {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
+ {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
+ {-1, "", "*** unknown regexp error code ***"},
+};
+
+/*
+ - regerror - the interface to error numbers
+ = extern size_t regerror(int, const regex_t *, char *, size_t);
+ */
+/* ARGSUSED */
+size_t
+regerror(errcode, preg, errbuf, errbuf_size)
+int errcode;
+const regex_t *preg;
+char *errbuf;
+size_t errbuf_size;
+{
+ register struct rerr *r;
+ register size_t len;
+ register int target = errcode &~ REG_ITOA;
+ register const char *s;
+ char convbuf[50];
+
+ if (errcode == REG_ATOI)
+ s = regatoi(preg, convbuf);
+ else {
+ for (r = rerrs; r->code >= 0; r++)
+ if (r->code == target)
+ break;
+
+ if (errcode&REG_ITOA) {
+ if (r->code >= 0)
+ (void) strcpy(convbuf, r->name);
+ else
+ sprintf(convbuf, "REG_0x%x", target);
+ assert(strlen(convbuf) < sizeof(convbuf));
+ s = convbuf;
+ } else
+ s = r->explain;
+ }
+
+ len = strlen(s) + 1;
+ if (errbuf_size > 0) {
+ if (errbuf_size > len)
+ (void) strcpy(errbuf, s);
+ else {
+ (void) strncpy(errbuf, s, errbuf_size-1);
+ errbuf[errbuf_size-1] = '\0';
+ }
+ }
+
+ return(len);
+}
+
+/*
+ - regatoi - internal routine to implement REG_ATOI
+ == static char *regatoi(const regex_t *preg, char *localbuf);
+ */
+static const char *
+regatoi(preg, localbuf)
+const regex_t *preg;
+char *localbuf;
+{
+ register struct rerr *r;
+
+ for (r = rerrs; r->code >= 0; r++)
+ if (strcmp(r->name, preg->re_endp) == 0)
+ break;
+ if (r->code < 0)
+ return("0");
+
+ sprintf(localbuf, "%d", r->code);
+ return(localbuf);
+}
diff --git a/winsup/cygwin/regex/regerror.ih b/winsup/cygwin/regex/regerror.ih
new file mode 100644
index 000000000..d428544e3
--- /dev/null
+++ b/winsup/cygwin/regex/regerror.ih
@@ -0,0 +1,12 @@
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === regerror.c === */
+static const char *regatoi(const regex_t *preg, char *localbuf);
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
diff --git a/winsup/cygwin/regex/regex.3 b/winsup/cygwin/regex/regex.3
new file mode 100644
index 000000000..bc747096d
--- /dev/null
+++ b/winsup/cygwin/regex/regex.3
@@ -0,0 +1,509 @@
+.TH REGEX 3 "25 Sept 1997"
+.BY "Henry Spencer"
+.de ZR
+.\" one other place knows this name: the SEE ALSO section
+.IR regex (7) \\$1
+..
+.SH NAME
+regcomp, regexec, regerror, regfree \- regular-expression library
+.SH SYNOPSIS
+.ft B
+.\".na
+#include <sys/types.h>
+.br
+#include <regex.h>
+.HP 10
+int regcomp(regex_t\ *preg, const\ char\ *pattern, int\ cflags);
+.HP
+int\ regexec(const\ regex_t\ *preg, const\ char\ *string,
+size_t\ nmatch, regmatch_t\ pmatch[], int\ eflags);
+.HP
+size_t\ regerror(int\ errcode, const\ regex_t\ *preg,
+char\ *errbuf, size_t\ errbuf_size);
+.HP
+void\ regfree(regex_t\ *preg);
+.\".ad
+.ft
+.SH DESCRIPTION
+These routines implement POSIX 1003.2 regular expressions (``RE''s);
+see
+.ZR .
+.I Regcomp
+compiles an RE written as a string into an internal form,
+.I regexec
+matches that internal form against a string and reports results,
+.I regerror
+transforms error codes from either into human-readable messages,
+and
+.I regfree
+frees any dynamically-allocated storage used by the internal form
+of an RE.
+.PP
+The header
+.I <regex.h>
+declares two structure types,
+.I regex_t
+and
+.IR regmatch_t ,
+the former for compiled internal forms and the latter for match reporting.
+It also declares the four functions,
+a type
+.IR regoff_t ,
+and a number of constants with names starting with ``REG_''.
+.PP
+.I Regcomp
+compiles the regular expression contained in the
+.I pattern
+string,
+subject to the flags in
+.IR cflags ,
+and places the results in the
+.I regex_t
+structure pointed to by
+.IR preg .
+.I Cflags
+is the bitwise OR of zero or more of the following flags:
+.IP REG_EXTENDED \w'REG_EXTENDED'u+2n
+Compile modern (``extended'') REs,
+rather than the obsolete (``basic'') REs that
+are the default.
+.IP REG_BASIC
+This is a synonym for 0,
+provided as a counterpart to REG_EXTENDED to improve readability.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.IP REG_NOSPEC
+Compile with recognition of all special characters turned off.
+All characters are thus considered ordinary,
+so the ``RE'' is a literal string.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+REG_EXTENDED and REG_NOSPEC may not be used
+in the same call to
+.IR regcomp .
+.IP REG_ICASE
+Compile for matching that ignores upper/lower case distinctions.
+See
+.ZR .
+.IP REG_NOSUB
+Compile for matching that need only report success or failure,
+not what was matched.
+.IP REG_NEWLINE
+Compile for newline-sensitive matching.
+By default, newline is a completely ordinary character with no special
+meaning in either REs or strings.
+With this flag,
+`[^' bracket expressions and `.' never match newline,
+a `^' anchor matches the null string after any newline in the string
+in addition to its normal function,
+and the `$' anchor matches the null string before any newline in the
+string in addition to its normal function.
+.IP REG_PEND
+The regular expression ends,
+not at the first NUL,
+but just before the character pointed to by the
+.I re_endp
+member of the structure pointed to by
+.IR preg .
+The
+.I re_endp
+member is of type
+.IR const\ char\ * .
+This flag permits inclusion of NULs in the RE;
+they are considered ordinary characters.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+When successful,
+.I regcomp
+returns 0 and fills in the structure pointed to by
+.IR preg .
+One member of that structure
+(other than
+.IR re_endp )
+is publicized:
+.IR re_nsub ,
+of type
+.IR size_t ,
+contains the number of parenthesized subexpressions within the RE
+(except that the value of this member is undefined if the
+REG_NOSUB flag was used).
+If
+.I regcomp
+fails, it returns a non-zero error code;
+see DIAGNOSTICS.
+.PP
+.I Regexec
+matches the compiled RE pointed to by
+.I preg
+against the
+.IR string ,
+subject to the flags in
+.IR eflags ,
+and reports results using
+.IR nmatch ,
+.IR pmatch ,
+and the returned value.
+The RE must have been compiled by a previous invocation of
+.IR regcomp .
+The compiled form is not altered during execution of
+.IR regexec ,
+so a single compiled RE can be used simultaneously by multiple threads.
+.PP
+By default,
+the NUL-terminated string pointed to by
+.I string
+is considered to be the text of an entire line,
+with the NUL indicating the end of the line.
+(That is,
+any other end-of-line marker is considered to have been removed
+and replaced by the NUL.)
+The
+.I eflags
+argument is the bitwise OR of zero or more of the following flags:
+.IP REG_NOTBOL \w'REG_STARTEND'u+2n
+The first character of
+the string
+is not the beginning of a line, so the `^' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_NOTEOL
+The NUL terminating
+the string
+does not end a line, so the `$' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_STARTEND
+The string is considered to start at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_so\fR
+and to have a terminating NUL located at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_eo\fR
+(there need not actually be a NUL at that location),
+regardless of the value of
+.IR nmatch .
+See below for the definition of
+.IR pmatch
+and
+.IR nmatch .
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Note that a non-zero \fIrm_so\fR does not imply REG_NOTBOL;
+REG_STARTEND affects only the location of the string,
+not how it is matched.
+.PP
+See
+.ZR
+for a discussion of what is matched in situations where an RE or a
+portion thereof could match any of several substrings of
+.IR string .
+.PP
+Normally,
+.I regexec
+returns 0 for success and the non-zero code REG_NOMATCH for failure.
+Other non-zero error codes may be returned in exceptional situations;
+see DIAGNOSTICS.
+.PP
+If REG_NOSUB was specified in the compilation of the RE,
+or if
+.I nmatch
+is 0,
+.I regexec
+ignores the
+.I pmatch
+argument (but see below for the case where REG_STARTEND is specified).
+Otherwise,
+.I pmatch
+points to an array of
+.I nmatch
+structures of type
+.IR regmatch_t .
+Such a structure has at least the members
+.I rm_so
+and
+.IR rm_eo ,
+both of type
+.I regoff_t
+(a signed arithmetic type at least as large as an
+.I off_t
+and a
+.IR ssize_t ),
+containing respectively the offset of the first character of a substring
+and the offset of the first character after the end of the substring.
+Offsets are measured from the beginning of the
+.I string
+argument given to
+.IR regexec .
+An empty substring is denoted by equal offsets,
+both indicating the character following the empty substring.
+.PP
+The 0th member of the
+.I pmatch
+array is filled in to indicate what substring of
+.I string
+was matched by the entire RE.
+Remaining members report what substring was matched by parenthesized
+subexpressions within the RE;
+member
+.I i
+reports subexpression
+.IR i ,
+with subexpressions counted (starting at 1) by the order of their opening
+parentheses in the RE, left to right.
+Unused entries in the array\(emcorresponding either to subexpressions that
+did not participate in the match at all, or to subexpressions that do not
+exist in the RE (that is, \fIi\fR\ > \fIpreg\fR\->\fIre_nsub\fR)\(emhave both
+.I rm_so
+and
+.I rm_eo
+set to \-1.
+If a subexpression participated in the match several times,
+the reported substring is the last one it matched.
+(Note, as an example in particular, that when the RE `(b*)+' matches `bbb',
+the parenthesized subexpression matches the three `b's and then
+an infinite number of empty strings following the last `b',
+so the reported substring is one of the empties.)
+.PP
+If REG_STARTEND is specified,
+.I pmatch
+must point to at least one
+.I regmatch_t
+(even if
+.I nmatch
+is 0 or REG_NOSUB was specified),
+to hold the input offsets for REG_STARTEND.
+Use for output is still entirely controlled by
+.IR nmatch ;
+if
+.I nmatch
+is 0 or REG_NOSUB was specified,
+the value of
+.IR pmatch [0]
+will not be changed by a successful
+.IR regexec .
+.PP
+.I Regerror
+maps a non-zero
+.I errcode
+from either
+.I regcomp
+or
+.I regexec
+to a human-readable, printable message.
+If
+.I preg
+is non-NULL,
+the error code should have arisen from use of
+the
+.I regex_t
+pointed to by
+.IR preg ,
+and if the error code came from
+.IR regcomp ,
+it should have been the result from the most recent
+.I regcomp
+using that
+.IR regex_t .
+.RI ( Regerror
+may be able to supply a more detailed message using information
+from the
+.IR regex_t .)
+.I Regerror
+places the NUL-terminated message into the buffer pointed to by
+.IR errbuf ,
+limiting the length (including the NUL) to at most
+.I errbuf_size
+bytes.
+If the whole message won't fit,
+as much of it as will fit before the terminating NUL is supplied.
+In any case,
+the returned value is the size of buffer needed to hold the whole
+message (including terminating NUL).
+If
+.I errbuf_size
+is 0,
+.I errbuf
+is ignored but the return value is still correct.
+.PP
+If the
+.I errcode
+given to
+.I regerror
+is first ORed with REG_ITOA,
+the ``message'' that results is the printable name of the error code,
+e.g. ``REG_NOMATCH'',
+rather than an explanation thereof.
+If
+.I errcode
+is REG_ATOI,
+then
+.I preg
+shall be non-NULL and the
+.I re_endp
+member of the structure it points to
+must point to the printable name of an error code;
+in this case, the result in
+.I errbuf
+is the decimal digits of
+the numeric value of the error code
+(0 if the name is not recognized).
+REG_ITOA and REG_ATOI are intended primarily as debugging facilities;
+they are extensions,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Be warned also that they are considered experimental and changes are possible.
+.PP
+.I Regfree
+frees any dynamically-allocated storage associated with the compiled RE
+pointed to by
+.IR preg .
+The remaining
+.I regex_t
+is no longer a valid compiled RE
+and the effect of supplying it to
+.I regexec
+or
+.I regerror
+is undefined.
+.PP
+None of these functions references global variables except for tables
+of constants;
+all are safe for use from multiple threads if the arguments are safe.
+.SH IMPLEMENTATION CHOICES
+There are a number of decisions that 1003.2 leaves up to the implementor,
+either by explicitly saying ``undefined'' or by virtue of them being
+forbidden by the RE grammar.
+This implementation treats them as follows.
+.PP
+See
+.ZR
+for a discussion of the definition of case-independent matching.
+.PP
+There is no particular limit on the length of REs,
+except insofar as memory is limited.
+Memory usage is approximately linear in RE size, and largely insensitive
+to RE complexity, except for bounded repetitions.
+See BUGS for one short RE using them
+that will run almost any system out of memory.
+.PP
+A backslashed character other than one specifically given a magic meaning
+by 1003.2 (such magic meanings occur only in obsolete [``basic''] REs)
+is taken as an ordinary character.
+.PP
+Any unmatched [ is a REG_EBRACK error.
+.PP
+Equivalence classes cannot begin or end bracket-expression ranges.
+The endpoint of one range cannot begin another.
+.PP
+RE_DUP_MAX, the limit on repetition counts in bounded repetitions, is 255.
+.PP
+A repetition operator (?, *, +, or bounds) cannot follow another
+repetition operator.
+A repetition operator cannot begin an expression or subexpression
+or follow `^' or `|'.
+.PP
+`|' cannot appear first or last in a (sub)expression or after another `|',
+i.e. an operand of `|' cannot be an empty subexpression.
+An empty parenthesized subexpression, `()', is legal and matches an
+empty (sub)string.
+An empty string is not a legal RE.
+.PP
+A `{' followed by a digit is considered the beginning of bounds for a
+bounded repetition, which must then follow the syntax for bounds.
+A `{' \fInot\fR followed by a digit is considered an ordinary character.
+.PP
+`^' and `$' beginning and ending subexpressions in obsolete (``basic'')
+REs are anchors, not ordinary characters.
+.SH SEE ALSO
+grep(1), regex(7)
+.PP
+POSIX 1003.2, sections 2.8 (Regular Expression Notation)
+and
+B.5 (C Binding for Regular Expression Matching).
+.SH DIAGNOSTICS
+Non-zero error codes from
+.I regcomp
+and
+.I regexec
+include the following:
+.PP
+.nf
+.ta \w'REG_ECOLLATE'u+3n
+REG_NOMATCH regexec() failed to match
+REG_BADPAT invalid regular expression
+REG_ECOLLATE invalid collating element
+REG_ECTYPE invalid character class
+REG_EESCAPE \e applied to unescapable character
+REG_ESUBREG invalid backreference number
+REG_EBRACK brackets [ ] not balanced
+REG_EPAREN parentheses ( ) not balanced
+REG_EBRACE braces { } not balanced
+REG_BADBR invalid repetition count(s) in { }
+REG_ERANGE invalid character range in [ ]
+REG_ESPACE ran out of memory
+REG_BADRPT ?, *, or + operand invalid
+REG_EMPTY empty (sub)expression
+REG_ASSERT ``can't happen''\(emyou found a bug
+REG_INVARG invalid argument, e.g. negative-length string
+.fi
+.SH HISTORY
+Written by Henry Spencer,
+henry@zoo.toronto.edu.
+.SH BUGS
+This is an alpha release with known defects.
+Please report problems.
+.PP
+There is one known functionality bug.
+The implementation of internationalization is incomplete:
+the locale is always assumed to be the default one of 1003.2,
+and only the collating elements etc. of that locale are available.
+.PP
+The back-reference code is subtle and doubts linger about its correctness
+in complex cases.
+.PP
+.I Regexec
+performance is poor.
+This will improve with later releases.
+.I Nmatch
+exceeding 0 is expensive;
+.I nmatch
+exceeding 1 is worse.
+.I Regexec
+is largely insensitive to RE complexity \fIexcept\fR that back
+references are massively expensive.
+RE length does matter; in particular, there is a strong speed bonus
+for keeping RE length under about 30 characters,
+with most special characters counting roughly double.
+.PP
+.I Regcomp
+implements bounded repetitions by macro expansion,
+which is costly in time and space if counts are large
+or bounded repetitions are nested.
+An RE like, say,
+`((((a{1,100}){1,100}){1,100}){1,100}){1,100}'
+will (eventually) run almost any existing machine out of swap space.
+.PP
+There are suspected problems with response to obscure error conditions.
+Notably,
+certain kinds of internal overflow,
+produced only by truly enormous REs or by multiply nested bounded repetitions,
+are probably not handled well.
+.PP
+Due to a mistake in 1003.2, things like `a)b' are legal REs because `)' is
+a special character only in the presence of a previous unmatched `('.
+This can't be fixed until the spec is fixed.
+.PP
+The standard's definition of back references is vague.
+For example, does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?
+Until the standard is clarified,
+behavior in such cases should not be relied on.
+.PP
+The implementation of word-boundary matching is a bit of a kludge,
+and bugs may lurk in combinations of word-boundary matching and anchoring.
diff --git a/winsup/cygwin/regex/regex.7 b/winsup/cygwin/regex/regex.7
new file mode 100644
index 000000000..0fa180269
--- /dev/null
+++ b/winsup/cygwin/regex/regex.7
@@ -0,0 +1,235 @@
+.TH REGEX 7 "25 Oct 1995"
+.BY "Henry Spencer"
+.SH NAME
+regex \- POSIX 1003.2 regular expressions
+.SH DESCRIPTION
+Regular expressions (``RE''s),
+as defined in POSIX 1003.2, come in two forms:
+modern REs (roughly those of
+.IR egrep ;
+1003.2 calls these ``extended'' REs)
+and obsolete REs (roughly those of
+.IR ed ;
+1003.2 ``basic'' REs).
+Obsolete REs mostly exist for backward compatibility in some old programs;
+they will be discussed at the end.
+1003.2 leaves some aspects of RE syntax and semantics open;
+`\(dg' marks decisions on these aspects that
+may not be fully portable to other 1003.2 implementations.
+.PP
+A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR,
+separated by `|'.
+It matches anything that matches one of the branches.
+.PP
+A branch is one\(dg or more \fIpieces\fR, concatenated.
+It matches a match for the first, followed by a match for the second, etc.
+.PP
+A piece is an \fIatom\fR possibly followed
+by a single\(dg `*', `+', `?', or \fIbound\fR.
+An atom followed by `*' matches a sequence of 0 or more matches of the atom.
+An atom followed by `+' matches a sequence of 1 or more matches of the atom.
+An atom followed by `?' matches a sequence of 0 or 1 matches of the atom.
+.PP
+A \fIbound\fR is `{' followed by an unsigned decimal integer,
+possibly followed by `,'
+possibly followed by another unsigned decimal integer,
+always followed by `}'.
+The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive,
+and if there are two of them, the first may not exceed the second.
+An atom followed by a bound containing one integer \fIi\fR
+and no comma matches
+a sequence of exactly \fIi\fR matches of the atom.
+An atom followed by a bound
+containing one integer \fIi\fR and a comma matches
+a sequence of \fIi\fR or more matches of the atom.
+An atom followed by a bound
+containing two integers \fIi\fR and \fIj\fR matches
+a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom.
+.PP
+An atom is a regular expression enclosed in `()' (matching a match for the
+regular expression),
+an empty set of `()' (matching the null string)\(dg,
+a \fIbracket expression\fR (see below), `.'
+(matching any single character), `^' (matching the null string at the
+beginning of a line), `$' (matching the null string at the
+end of a line), a `\e' followed by one of the characters
+`^.[$()|*+?{\e'
+(matching that character taken as an ordinary character),
+a `\e' followed by any other character\(dg
+(matching that character taken as an ordinary character,
+as if the `\e' had not been present\(dg),
+or a single character with no other significance (matching that character).
+A `{' followed by a character other than a digit is an ordinary
+character, not the beginning of a bound\(dg.
+It is illegal to end an RE with `\e'.
+.PP
+A \fIbracket expression\fR is a list of characters enclosed in `[]'.
+It normally matches any single character from the list (but see below).
+If the list begins with `^',
+it matches any single character
+(but see below) \fInot\fR from the rest of the list.
+If two characters in the list are separated by `\-', this is shorthand
+for the full \fIrange\fR of characters between those two (inclusive) in the
+collating sequence,
+e.g. `[0\-9]' in ASCII matches any decimal digit.
+It is illegal\(dg for two ranges to share an
+endpoint, e.g. `a\-c\-e'.
+Ranges are very collating-sequence-dependent,
+and portable programs should avoid relying on them.
+.PP
+To include a literal `]' in the list, make it the first character
+(following a possible `^').
+To include a literal `\-', make it the first or last character,
+or the second endpoint of a range.
+To use a literal `\-' as the first endpoint of a range,
+enclose it in `[.' and `.]' to make it a collating element (see below).
+With the exception of these and some combinations using `[' (see next
+paragraphs), all other special characters, including `\e', lose their
+special significance within a bracket expression.
+.PP
+Within a bracket expression, a collating element (a character,
+a multi-character sequence that collates as if it were a single character,
+or a collating-sequence name for either)
+enclosed in `[.' and `.]' stands for the
+sequence of characters of that collating element.
+The sequence is a single element of the bracket expression's list.
+A bracket expression containing a multi-character collating element
+can thus match more than one character,
+e.g. if the collating sequence includes a `ch' collating element,
+then the RE `[[.ch.]]*c' matches the first five characters
+of `chchcc'.
+.PP
+Within a bracket expression, a collating element enclosed in `[=' and
+`=]' is an equivalence class, standing for the sequences of characters
+of all collating elements equivalent to that one, including itself.
+(If there are no other equivalent collating elements,
+the treatment is as if the enclosing delimiters were `[.' and `.]'.)
+For example, if o and \o'o^' are the members of an equivalence class,
+then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous.
+An equivalence class may not\(dg be an endpoint
+of a range.
+.PP
+Within a bracket expression, the name of a \fIcharacter class\fR enclosed
+in `[:' and `:]' stands for the list of all characters belonging to that
+class.
+Standard character class names are:
+.PP
+.RS
+.nf
+.ta 3c 6c 9c
+alnum digit punct
+alpha graph space
+blank lower upper
+cntrl print xdigit
+.fi
+.RE
+.PP
+These stand for the character classes defined in
+.IR ctype (3).
+A locale may provide others.
+A character class may not be used as an endpoint of a range.
+.PP
+There are two special cases\(dg of bracket expressions:
+the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at
+the beginning and end of a word respectively.
+A word is defined as a sequence of
+word characters
+which is neither preceded nor followed by
+word characters.
+A word character is an
+.I alnum
+character (as defined by
+.IR ctype (3))
+or an underscore.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+In the event that an RE could match more than one substring of a given
+string,
+the RE matches the one starting earliest in the string.
+If the RE could match more than one substring starting at that point,
+it matches the longest.
+Subexpressions also match the longest possible substrings, subject to
+the constraint that the whole match be as long as possible,
+with subexpressions starting earlier in the RE taking priority over
+ones starting later.
+Note that higher-level subexpressions thus take priority over
+their lower-level component subexpressions.
+.PP
+Match lengths are measured in characters, not collating elements.
+A null string is considered longer than no match at all.
+For example,
+`bb*' matches the three middle characters of `abbbc',
+`(wee|week)(knights|nights)' matches all ten characters of `weeknights',
+when `(.*).*' is matched against `abc' the parenthesized subexpression
+matches all three characters, and
+when `(a*)*' is matched against `bc' both the whole RE and the parenthesized
+subexpression match the null string.
+.PP
+If case-independent matching is specified,
+the effect is much as if all case distinctions had vanished from the
+alphabet.
+When an alphabetic that exists in multiple cases appears as an
+ordinary character outside a bracket expression, it is effectively
+transformed into a bracket expression containing both cases,
+e.g. `x' becomes `[xX]'.
+When it appears inside a bracket expression, all case counterparts
+of it are added to the bracket expression, so that (e.g.) `[x]'
+becomes `[xX]' and `[^x]' becomes `[^xX]'.
+.PP
+No particular limit is imposed on the length of REs\(dg.
+Programs intended to be portable should not employ REs longer
+than 256 bytes,
+as an implementation can refuse to accept such REs and remain
+POSIX-compliant.
+.PP
+Obsolete (``basic'') regular expressions differ in several respects.
+`|', `+', and `?' are ordinary characters and there is no equivalent
+for their functionality.
+The delimiters for bounds are `\e{' and `\e}',
+with `{' and `}' by themselves ordinary characters.
+The parentheses for nested subexpressions are `\e(' and `\e)',
+with `(' and `)' by themselves ordinary characters.
+`^' is an ordinary character except at the beginning of the
+RE or\(dg the beginning of a parenthesized subexpression,
+`$' is an ordinary character except at the end of the
+RE or\(dg the end of a parenthesized subexpression,
+and `*' is an ordinary character if it appears at the beginning of the
+RE or the beginning of a parenthesized subexpression
+(after a possible leading `^').
+Finally, there is one new type of atom, a \fIback reference\fR:
+`\e' followed by a non-zero decimal digit \fId\fR
+matches the same sequence of characters
+matched by the \fId\fRth parenthesized subexpression
+(numbering subexpressions by the positions of their opening parentheses,
+left to right),
+so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'.
+.SH SEE ALSO
+regex(3)
+.PP
+POSIX 1003.2, section 2.8 (Regular Expression Notation).
+.SH HISTORY
+Written by Henry Spencer, based on the 1003.2 spec.
+.SH BUGS
+Having two kinds of REs is a botch.
+.PP
+The current 1003.2 spec says that `)' is an ordinary character in
+the absence of an unmatched `(';
+this was an unintentional result of a wording error,
+and change is likely.
+Avoid relying on it.
+.PP
+Back references are a dreadful botch,
+posing major problems for efficient implementations.
+They are also somewhat vaguely defined
+(does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?).
+Avoid using them.
+.PP
+1003.2's specification of case-independent matching is vague.
+The ``one case implies all cases'' definition given above
+is current consensus among implementors as to the right interpretation.
+.PP
+The syntax for word boundaries is incredibly ugly.
diff --git a/winsup/cygwin/regex/regex.h b/winsup/cygwin/regex/regex.h
new file mode 100644
index 000000000..0ef0ace36
--- /dev/null
+++ b/winsup/cygwin/regex/regex.h
@@ -0,0 +1,83 @@
+#ifndef _REGEX_H_
+#define _REGEX_H_ /* never again */
+#include <sys/types.h>
+/* ========= begin header generated by ./mkh ========= */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __INSIDE_CYGWIN__
+#define regcomp posix_regcomp
+#define regerror posix_regerror
+#define regexec posix_regexec
+#define regfree posix_regfree
+#endif
+
+/* === regex2.h === */
+typedef off_t regoff_t;
+typedef struct {
+ int re_magic;
+ size_t re_nsub; /* number of parenthesized subexpressions */
+ const char *re_endp; /* end pointer for REG_PEND */
+ struct re_guts *re_g; /* none of your business :-) */
+} regex_t;
+typedef struct {
+ regoff_t rm_so; /* start of match */
+ regoff_t rm_eo; /* end of match */
+} regmatch_t;
+
+
+/* === regcomp.c === */
+extern int regcomp(regex_t *, const char *, int);
+#define REG_BASIC 0000
+#define REG_EXTENDED 0001
+#define REG_ICASE 0002
+#define REG_NOSUB 0004
+#define REG_NEWLINE 0010
+#define REG_NOSPEC 0020
+#define REG_PEND 0040
+#define REG_DUMP 0200
+
+
+/* === regerror.c === */
+#define REG_OKAY 0
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+#define REG_EMPTY 14
+#define REG_ASSERT 15
+#define REG_INVARG 16
+#define REG_ATOI 255 /* convert name to number (!) */
+#define REG_ITOA 0400 /* convert number to name (!) */
+extern size_t regerror(int, const regex_t *, char *, size_t);
+
+
+/* === regexec.c === */
+extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
+#define REG_NOTBOL 00001
+#define REG_NOTEOL 00002
+#define REG_STARTEND 00004
+#define REG_TRACE 00400 /* tracing of execution */
+#define REG_LARGE 01000 /* force large representation */
+#define REG_BACKR 02000 /* force use of backref code */
+
+
+/* === regfree.c === */
+extern void regfree(regex_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+/* ========= end header generated by ./mkh ========= */
+#endif
diff --git a/winsup/cygwin/regex/regex2.h b/winsup/cygwin/regex/regex2.h
new file mode 100644
index 000000000..58fd8d8a4
--- /dev/null
+++ b/winsup/cygwin/regex/regex2.h
@@ -0,0 +1,134 @@
+/*
+ * First, the stuff that ends up in the outside-world include file
+ = typedef off_t regoff_t;
+ = typedef struct {
+ = int re_magic;
+ = size_t re_nsub; // number of parenthesized subexpressions
+ = const char *re_endp; // end pointer for REG_PEND
+ = struct re_guts *re_g; // none of your business :-)
+ = } regex_t;
+ = typedef struct {
+ = regoff_t rm_so; // start of match
+ = regoff_t rm_eo; // end of match
+ = } regmatch_t;
+ */
+/*
+ * internals of regex_t
+ */
+#define MAGIC1 ((('r'^0200)<<8) | 'e')
+
+/*
+ * The internal representation is a *strip*, a sequence of
+ * operators ending with an endmarker. (Some terminology etc. is a
+ * historical relic of earlier versions which used multiple strips.)
+ * Certain oddities in the representation are there to permit running
+ * the machinery backwards; in particular, any deviation from sequential
+ * flow must be marked at both its source and its destination. Some
+ * fine points:
+ *
+ * - OPLUS_ and O_PLUS are *inside* the loop they create.
+ * - OQUEST_ and O_QUEST are *outside* the bypass they create.
+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while
+ * OOR1 and OOR2 are respectively the end and the beginning of one of
+ * the branches. Note that there is an implicit OOR2 following OCH_
+ * and an implicit OOR1 preceding O_CH.
+ *
+ * In state representations, an operator's bit is on to signify a state
+ * immediately *preceding* "execution" of that operator.
+ */
+typedef long sop; /* strip operator */
+typedef long sopno;
+#define OPRMASK 0x7c000000
+#define OPDMASK 0x03ffffff
+#define OPSHIFT (26)
+#define OP(n) ((n)&OPRMASK)
+#define OPND(n) ((n)&OPDMASK)
+#define SOP(op, opnd) ((op)|(opnd))
+/* operators meaning operand */
+/* (back, fwd are offsets) */
+#define OEND (1<<OPSHIFT) /* endmarker - */
+#define OCHAR (2<<OPSHIFT) /* character unsigned char */
+#define OBOL (3<<OPSHIFT) /* left anchor - */
+#define OEOL (4<<OPSHIFT) /* right anchor - */
+#define OANY (5<<OPSHIFT) /* . - */
+#define OANYOF (6<<OPSHIFT) /* [...] set number */
+#define OBACK_ (7<<OPSHIFT) /* begin \d paren number */
+#define O_BACK (8<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ (9<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS (10<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ (11<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST (12<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN (13<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN (14<<OPSHIFT) /* ) back to ( */
+#define OCH_ (15<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 (16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
+#define OOR2 (17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
+#define O_CH (18<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW (19<<OPSHIFT) /* begin word - */
+#define OEOW (20<<OPSHIFT) /* end word - */
+
+/*
+ * Structure for [] character-set representation. Character sets are
+ * done as bit vectors, grouped 8 to a byte vector for compactness.
+ * The individual set therefore has both a pointer to the byte vector
+ * and a mask to pick out the relevant bit of each byte. A hash code
+ * simplifies testing whether two sets could be identical.
+ *
+ * This will get trickier for multicharacter collating elements. As
+ * preliminary hooks for dealing with such things, we also carry along
+ * a string of multi-character elements, and decide the size of the
+ * vectors at run time.
+ */
+typedef struct {
+ uch *ptr; /* -> uch [csetsize] */
+ uch mask; /* bit within array */
+ uch hash; /* hash code */
+ size_t smultis;
+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
+} cset;
+/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
+#define MCsub(p, cs, cp) mcsub(p, cs, cp)
+#define MCin(p, cs, cp) mcin(p, cs, cp)
+
+/* stuff for character categories */
+typedef unsigned char cat_t;
+
+/*
+ * main compiled-expression structure
+ */
+struct re_guts {
+ int magic;
+# define MAGIC2 ((('R'^0200)<<8)|'E')
+ sop *strip; /* malloced area for strip */
+ int csetsize; /* number of bits in a cset vector */
+ int ncsets; /* number of csets in use */
+ cset *sets; /* -> cset [ncsets] */
+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
+ int cflags; /* copy of regcomp() cflags argument */
+ sopno nstates; /* = number of sops */
+ sopno firststate; /* the initial OEND (normally 0) */
+ sopno laststate; /* the final OEND */
+ int iflags; /* internal flags */
+# define USEBOL 01 /* used ^ */
+# define USEEOL 02 /* used $ */
+# define BAD 04 /* something wrong */
+ int nbol; /* number of ^ used */
+ int neol; /* number of $ used */
+ int ncategories; /* how many character categories */
+ cat_t *categories; /* ->catspace[-CHAR_MIN] */
+ char *must; /* match must contain this string */
+ int mlen; /* length of must */
+ size_t nsub; /* copy of re_nsub */
+ int backrefs; /* does it use back references? */
+ sopno nplus; /* how deep does it nest +s? */
+ /* catspace must be last */
+ cat_t catspace[1]; /* actually [NC] */
+};
+
+/* misc utilities */
+#define OUT (CHAR_MAX+1) /* a non-character value */
+#define ISWORD(c) (isalnum(c) || (c) == '_')
diff --git a/winsup/cygwin/regex/regexec.c b/winsup/cygwin/regex/regexec.c
new file mode 100644
index 000000000..5ab72e00e
--- /dev/null
+++ b/winsup/cygwin/regex/regexec.c
@@ -0,0 +1,141 @@
+/*
+ * the outer shell of regexec()
+ *
+ * This file includes engine.c *twice*, after muchos fiddling with the
+ * macros that code uses. This lets the same code operate on two different
+ * representations for state sets.
+ */
+#include "winsup.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include "regex.h"
+
+#include "utils.h"
+#include "regex2.h"
+
+#ifdef lint
+static int nope = 0; /* for use in asserts; shuts lint up */
+#endif
+
+/* macros for manipulating states, small version */
+#define states unsigned
+#define states1 unsigned /* for later use in regexec() decision */
+#define CLEAR(v) ((v) = 0)
+#define SET0(v, n) ((v) &= ~((unsigned)1 << (n)))
+#define SET1(v, n) ((v) |= (unsigned)1 << (n))
+#define ISSET(v, n) ((v) & ((unsigned)1 << (n)))
+#define ASSIGN(d, s) ((d) = (s))
+#define EQ(a, b) ((a) == (b))
+#define STATEVARS int dummy /* dummy version */
+#define STATESETUP(m, n) /* nothing */
+#define STATETEARDOWN(m) /* nothing */
+#define SETUP(v) ((v) = 0)
+#define onestate unsigned
+#define INIT(o, n) ((o) = (unsigned)1 << (n))
+#define INC(o) ((o) <<= 1)
+#define ISSTATEIN(v, o) ((v) & (o))
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n))
+#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n))
+#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
+/* function names */
+#define SNAMES /* engine.c looks after details */
+
+#include "engine.c"
+
+/* now undo things */
+#undef states
+#undef CLEAR
+#undef SET0
+#undef SET1
+#undef ISSET
+#undef ASSIGN
+#undef EQ
+#undef STATEVARS
+#undef STATESETUP
+#undef STATETEARDOWN
+#undef SETUP
+#undef onestate
+#undef INIT
+#undef INC
+#undef ISSTATEIN
+#undef FWD
+#undef BACK
+#undef ISSETBACK
+#undef SNAMES
+
+/* macros for manipulating states, large version */
+#define states char *
+#define CLEAR(v) memset(v, 0, m->g->nstates)
+#define SET0(v, n) ((v)[n] = 0)
+#define SET1(v, n) ((v)[n] = 1)
+#define ISSET(v, n) ((v)[n])
+#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
+#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
+#define STATEVARS int vn; char *space
+#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
+ if ((m)->space == NULL) return(REG_ESPACE); \
+ (m)->vn = 0; }
+#define STATETEARDOWN(m) { free((m)->space); }
+#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
+#define onestate int
+#define INIT(o, n) ((o) = (n))
+#define INC(o) ((o)++)
+#define ISSTATEIN(v, o) ((v)[o])
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
+#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
+#define ISSETBACK(v, n) ((v)[here - (n)])
+/* function names */
+#define LNAMES /* flag */
+
+#include "engine.c"
+
+/*
+ - regexec - interface for matching
+ = extern int regexec(const regex_t *, const char *, size_t, \
+ = regmatch_t [], int);
+ = #define REG_NOTBOL 00001
+ = #define REG_NOTEOL 00002
+ = #define REG_STARTEND 00004
+ = #define REG_TRACE 00400 // tracing of execution
+ = #define REG_LARGE 01000 // force large representation
+ = #define REG_BACKR 02000 // force use of backref code
+ *
+ * We put this here so we can exploit knowledge of the state representation
+ * when choosing which matcher to call. Also, by this point the matchers
+ * have been prototyped.
+ */
+int /* 0 success, REG_NOMATCH failure */
+regexec(preg, string, nmatch, pmatch, eflags)
+const regex_t *preg;
+const char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
+{
+ register struct re_guts *g = preg->re_g;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
+#endif
+
+ if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
+ return(REG_BADPAT);
+ assert(!(g->iflags&BAD));
+ if (g->iflags&BAD) /* backstop for no-debug case */
+ return(REG_BADPAT);
+ eflags = GOODFLAGS(eflags);
+
+ if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
+ return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
+ else
+ return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
+}
diff --git a/winsup/cygwin/regex/regfree.c b/winsup/cygwin/regex/regfree.c
new file mode 100644
index 000000000..b8be143d8
--- /dev/null
+++ b/winsup/cygwin/regex/regfree.c
@@ -0,0 +1,38 @@
+#include "winsup.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "regex.h"
+
+#include "utils.h"
+#include "regex2.h"
+
+/*
+ - regfree - free everything
+ = extern void regfree(regex_t *);
+ */
+void
+regfree(preg)
+regex_t *preg;
+{
+ register struct re_guts *g;
+
+ if (preg->re_magic != MAGIC1) /* oops */
+ return; /* nice to complain, but hard */
+
+ g = preg->re_g;
+ if (g == NULL || g->magic != MAGIC2) /* oops again */
+ return;
+ preg->re_magic = 0; /* mark it invalid */
+ g->magic = 0; /* mark it invalid */
+
+ if (g->strip != NULL)
+ free((char *)g->strip);
+ if (g->sets != NULL)
+ free((char *)g->sets);
+ if (g->setbits != NULL)
+ free((char *)g->setbits);
+ if (g->must != NULL)
+ free(g->must);
+ free((char *)g);
+}
diff --git a/winsup/cygwin/regex/tests b/winsup/cygwin/regex/tests
new file mode 100644
index 000000000..e4d928dad
--- /dev/null
+++ b/winsup/cygwin/regex/tests
@@ -0,0 +1,477 @@
+# regular expression test set
+# Lines are at least three fields, separated by one or more tabs. "" stands
+# for an empty field. First field is an RE. Second field is flags. If
+# C flag given, regcomp() is expected to fail, and the third field is the
+# error name (minus the leading REG_).
+#
+# Otherwise it is expected to succeed, and the third field is the string to
+# try matching it against. If there is no fourth field, the match is
+# expected to fail. If there is a fourth field, it is the substring that
+# the RE is expected to match. If there is a fifth field, it is a comma-
+# separated list of what the subexpressions should match, with - indicating
+# no match for that one. In both the fourth and fifth fields, a (sub)field
+# starting with @ indicates that the (sub)expression is expected to match
+# a null string followed by the stuff after the @; this provides a way to
+# test where null strings match. The character `N' in REs and strings
+# is newline, `S' is space, `T' is tab, `Z' is NUL.
+#
+# The full list of flags:
+# - placeholder, does nothing
+# b RE is a BRE, not an ERE
+# & try it as both an ERE and a BRE
+# C regcomp() error expected, third field is error name
+# i REG_ICASE
+# m ("mundane") REG_NOSPEC
+# s REG_NOSUB (not really testable)
+# n REG_NEWLINE
+# ^ REG_NOTBOL
+# $ REG_NOTEOL
+# # REG_STARTEND (see below)
+# p REG_PEND
+#
+# For REG_STARTEND, the start/end offsets are those of the substring
+# enclosed in ().
+
+# basics
+a & a a
+abc & abc abc
+abc|de - abc abc
+a|b|c - abc a
+
+# parentheses and perversions thereof
+a(b)c - abc abc
+a\(b\)c b abc abc
+a( C EPAREN
+a( b a( a(
+a\( - a( a(
+a\( bC EPAREN
+a\(b bC EPAREN
+a(b C EPAREN
+a(b b a(b a(b
+# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
+a) - a) a)
+) - ) )
+# end gagging (in a just world, those *should* give EPAREN)
+a) b a) a)
+a\) bC EPAREN
+\) bC EPAREN
+a()b - ab ab
+a\(\)b b ab ab
+
+# anchoring and REG_NEWLINE
+^abc$ & abc abc
+a^b - a^b
+a^b b a^b a^b
+a$b - a$b
+a$b b a$b a$b
+^ & abc @abc
+$ & abc @
+^$ & "" @
+$^ - "" @
+\($\)\(^\) b "" @
+# stop retching, those are legitimate (although disgusting)
+^^ - "" @
+$$ - "" @
+b$ & abNc
+b$ &n abNc b
+^b$ & aNbNc
+^b$ &n aNbNc b
+^$ &n aNNb @Nb
+^$ n abc
+^$ n abcN @
+$^ n aNNb @Nb
+\($\)\(^\) bn aNNb @Nb
+^^ n^ aNNb @Nb
+$$ n aNNb @NN
+^a ^ a
+a$ $ a
+^a ^n aNb
+^b ^n aNb b
+a$ $n bNa
+b$ $n bNa b
+a*(^b$)c* - b b
+a*\(^b$\)c* b b b
+
+# certain syntax errors and non-errors
+| C EMPTY
+| b | |
+* C BADRPT
+* b * *
++ C BADRPT
+? C BADRPT
+"" &C EMPTY
+() - abc @abc
+\(\) b abc @abc
+a||b C EMPTY
+|ab C EMPTY
+ab| C EMPTY
+(|a)b C EMPTY
+(a|)b C EMPTY
+(*a) C BADRPT
+(+a) C BADRPT
+(?a) C BADRPT
+({1}a) C BADRPT
+\(\{1\}a\) bC BADRPT
+(a|*b) C BADRPT
+(a|+b) C BADRPT
+(a|?b) C BADRPT
+(a|{1}b) C BADRPT
+^* C BADRPT
+^* b * *
+^+ C BADRPT
+^? C BADRPT
+^{1} C BADRPT
+^\{1\} bC BADRPT
+
+# metacharacters, backslashes
+a.c & abc abc
+a[bc]d & abd abd
+a\*c & a*c a*c
+a\\b & a\b a\b
+a\\\*b & a\*b a\*b
+a\bc & abc abc
+a\ &C EESCAPE
+a\\bc & a\bc a\bc
+\{ bC BADRPT
+a\[b & a[b a[b
+a[b &C EBRACK
+# trailing $ is a peculiar special case for the BRE code
+a$ & a a
+a$ & a$
+a\$ & a
+a\$ & a$ a$
+a\\$ & a
+a\\$ & a$
+a\\$ & a\$
+a\\$ & a\ a\
+
+# back references, ugh
+a\(b\)\2c bC ESUBREG
+a\(b\1\)c bC ESUBREG
+a\(b*\)c\1d b abbcbbd abbcbbd bb
+a\(b*\)c\1d b abbcbd
+a\(b*\)c\1d b abbcbbbd
+^\(.\)\1 b abc
+a\([bc]\)\1d b abcdabbd abbd b
+a\(\([bc]\)\2\)*d b abbccd abbccd
+a\(\([bc]\)\2\)*d b abbcbd
+# actually, this next one probably ought to fail, but the spec is unclear
+a\(\(b\)*\2\)*d b abbbd abbbd
+# here is a case that no NFA implementation does right
+\(ab*\)[ab]*\1 b ababaaa ababaaa a
+# check out normal matching in the presence of back refs
+\(a\)\1bcd b aabcd aabcd
+\(a\)\1bc*d b aabcd aabcd
+\(a\)\1bc*d b aabd aabd
+\(a\)\1bc*d b aabcccd aabcccd
+\(a\)\1bc*[ce]d b aabcccd aabcccd
+^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd
+
+# ordinary repetitions
+ab*c & abc abc
+ab+c - abc abc
+ab?c - abc abc
+a\(*\)b b a*b a*b
+a\(**\)b b ab ab
+a\(***\)b bC BADRPT
+*a b *a *a
+**a b a a
+***a bC BADRPT
+
+# the dreaded bounded repetitions
+{ & { {
+{abc & {abc {abc
+{1 C BADRPT
+{1} C BADRPT
+a{b & a{b a{b
+a{1}b - ab ab
+a\{1\}b b ab ab
+a{1,}b - ab ab
+a\{1,\}b b ab ab
+a{1,2}b - aab aab
+a\{1,2\}b b aab aab
+a{1 C EBRACE
+a\{1 bC EBRACE
+a{1a C EBRACE
+a\{1a bC EBRACE
+a{1a} C BADBR
+a\{1a\} bC BADBR
+a{,2} - a{,2} a{,2}
+a\{,2\} bC BADBR
+a{,} - a{,} a{,}
+a\{,\} bC BADBR
+a{1,x} C BADBR
+a\{1,x\} bC BADBR
+a{1,x C EBRACE
+a\{1,x bC EBRACE
+a{300} C BADBR
+a\{300\} bC BADBR
+a{1,0} C BADBR
+a\{1,0\} bC BADBR
+ab{0,0}c - abcac ac
+ab\{0,0\}c b abcac ac
+ab{0,1}c - abcac abc
+ab\{0,1\}c b abcac abc
+ab{0,3}c - abbcac abbc
+ab\{0,3\}c b abbcac abbc
+ab{1,1}c - acabc abc
+ab\{1,1\}c b acabc abc
+ab{1,3}c - acabc abc
+ab\{1,3\}c b acabc abc
+ab{2,2}c - abcabbc abbc
+ab\{2,2\}c b abcabbc abbc
+ab{2,4}c - abcabbc abbc
+ab\{2,4\}c b abcabbc abbc
+((a{1,10}){1,10}){1,10} - a a a,a
+
+# multiple repetitions
+a** &C BADRPT
+a++ C BADRPT
+a?? C BADRPT
+a*+ C BADRPT
+a*? C BADRPT
+a+* C BADRPT
+a+? C BADRPT
+a?* C BADRPT
+a?+ C BADRPT
+a{1}{1} C BADRPT
+a*{1} C BADRPT
+a+{1} C BADRPT
+a?{1} C BADRPT
+a{1}* C BADRPT
+a{1}+ C BADRPT
+a{1}? C BADRPT
+a*{b} - a{b} a{b}
+a\{1\}\{1\} bC BADRPT
+a*\{1\} bC BADRPT
+a\{1\}* bC BADRPT
+
+# brackets, and numerous perversions thereof
+a[b]c & abc abc
+a[ab]c & abc abc
+a[^ab]c & adc adc
+a[]b]c & a]c a]c
+a[[b]c & a[c a[c
+a[-b]c & a-c a-c
+a[^]b]c & adc adc
+a[^-b]c & adc adc
+a[b-]c & a-c a-c
+a[b &C EBRACK
+a[] &C EBRACK
+a[1-3]c & a2c a2c
+a[3-1]c &C ERANGE
+a[1-3-5]c &C ERANGE
+a[[.-.]--]c & a-c a-c
+a[1- &C ERANGE
+a[[. &C EBRACK
+a[[.x &C EBRACK
+a[[.x. &C EBRACK
+a[[.x.] &C EBRACK
+a[[.x.]] & ax ax
+a[[.x,.]] &C ECOLLATE
+a[[.one.]]b & a1b a1b
+a[[.notdef.]]b &C ECOLLATE
+a[[.].]]b & a]b a]b
+a[[:alpha:]]c & abc abc
+a[[:notdef:]]c &C ECTYPE
+a[[: &C EBRACK
+a[[:alpha &C EBRACK
+a[[:alpha:] &C EBRACK
+a[[:alpha,:] &C ECTYPE
+a[[:]:]]b &C ECTYPE
+a[[:-:]]b &C ECTYPE
+a[[:alph:]] &C ECTYPE
+a[[:alphabet:]] &C ECTYPE
+[[:alnum:]]+ - -%@a0X- a0X
+[[:alpha:]]+ - -%@aX0- aX
+[[:blank:]]+ - aSSTb SST
+[[:cntrl:]]+ - aNTb NT
+[[:digit:]]+ - a019b 019
+[[:graph:]]+ - Sa%bS a%b
+[[:lower:]]+ - AabC ab
+[[:print:]]+ - NaSbN aSb
+[[:punct:]]+ - S%-&T %-&
+[[:space:]]+ - aSNTb SNT
+[[:upper:]]+ - aBCd BC
+[[:xdigit:]]+ - p0f3Cq 0f3C
+a[[=b=]]c & abc abc
+a[[= &C EBRACK
+a[[=b &C EBRACK
+a[[=b= &C EBRACK
+a[[=b=] &C EBRACK
+a[[=b,=]] &C ECOLLATE
+a[[=one=]]b & a1b a1b
+
+# complexities
+a(((b)))c - abc abc
+a(b|(c))d - abd abd
+a(b*|c)d - abbd abbd
+# just gotta have one DFA-buster, of course
+a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and an inline expansion in case somebody gets tricky
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and in case somebody just slips in an NFA...
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
+# fish for anomalies as the number of states passes 32
+12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789
+123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890
+1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901
+12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012
+123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123
+# and one really big one, beyond any plausible word width
+1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890
+# fish for problems as brackets go past 8
+[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm
+[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo
+[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq
+[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq
+
+# subtleties of matching
+abc & xabcy abc
+a\(b\)?c\1d b acd
+aBc i Abc Abc
+a[Bc]*d i abBCcd abBCcd
+0[[:upper:]]1 &i 0a1 0a1
+0[[:lower:]]1 &i 0A1 0A1
+a[^b]c &i abc
+a[^b]c &i aBc
+a[^b]c &i adc adc
+[a]b[c] - abc abc
+[a]b[a] - aba aba
+[abc]b[abc] - abc abc
+[abc]b[abd] - abd abd
+a(b?c)+d - accd accd
+(wee|week)(knights|night) - weeknights weeknights
+(we|wee|week|frob)(knights|night|day) - weeknights weeknights
+a[bc]d - xyzaaabcaababdacd abd
+a[ab]c - aaabc abc
+abc s abc abc
+a* & b @b
+
+# Let's have some fun -- try to match a C comment.
+# first the obvious, which looks okay at first glance...
+/\*.*\*/ - /*x*/ /*x*/
+# but...
+/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/
+# okay, we must not match */ inside; try to do that...
+/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/
+/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/
+# but...
+/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/
+# and a still fancier version, which does it right (I think)...
+/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/
+/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/
+/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/
+
+# subexpressions
+.* - abc abc -
+a(b)(c)d - abcd abcd b,c
+a(((b)))c - abc abc b,b,b
+a(b|(c))d - abd abd b,-
+a(b*|c|e)d - abbd abbd bb
+a(b*|c|e)d - acd acd c
+a(b*|c|e)d - ad ad @d
+a(b?)c - abc abc b
+a(b?)c - ac ac @c
+a(b+)c - abc abc b
+a(b+)c - abbbc abbbc bbb
+a(b*)c - ac ac @c
+(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de
+# the regression tester only asks for 9 subexpressions
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k
+a([bc]?)c - abc abc b
+a([bc]?)c - ac ac @c
+a([bc]+)c - abc abc b
+a([bc]+)c - abcc abcc bc
+a([bc]+)bc - abcbc abcbc bc
+a(bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abbb abbb bb
+a(bbb+|bb+|b)bb - abbb abbb b
+(.*).* - abcdef abcdef abcdef
+(a*)* - bc @b @b
+
+# do we get the right subexpression when it is used more than once?
+a(b|c)*d - ad ad -
+a(b|c)*d - abcd abcd c
+a(b|c)+d - abd abd b
+a(b|c)+d - abcd abcd c
+a(b|c?)+d - ad ad @d
+a(b|c?)+d - abcd abcd @d
+a(b|c){0,0}d - ad ad -
+a(b|c){0,1}d - ad ad -
+a(b|c){0,1}d - abd abd b
+a(b|c){0,2}d - ad ad -
+a(b|c){0,2}d - abcd abcd c
+a(b|c){0,}d - ad ad -
+a(b|c){0,}d - abcd abcd c
+a(b|c){1,1}d - abd abd b
+a(b|c){1,1}d - acd acd c
+a(b|c){1,2}d - abd abd b
+a(b|c){1,2}d - abcd abcd c
+a(b|c){1,}d - abd abd b
+a(b|c){1,}d - abcd abcd c
+a(b|c){2,2}d - acbd acbd b
+a(b|c){2,2}d - abcd abcd c
+a(b|c){2,4}d - abcd abcd c
+a(b|c){2,4}d - abcbd abcbd b
+a(b|c){2,4}d - abcbcd abcbcd c
+a(b|c){2,}d - abcd abcd c
+a(b|c){2,}d - abcbd abcbd b
+a(b+|((c)*))+d - abd abd @d,@d,-
+a(b+|((c)*))+d - abcd abcd @d,@d,-
+
+# check out the STARTEND option
+[abc] &# a(b)c b
+[abc] &# a(d)c
+[abc] &# a(bc)d b
+[abc] &# a(dc)d c
+. &# a()c
+b.*c &# b(bc)c bc
+b.* &# b(bc)c bc
+.*c &# b(bc)c bc
+
+# plain strings, with the NOSPEC flag
+abc m abc abc
+abc m xabcy abc
+abc m xyz
+a*b m aba*b a*b
+a*b m ab
+"" mC EMPTY
+
+# cases involving NULs
+aZb & a a
+aZb &p a
+aZb &p# (aZb) aZb
+aZ*b &p# (ab) ab
+a.b &# (aZb) aZb
+a.* &# (aZb)c aZb
+
+# word boundaries (ick)
+[[:<:]]a & a a
+[[:<:]]a & ba
+[[:<:]]a & -a a
+a[[:>:]] & a a
+a[[:>:]] & ab
+a[[:>:]] & a- a
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc
+[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc
+[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc
+[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_
+[[:<:]]a_b[[:>:]] & x_a_b
+
+# past problems, and suspected problems
+(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1
+abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop
+abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv
+(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11
+CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11
+Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz
+a?b - ab ab
+-\{0,1\}[0-9]*$ b -5 -5
+a*a*a*a*a*a*a* & aaaaaa aaaaaa
diff --git a/winsup/cygwin/regex/utils.h b/winsup/cygwin/regex/utils.h
new file mode 100644
index 000000000..1a997ac8f
--- /dev/null
+++ b/winsup/cygwin/regex/utils.h
@@ -0,0 +1,22 @@
+/* utility definitions */
+#ifdef _POSIX2_RE_DUP_MAX
+#define DUPMAX _POSIX2_RE_DUP_MAX
+#else
+#define DUPMAX 255
+#endif
+#define INFINITY (DUPMAX + 1)
+#define NC (CHAR_MAX - CHAR_MIN + 1)
+typedef unsigned char uch;
+
+/* switch off assertions (if not already off) if no REDEBUG */
+#ifndef REDEBUG
+#ifndef NDEBUG
+#define NDEBUG /* no assertions please */
+#endif
+#endif
+#include <assert.h>
+
+/* for old systems with bcopy() but no memmove() */
+#ifdef USEBCOPY
+#define memmove(d, s, c) bcopy(s, d, c)
+#endif
diff --git a/winsup/cygwin/regexp/v8_regerror.c b/winsup/cygwin/regexp/v8_regerror.c
new file mode 100644
index 000000000..56d63ff2f
--- /dev/null
+++ b/winsup/cygwin/regexp/v8_regerror.c
@@ -0,0 +1,28 @@
+/* regerror.c
+
+ Copyright 1996, 1998, 2001 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#include "regexp.h"
+#include <stdio.h>
+
+void __declspec(dllexport)
+regerror(const char *s __attribute__ ((unused)))
+{
+#ifdef ERRAVAIL
+ error("regexp: %s", s);
+#else
+/*
+ fprintf(stderr, "regexp(3): %s\n", s);
+ exit(1);
+*/
+ return; /* let std. egrep handle errors */
+#endif
+ /* NOTREACHED */
+}
diff --git a/winsup/cygwin/regexp/v8_regexp.c b/winsup/cygwin/regexp/v8_regexp.c
new file mode 100644
index 000000000..fef1267a0
--- /dev/null
+++ b/winsup/cygwin/regexp/v8_regexp.c
@@ -0,0 +1,1321 @@
+/*
+ * regcomp and regexec -- regsub and regerror are elsewhere
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
+ *** to assist in implementing egrep.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
+ *** as in BSD grep and ex.
+ *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+ *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
+ *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
+ *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
+ *** THIS IS AN ALTERED VERSION. It was altered by Geoffrey Noer,
+ *** noer@cygnus.com, on 6 Oct 1997, to change the prototype format
+ *** for inclusion in the Cygwin32 library.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+
+#include "winsup.h"
+#include "regexp.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "regmagic.h"
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; '\0' if none obvious
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in regexec() needs it and regcomp() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
+ * have one of the subtle syntax dependencies: an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.) The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM. In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects
+ * to the thing following the set of BRANCHes.) The opcodes are:
+ */
+
+/* definition number opnd? meaning */
+#define END 0 /* no End of program. */
+#define BOL 1 /* no Match "" at beginning of line. */
+#define EOL 2 /* no Match "" at end of line. */
+#define ANY 3 /* no Match any one character. */
+#define ANYOF 4 /* str Match any character in this string. */
+#define ANYBUT 5 /* str Match any character not in this string. */
+#define BRANCH 6 /* node Match this alternative, or the next... */
+#define BACK 7 /* no Match "", "next" ptr points backward. */
+#define EXACTLY 8 /* str Match this string. */
+#define NOTHING 9 /* no Match empty string. */
+#define STAR 10 /* node Match this (simple) thing 0 or more times. */
+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
+#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
+#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
+#define OPEN 20 /* no Mark this point in input as start of #n. */
+ /* OPEN+1 is number 1, etc. */
+#define CLOSE 30 /* no Analogous to OPEN. */
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE ...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p) (*(p))
+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define OPERAND(p) ((p) + 3)
+
+/*
+ * See regmagic.h for one further detail of program structure.
+ */
+
+
+/*
+ * Utility definitions.
+ */
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+#define FAIL(m) { regerror(m); return(NULL); }
+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 01 /* Known never to match null string. */
+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
+#define SPSTART 04 /* Starts with * or +. */
+#define WORST 0 /* Worst case. */
+
+/*
+ * Global work variables for regcomp().
+ */
+static char *regparse; /* Input-scan pointer. */
+static int regnpar; /* () count. */
+static char regdummy;
+static char *regcode; /* Code-emit pointer; &regdummy = don't. */
+static long regsize; /* Code size. */
+
+/*
+ * Forward declarations for regcomp()'s friends.
+ */
+#ifndef STATIC
+#define STATIC static
+#endif
+STATIC char *reg (int, int *);
+STATIC char *regbranch (int *);
+STATIC char *regpiece (int *);
+STATIC char *regatom (int *);
+STATIC char *regnode (char);
+STATIC char *regnext (char *);
+STATIC void regc (char);
+STATIC void reginsert (char, char *);
+STATIC void regtail (char *, char *);
+STATIC void regoptail (char *, char *);
+#ifdef STRCSPN
+STATIC int strcspn (char *, char *);
+#endif
+
+/*
+ - regcomp - compile a regular expression into internal code
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code. So we cheat: we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it. (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+regexp * __declspec(dllexport)
+regcomp(exp)
+const char *exp;
+{
+ register regexp *r;
+ register char *scan;
+ register char *longest;
+ register int len;
+ int flags;
+
+ if (exp == NULL)
+ FAIL("NULL argument");
+
+ /* First pass: determine size, legality. */
+#ifdef notdef
+ if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
+#endif
+ regparse = (char *)exp;
+ regnpar = 1;
+ regsize = 0L;
+ regcode = &regdummy;
+ regc(MAGIC);
+ if (reg(0, &flags) == NULL)
+ return(NULL);
+
+ /* Small enough for pointer-storage convention? */
+ if (regsize >= 32767L) /* Probably could be 65535L. */
+ FAIL("regexp too big");
+
+ /* Allocate space. */
+ r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
+ if (r == NULL)
+ FAIL("out of space");
+
+ /* Second pass: emit code. */
+ regparse = (char *)exp;
+ regnpar = 1;
+ regcode = r->program;
+ regc(MAGIC);
+ if (reg(0, &flags) == NULL)
+ return(NULL);
+
+ /* Dig out information for optimizations. */
+ r->regstart = '\0'; /* Worst-case defaults. */
+ r->reganch = 0;
+ r->regmust = NULL;
+ r->regmlen = 0;
+ scan = r->program+1; /* First BRANCH. */
+ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
+ scan = OPERAND(scan);
+
+ /* Starting-point info. */
+ if (OP(scan) == EXACTLY)
+ r->regstart = *OPERAND(scan);
+ else if (OP(scan) == BOL)
+ r->reganch++;
+
+ /*
+ * If there's something expensive in the r.e., find the
+ * longest literal string that must appear and make it the
+ * regmust. Resolve ties in favor of later strings, since
+ * the regstart check works with the beginning of the r.e.
+ * and avoiding duplication strengthens checking. Not a
+ * strong reason, but sufficient in the absence of others.
+ */
+ if (flags&SPSTART) {
+ longest = NULL;
+ len = 0;
+ for (; scan != NULL; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && (int) strlen(OPERAND(scan)) >= len) {
+ longest = OPERAND(scan);
+ len = strlen(OPERAND(scan));
+ }
+ r->regmust = longest;
+ r->regmlen = len;
+ }
+ }
+
+ return(r);
+}
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char *
+reg(paren, flagp)
+int paren; /* Parenthesized? */
+int *flagp;
+{
+ register char *ret;
+ register char *br;
+ register char *ender;
+ register int parno = 0;
+ int flags;
+
+ *flagp = HASWIDTH; /* Tentatively. */
+
+ /* Make an OPEN node, if parenthesized. */
+ if (paren) {
+ if (regnpar >= NSUBEXP)
+ FAIL("too many ()");
+ parno = regnpar;
+ regnpar++;
+ ret = regnode(OPEN+parno);
+ } else
+ ret = NULL;
+
+ /* Pick up the branches, linking them together. */
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ if (ret != NULL)
+ regtail(ret, br); /* OPEN -> first. */
+ else
+ ret = br;
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ while (*regparse == '|' || *regparse == '\n') {
+ regparse++;
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ regtail(ret, br); /* BRANCH -> BRANCH. */
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ }
+
+ /* Make a closing node, and hook it on the end. */
+ ender = regnode((paren) ? CLOSE+parno : END);
+ regtail(ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ /* Check for proper termination. */
+ if (paren && *regparse++ != ')') {
+ FAIL("unmatched ()");
+ } else if (!paren && *regparse != '\0') {
+ if (*regparse == ')') {
+ FAIL("unmatched ()");
+ } else
+ FAIL("junk on end"); /* "Can't happen". */
+ /* NOTREACHED */
+ }
+
+ return(ret);
+}
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char *
+regbranch(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char *chain;
+ register char *latest;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ ret = regnode(BRANCH);
+ chain = NULL;
+ while (*regparse != '\0' && *regparse != ')' &&
+ *regparse != '\n' && *regparse != '|') {
+ latest = regpiece(&flags);
+ if (latest == NULL)
+ return(NULL);
+ *flagp |= flags&HASWIDTH;
+ if (chain == NULL) /* First piece. */
+ *flagp |= flags&SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == NULL) /* Loop ran zero times. */
+ (void) regnode(NOTHING);
+
+ return(ret);
+}
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char *
+regpiece(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char op;
+ register char *next;
+ int flags;
+
+ ret = regatom(&flags);
+ if (ret == NULL)
+ return(NULL);
+
+ op = *regparse;
+ if (!ISMULT(op)) {
+ *flagp = flags;
+ return(ret);
+ }
+
+ if (!(flags&HASWIDTH) && op != '?')
+ FAIL("*+ operand could be empty");
+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
+
+ if (op == '*' && (flags&SIMPLE))
+ reginsert(STAR, ret);
+ else if (op == '*') {
+ /* Emit x* as (x&|), where & means "self". */
+ reginsert(BRANCH, ret); /* Either x */
+ regoptail(ret, regnode(BACK)); /* and loop */
+ regoptail(ret, ret); /* back */
+ regtail(ret, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '+' && (flags&SIMPLE))
+ reginsert(PLUS, ret);
+ else if (op == '+') {
+ /* Emit x+ as x(&|), where & means "self". */
+ next = regnode(BRANCH); /* Either */
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); /* loop back */
+ regtail(next, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '?') {
+ /* Emit x? as (x|) */
+ reginsert(BRANCH, ret); /* Either x */
+ regtail(ret, regnode(BRANCH)); /* or */
+ next = regnode(NOTHING); /* null. */
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ regparse++;
+ if (ISMULT(*regparse))
+ FAIL("nested *?+");
+
+ return(ret);
+}
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char *
+regatom(flagp)
+int *flagp;
+{
+ register char *ret;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ switch (*regparse++) {
+ /* FIXME: these chars only have meaning at beg/end of pat? */
+ case '^':
+ ret = regnode(BOL);
+ break;
+ case '$':
+ ret = regnode(EOL);
+ break;
+ case '.':
+ ret = regnode(ANY);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ case '[': {
+ register int class;
+ register int classend;
+
+ if (*regparse == '^') { /* Complement of range. */
+ ret = regnode(ANYBUT);
+ regparse++;
+ } else
+ ret = regnode(ANYOF);
+ if (*regparse == ']' || *regparse == '-')
+ regc(*regparse++);
+ while (*regparse != '\0' && *regparse != ']') {
+ if (*regparse == '-') {
+ regparse++;
+ if (*regparse == ']' || *regparse == '\0')
+ regc('-');
+ else {
+ class = UCHARAT(regparse-2)+1;
+ classend = UCHARAT(regparse);
+ if (class > classend+1)
+ FAIL("invalid [] range");
+ for (; class <= classend; class++)
+ regc(class);
+ regparse++;
+ }
+ } else
+ regc(*regparse++);
+ }
+ regc('\0');
+ if (*regparse != ']')
+ FAIL("unmatched []");
+ regparse++;
+ *flagp |= HASWIDTH|SIMPLE;
+ }
+ break;
+ case '(':
+ ret = reg(1, &flags);
+ if (ret == NULL)
+ return(NULL);
+ *flagp |= flags&(HASWIDTH|SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case '\n':
+ case ')':
+ FAIL("internal urp"); /* Supposed to be caught earlier. */
+ break;
+ case '?':
+ case '+':
+ case '*':
+ FAIL("?+* follows nothing");
+ break;
+ case '\\':
+ switch (*regparse++) {
+ case '\0':
+ FAIL("trailing \\");
+ break;
+ case '<':
+ ret = regnode(WORDA);
+ break;
+ case '>':
+ ret = regnode(WORDZ);
+ break;
+ /* FIXME: Someday handle \1, \2, ... */
+ default:
+ /* Handle general quoted chars in exact-match routine */
+ goto de_fault;
+ }
+ break;
+ de_fault:
+ default:
+ /*
+ * Encode a string of characters to be matched exactly.
+ *
+ * This is a bit tricky due to quoted chars and due to
+ * '*', '+', and '?' taking the SINGLE char previous
+ * as their operand.
+ *
+ * On entry, the char at regparse[-1] is going to go
+ * into the string, no matter what it is. (It could be
+ * following a \ if we are entered from the '\' case.)
+ *
+ * Basic idea is to pick up a good char in ch and
+ * examine the next char. If it's *+? then we twiddle.
+ * If it's \ then we frozzle. If it's other magic char
+ * we push ch and terminate the string. If none of the
+ * above, we push ch on the string and go around again.
+ *
+ * regprev is used to remember where "the current char"
+ * starts in the string, if due to a *+? we need to back
+ * up and put the current char in a separate, 1-char, string.
+ * When regprev is NULL, ch is the only char in the
+ * string; this is used in *+? handling, and in setting
+ * flags |= SIMPLE at the end.
+ */
+ {
+ char *regprev;
+ register char ch = 0;
+
+ regparse--; /* Look at cur char */
+ ret = regnode(EXACTLY);
+ for ( regprev = 0 ; ; ) {
+ ch = *regparse++; /* Get current char */
+ switch (*regparse) { /* look at next one */
+
+ default:
+ regc(ch); /* Add cur to string */
+ break;
+
+ case '.': case '[': case '(':
+ case ')': case '|': case '\n':
+ case '$': case '^':
+ case '\0':
+ /* FIXME, $ and ^ should not always be magic */
+ magic:
+ regc(ch); /* dump cur char */
+ goto done; /* and we are done */
+
+ case '?': case '+': case '*':
+ if (!regprev) /* If just ch in str, */
+ goto magic; /* use it */
+ /* End mult-char string one early */
+ regparse = regprev; /* Back up parse */
+ goto done;
+
+ case '\\':
+ regc(ch); /* Cur char OK */
+ switch (regparse[1]){ /* Look after \ */
+ case '\0':
+ case '<':
+ case '>':
+ /* FIXME: Someday handle \1, \2, ... */
+ goto done; /* Not quoted */
+ default:
+ /* Backup point is \, scan * point is after it. */
+ regprev = regparse;
+ regparse++;
+ continue; /* NOT break; */
+ }
+ }
+ regprev = regparse; /* Set backup point */
+ }
+ done:
+ regc('\0');
+ *flagp |= HASWIDTH;
+ if (!regprev) /* One char? */
+ *flagp |= SIMPLE;
+ }
+ break;
+ }
+
+ return(ret);
+}
+
+/*
+ - regnode - emit a node
+ */
+static char * /* Location. */
+regnode(op)
+char op;
+{
+ register char *ret;
+ register char *ptr;
+
+ ret = regcode;
+ if (ret == &regdummy) {
+ regsize += 3;
+ return(ret);
+ }
+
+ ptr = ret;
+ *ptr++ = op;
+ *ptr++ = '\0'; /* Null "next" pointer. */
+ *ptr++ = '\0';
+ regcode = ptr;
+
+ return(ret);
+}
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void
+regc(b)
+char b;
+{
+ if (regcode != &regdummy)
+ *regcode++ = b;
+ else
+ regsize++;
+}
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void
+reginsert(op, opnd)
+char op;
+char *opnd;
+{
+ register char *src;
+ register char *dst;
+ register char *place;
+
+ if (regcode == &regdummy) {
+ regsize += 3;
+ return;
+ }
+
+ src = regcode;
+ regcode += 3;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = op;
+ *place++ = '\0';
+ *place++ = '\0';
+}
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void
+regtail(p, val)
+char *p;
+char *val;
+{
+ register char *scan;
+ register char *temp;
+ register int offset;
+
+ if (p == &regdummy)
+ return;
+
+ /* Find last node. */
+ scan = p;
+ for (;;) {
+ temp = regnext(scan);
+ if (temp == NULL)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = scan - val;
+ else
+ offset = val - scan;
+ *(scan+1) = (offset>>8)&0377;
+ *(scan+2) = offset&0377;
+}
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void
+regoptail(p, val)
+char *p;
+char *val;
+{
+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */
+ if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+ return;
+ regtail(OPERAND(p), val);
+}
+
+/*
+ * regexec and friends
+ */
+
+/*
+ * Global work variables for regexec().
+ */
+static char *reginput; /* String-input pointer. */
+static char *regbol; /* Beginning of input, for ^ check. */
+static char **regstartp; /* Pointer to startp array. */
+static char **regendp; /* Ditto for endp. */
+
+/*
+ * Forwards.
+ */
+STATIC int regtry (const regexp *, const char *);
+STATIC int regmatch (char *);
+STATIC int regrepeat (char *);
+
+#ifdef DEBUG
+int regnarrate = 0;
+void regdump __P((regexp *));
+STATIC char *regprop __P((char *));
+#endif
+
+/*
+ - regexec - match a regexp against a string
+ */
+int __declspec(dllexport)
+regexec(prog, string)
+register const regexp *prog;
+register const char *string;
+{
+ register char *s;
+
+ /* Be paranoid... */
+ if (prog == NULL || string == NULL) {
+ regerror("NULL parameter");
+ return(0);
+ }
+
+ /* Check validity of program. */
+ if (UCHARAT(prog->program) != MAGIC) {
+ regerror("corrupted program");
+ return(0);
+ }
+
+ /* If there is a "must appear" string, look for it. */
+ if (prog->regmust != NULL) {
+ s = (char *)string;
+ while ((s = strchr(s, prog->regmust[0])) != NULL) {
+ if (strncmp(s, prog->regmust, prog->regmlen) == 0)
+ break; /* Found it. */
+ s++;
+ }
+ if (s == NULL) /* Not present. */
+ return(0);
+ }
+
+ /* Mark beginning of line for ^ . */
+ regbol = (char *)string;
+
+ /* Simplest case: anchored match need be tried only once. */
+ if (prog->reganch)
+ return(regtry(prog, string));
+
+ /* Messy cases: unanchored match. */
+ s = (char *)string;
+ if (prog->regstart != '\0')
+ /* We know what char it must start with. */
+ while ((s = strchr(s, prog->regstart)) != NULL) {
+ if (regtry(prog, s))
+ return(1);
+ s++;
+ }
+ else
+ /* We don't -- general case. */
+ do {
+ if (regtry(prog, s))
+ return(1);
+ } while (*s++ != '\0');
+
+ /* Failure. */
+ return(0);
+}
+
+/*
+ - regtry - try match at specific point
+ */
+static int /* 0 failure, 1 success */
+regtry(prog, string)
+const regexp *prog;
+const char *string;
+{
+ register int i;
+ register char **sp;
+ register char **ep;
+
+ reginput = (char *)string; /* XXX */
+ regstartp = (char **)prog->startp; /* XXX */
+ regendp = (char **)prog->endp; /* XXX */
+
+ sp = (char **)prog->startp; /* XXX */
+ ep = (char **)prog->endp; /* XXX */
+ for (i = NSUBEXP; i > 0; i--) {
+ *sp++ = NULL;
+ *ep++ = NULL;
+ }
+ if (regmatch((char *)prog->program + 1)) { /* XXX */
+ ((regexp *)prog)->startp[0] = (char *)string; /* XXX */
+ ((regexp *)prog)->endp[0] = reginput; /* XXX */
+ return(1);
+ } else
+ return(0);
+}
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly. In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ */
+static int /* 0 failure, 1 success */
+regmatch(prog)
+char *prog;
+{
+ register char *scan; /* Current node. */
+ char *next; /* Next node. */
+
+ scan = prog;
+#ifdef DEBUG
+ if (scan != NULL && regnarrate)
+ fprintf(stderr, "%s(\n", regprop(scan));
+#endif
+ while (scan != NULL) {
+#ifdef DEBUG
+ if (regnarrate)
+ fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+ next = regnext(scan);
+
+ switch (OP(scan)) {
+ case BOL:
+ if (reginput != regbol)
+ return(0);
+ break;
+ case EOL:
+ if (*reginput != '\0')
+ return(0);
+ break;
+ case WORDA:
+ /* Must be looking at a letter, digit, or _ */
+ if ((!isalnum(*reginput)) && *reginput != '_')
+ return(0);
+ /* Prev must be BOL or nonword */
+ if (reginput > regbol &&
+ (isalnum(reginput[-1]) || reginput[-1] == '_'))
+ return(0);
+ break;
+ case WORDZ:
+ /* Must be looking at non letter, digit, or _ */
+ if (isalnum(*reginput) || *reginput == '_')
+ return(0);
+ /* We don't care what the previous char was */
+ break;
+ case ANY:
+ if (*reginput == '\0')
+ return(0);
+ reginput++;
+ break;
+ case EXACTLY: {
+ register int len;
+ register char *opnd;
+
+ opnd = OPERAND(scan);
+ /* Inline the first character, for speed. */
+ if (*opnd != *reginput)
+ return(0);
+ len = strlen(opnd);
+ if (len > 1 && strncmp(opnd, reginput, len) != 0)
+ return(0);
+ reginput += len;
+ }
+ break;
+ case ANYOF:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+ return(0);
+ reginput++;
+ break;
+ case ANYBUT:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+ return(0);
+ reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9: {
+ register int no;
+ register char *save;
+
+ no = OP(scan) - OPEN;
+ save = reginput;
+
+ if (regmatch(next)) {
+ /*
+ * Don't set startp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regstartp[no] == NULL)
+ regstartp[no] = save;
+ return(1);
+ } else
+ return(0);
+ }
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9: {
+ register int no;
+ register char *save;
+
+ no = OP(scan) - CLOSE;
+ save = reginput;
+
+ if (regmatch(next)) {
+ /*
+ * Don't set endp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regendp[no] == NULL)
+ regendp[no] = save;
+ return(1);
+ } else
+ return(0);
+ }
+ break;
+ case BRANCH: {
+ register char *save;
+
+ if (OP(next) != BRANCH) /* No choice. */
+ next = OPERAND(scan); /* Avoid recursion. */
+ else {
+ do {
+ save = reginput;
+ if (regmatch(OPERAND(scan)))
+ return(1);
+ reginput = save;
+ scan = regnext(scan);
+ } while (scan != NULL && OP(scan) == BRANCH);
+ return(0);
+ /* NOTREACHED */
+ }
+ }
+ break;
+ case STAR:
+ case PLUS: {
+ register char nextch;
+ register int no;
+ register char *save;
+ register int min;
+
+ /*
+ * Lookahead to avoid useless match attempts
+ * when we know what character comes next.
+ */
+ nextch = '\0';
+ if (OP(next) == EXACTLY)
+ nextch = *OPERAND(next);
+ min = (OP(scan) == STAR) ? 0 : 1;
+ save = reginput;
+ no = regrepeat(OPERAND(scan));
+ while (no >= min) {
+ /* If it could work, try it. */
+ if (nextch == '\0' || *reginput == nextch)
+ if (regmatch(next))
+ return(1);
+ /* Couldn't or didn't -- back up. */
+ no--;
+ reginput = save + no;
+ }
+ return(0);
+ }
+ break;
+ case END:
+ return(1); /* Success! */
+ break;
+ default:
+ regerror("memory corruption");
+ return(0);
+ break;
+ }
+
+ scan = next;
+ }
+
+ /*
+ * We get here only if there's trouble -- normally "case END" is
+ * the terminating point.
+ */
+ regerror("corrupted pointers");
+ return(0);
+}
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int
+regrepeat(p)
+char *p;
+{
+ register int count = 0;
+ register char *scan;
+ register char *opnd;
+
+ scan = reginput;
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ count = strlen(scan);
+ scan += count;
+ break;
+ case EXACTLY:
+ while (*opnd == *scan) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYOF:
+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYBUT:
+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ default: /* Oh dear. Called inappropriately. */
+ regerror("internal foulup");
+ count = 0; /* Best compromise. */
+ break;
+ }
+ reginput = scan;
+
+ return(count);
+}
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static char *
+regnext(p)
+register char *p;
+{
+ register int offset;
+
+ if (p == &regdummy)
+ return(NULL);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return(NULL);
+
+ if (OP(p) == BACK)
+ return(p-offset);
+ else
+ return(p+offset);
+}
+
+#ifdef DEBUG
+
+/*
+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+void
+regdump(r)
+regexp *r;
+{
+ register char *s;
+ register char op = EXACTLY; /* Arbitrary non-END op. */
+ register char *next;
+ extern char *strchr();
+
+
+ s = r->program + 1;
+ while (op != END) { /* While that wasn't END last time... */
+ op = OP(s);
+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
+ next = regnext(s);
+ if (next == NULL) /* Next ptr. */
+ printf("(0)");
+ else
+ printf("(%d)", (s-r->program)+(next-s));
+ s += 3;
+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
+ /* Literal string, where present. */
+ while (*s != '\0') {
+ putchar(*s);
+ s++;
+ }
+ s++;
+ }
+ putchar('\n');
+ }
+
+ /* Header fields of interest. */
+ if (r->regstart != '\0')
+ printf("start `%c' ", r->regstart);
+ if (r->reganch)
+ printf("anchored ");
+ if (r->regmust != NULL)
+ printf("must have \"%s\"", r->regmust);
+ printf("\n");
+}
+
+/*
+ - regprop - printable representation of opcode
+ */
+static char *
+regprop(op)
+char *op;
+{
+ register char *p;
+ static char buf[50];
+
+ (void) strcpy(buf, ":");
+
+ switch (OP(op)) {
+ case BOL:
+ p = "BOL";
+ break;
+ case EOL:
+ p = "EOL";
+ break;
+ case ANY:
+ p = "ANY";
+ break;
+ case ANYOF:
+ p = "ANYOF";
+ break;
+ case ANYBUT:
+ p = "ANYBUT";
+ break;
+ case BRANCH:
+ p = "BRANCH";
+ break;
+ case EXACTLY:
+ p = "EXACTLY";
+ break;
+ case NOTHING:
+ p = "NOTHING";
+ break;
+ case BACK:
+ p = "BACK";
+ break;
+ case END:
+ p = "END";
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9:
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9:
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ break;
+ case STAR:
+ p = "STAR";
+ break;
+ case PLUS:
+ p = "PLUS";
+ break;
+ case WORDA:
+ p = "WORDA";
+ break;
+ case WORDZ:
+ p = "WORDZ";
+ break;
+ default:
+ regerror("corrupted opcode");
+ break;
+ }
+ if (p != NULL)
+ (void) strcat(buf, p);
+ return(buf);
+}
+#endif
+
+/*
+ * The following is provided for those people who do not have strcspn() in
+ * their C libraries. They should get off their butts and do something
+ * about it; at least one public-domain implementation of those (highly
+ * useful) string routines has been published on Usenet.
+ */
+#ifdef STRCSPN
+/*
+ * strcspn - find length of initial segment of s1 consisting entirely
+ * of characters not from s2
+ */
+
+static int
+strcspn(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *scan1;
+ register char *scan2;
+ register int count;
+
+ count = 0;
+ for (scan1 = s1; *scan1 != '\0'; scan1++) {
+ for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
+ if (*scan1 == *scan2++)
+ return(count);
+ count++;
+ }
+ return(count);
+}
+#endif
diff --git a/winsup/cygwin/regexp/v8_regsub.c b/winsup/cygwin/regexp/v8_regsub.c
new file mode 100644
index 000000000..aa95b876a
--- /dev/null
+++ b/winsup/cygwin/regexp/v8_regsub.c
@@ -0,0 +1,88 @@
+/*
+ * regsub
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ */
+
+#if 0
+#ifndef lint
+static char *rcsid = "$Id$";
+#endif /* not lint */
+#endif
+
+#include "winsup.h"
+#include "regexp.h"
+#include <stdio.h>
+#include <string.h>
+#include "regmagic.h"
+
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+/*
+ - regsub - perform substitutions after a regexp match
+ */
+void __declspec(dllexport)
+regsub(prog, source, dest)
+const regexp *prog;
+const char *source;
+char *dest;
+{
+ register char *src;
+ register char *dst;
+ register char c;
+ register int no;
+ register int len;
+
+ if (prog == NULL || source == NULL || dest == NULL) {
+ regerror("NULL parm to regsub");
+ return;
+ }
+ if (UCHARAT(prog->program) != MAGIC) {
+ regerror("damaged regexp fed to regsub");
+ return;
+ }
+
+ src = (char *)source;
+ dst = dest;
+ while ((c = *src++) != '\0') {
+ if (c == '&')
+ no = 0;
+ else if (c == '\\' && '0' <= *src && *src <= '9')
+ no = *src++ - '0';
+ else
+ no = -1;
+ if (no < 0) { /* Ordinary character. */
+ if (c == '\\' && (*src == '\\' || *src == '&'))
+ c = *src++;
+ *dst++ = c;
+ } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
+ len = prog->endp[no] - prog->startp[no];
+ (void) strncpy(dst, prog->startp[no], len);
+ dst += len;
+ if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
+ regerror("damaged match string");
+ return;
+ }
+ }
+ }
+ *dst++ = '\0';
+}
diff --git a/winsup/cygwin/rmsym b/winsup/cygwin/rmsym
new file mode 100755
index 000000000..685802684
--- /dev/null
+++ b/winsup/cygwin/rmsym
@@ -0,0 +1,11 @@
+#!/bin/sh
+lib=$1; shift
+nm=$1; shift
+ar=$1; shift
+ranlib=$1; shift
+grepit=`echo $* | sed 's/ /|__imp__/g'`
+[ -n "$grepit" ] && grepit="__imp__$grepit"
+objs=`$nm $lib | awk -F: '/^d[0-9]*.o:/ {obj=$1} '"/$grepit/"'{print obj}'`
+[ -n "$objs" ] || exit 1
+$ar d $lib $objs
+$ranlib $lib
diff --git a/winsup/cygwin/speclib b/winsup/cygwin/speclib
new file mode 100755
index 000000000..f9c467685
--- /dev/null
+++ b/winsup/cygwin/speclib
@@ -0,0 +1,12 @@
+#!/bin/sh
+case "$1" in
+ -v) v="-v"; shift
+esac
+lib=$1; shift
+nm=$1; shift
+dlltool=$1; shift
+def=$1; shift
+trap "rm /tmp/$$.def" 0 1 2 15
+(echo "LIBRARY cygwin1.dll
+EXPORTS"; $nm --extern-only --defined-only $* | sed -e '/^[ ]*$/d' -e '/:$/d' -e 's/^.* _\(.*\)/\1/' | grep $v -f - -w $def |egrep -vi '^library|exports|^$' | sort) > /tmp/$$.def
+exec $dlltool -d /tmp/$$.def -l "$lib" -D /dev/null
diff --git a/winsup/cygwin/winbase.h b/winsup/cygwin/winbase.h
new file mode 100644
index 000000000..d72bb0893
--- /dev/null
+++ b/winsup/cygwin/winbase.h
@@ -0,0 +1,83 @@
+#include_next "winbase.h"
+
+#ifndef _WINBASE2_H
+#define _WINBASE2_H
+
+extern __inline__ long ilockincr (long *m)
+{
+ register int __res;
+ __asm__ __volatile__ ("\n\
+ movl $1,%0\n\
+ lock xadd %0,(%1)\n\
+ inc %0\n\
+ ": "=a" (__res), "=r" (m): "1" (m));
+ return __res;
+}
+extern __inline__ long ilockdecr (long *m)
+{
+ register int __res;
+ __asm__ __volatile__ ("\n\
+ movl $0xffffffff,%0\n\
+ lock xadd %0,(%1)\n\
+ dec %0\n\
+ ": "=a" (__res), "=r" (m): "1" (m));
+ return __res;
+}
+extern __inline__ long ilockexch (long *t, long v)
+{
+ register int __res;
+ __asm__ __volatile__ ("\n\
+ movl (%2),%0\n\
+1: lock cmpxchgl %3,(%1)\n\
+ jne 1b\n\
+ ": "=a" (__res), "=c" (t): "1" (t), "d" (v));
+ return __res;
+}
+
+#undef InterlockedIncrement
+#define InterlockedIncrement ilockincr
+#undef InterlockedDecrement
+#define InterlockedDecrement ilockdecr
+#undef InterlockedExchange
+#define InterlockedExchange ilockexch
+
+extern long tls_ix;
+extern char * volatile *__stackbase __asm__ ("%fs:4");
+
+extern __inline__ DWORD
+my_tlsalloc ()
+{
+ DWORD n = ilockdecr (&tls_ix);
+ __stackbase[tls_ix] = NULL;
+ return n;
+}
+
+extern __inline__ BOOL
+my_tlssetvalue (DWORD ix, void *val)
+{
+ __stackbase[ix] = (char *) val;
+ return 1;
+}
+
+extern __inline__ void *
+my_tlsgetvalue (DWORD ix)
+{
+ return __stackbase[ix];
+}
+
+extern __inline__ BOOL
+my_tlsfree (DWORD ix)
+{
+ /* nothing for now */
+ return 1;
+}
+
+#undef TlsAlloc
+#define TlsAlloc my_tlsalloc
+#undef TlsGetValue
+#define TlsGetValue my_tlsgetvalue
+#undef TlsSetValue
+#define TlsSetValue my_tlssetvalue
+#undef TlsFree
+#define TlsFree my_tlsfree
+#endif /*_WINBASE2_H*/