diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0935486f4..ca302eb75 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +Sat Sep 22 12:44:57 2001 Christopher Faylor + + * 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 * fhandler.cc (fhandler_base::set_inheritance): Just use diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index c32ac6733..e8293b91f 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -105,7 +105,6 @@ makethread (LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, { DWORD tid; HANDLE h; - SECURITY_ATTRIBUTES *sa; thread_start *info; /* Various information needed by the newly created thread */ for (;;) @@ -123,16 +122,9 @@ out: info->func = start; /* Real function to start */ info->arg = param; /* The single parameter to the thread */ - if (*name != '+') - sa = &sec_none_nih; /* The handle should not be inherited by subprocesses. */ - else - { - name++; - sa = &sec_none; /* The handle should be inherited by subprocesses. */ - } - - if ((h = CreateThread (sa, 0, thread_stub, (VOID *) info, flags, &tid))) - regthread (name, tid); /* Register this name/thread id for debugging output. */ + if ((h = CreateThread (&sec_none_nih, 0, thread_stub, (VOID *) info, flags, + &tid))) + regthread (name, tid); /* Register for debugging output. */ return h; } diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 37607cd8e..0102371a7 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -849,8 +849,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga) if (th) { interrupted = interrupt_on_return (th, sig, handler, siga); - if (!interrupted) - LeaveCriticalSection (&th->lock); + LeaveCriticalSection (&th->lock); } else if (interruptible (cx.Eip)) interrupted = interrupt_now (&cx, sig, handler, siga); @@ -870,9 +869,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga) sigproc_printf ("couldn't send signal %d", sig); } - if (th) - LeaveCriticalSection (&th->lock); - if (!hth) sigproc_printf ("good. Didn't suspend main thread, th %p", th); else diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index ff3946512..8ed52ffe9 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1289,8 +1289,8 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode) 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 non - existant directory. */ + 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) { @@ -1493,23 +1493,6 @@ fhandler_dev_null::dump (void) paranoid_printf ("here"); } -/**********************************************************************/ -/* fhandler_pipe */ - -fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) : - fhandler_base (devtype, name) -{ - set_cb (sizeof *this); -} - -off_t -fhandler_pipe::lseek (off_t offset, int whence) -{ - debug_printf ("(%d, %d)", offset, whence); - set_errno (ESPIPE); - return -1; -} - void fhandler_base::set_inheritance (HANDLE &h, int not_inheriting) { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 94c623f8b..79d039e64 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -435,17 +435,20 @@ public: class fhandler_pipe: public fhandler_base { + HANDLE guard; public: fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE); off_t lseek (off_t offset, int whence); - /* This strange test is due to the fact that we can't rely on - Windows shells to "do the right thing" with pipes. Apparently - the can keep one end of the pipe open when it shouldn't be. */ BOOL is_slow () {return !wincap.has_unreliable_pipes ();} select_record *select_read (select_record *s); select_record *select_write (select_record *s); select_record *select_except (select_record *s); int ready_for_read (int fd, DWORD howlong, int ignra); + void set_close_on_exec (int val); + int read (void *ptr, size_t len); + int close (); + void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);} + int dup (fhandler_base *child); }; class fhandler_dev_raw: public fhandler_base diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c4d122f4d..ffd48e47a 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -198,7 +198,7 @@ sync_with_parent(const char *s, bool hang_self) debug_printf ("signalling parent: %s", s); /* Tell our parent we're waiting. */ if (!SetEvent (child_proc_info->subproc_ready)) - api_fatal ("fork child - SetEvent failed, %E"); + api_fatal ("fork child - SetEvent for %s failed, %E", s); if (hang_self) { HANDLE h = child_proc_info->forker_finished; @@ -210,13 +210,14 @@ sync_with_parent(const char *s, bool hang_self) switch (psync_rc) { case WAIT_TIMEOUT: - api_fatal ("WFSO timed out"); + api_fatal ("WFSO timed out for %s", s); break; case WAIT_FAILED: if (GetLastError () == ERROR_INVALID_HANDLE && WaitForSingleObject (child_proc_info->forker_finished, 1) != WAIT_FAILED) break; - api_fatal ("WFSO failed, fork_finished %p, %E", child_proc_info->forker_finished); + api_fatal ("WFSO failed for %s, fork_finished %p, %E", s, + child_proc_info->forker_finished); break; default: debug_printf ("no problems"); diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 1c1d0ad80..04a1fbece 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -19,6 +19,60 @@ details. */ #include "cygheap.h" #include "thread.h" +fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) : + fhandler_base (devtype, name), guard (0) +{ + set_cb (sizeof *this); +} + +off_t +fhandler_pipe::lseek (off_t offset, int whence) +{ + debug_printf ("(%d, %d)", offset, whence); + set_errno (ESPIPE); + return -1; +} + +void +fhandler_pipe::set_close_on_exec (int val) +{ + this->fhandler_base::set_close_on_exec (val); + set_inheritance (guard, val); +} + +int +fhandler_pipe::read (void *in_ptr, size_t in_len) +{ + int res = this->fhandler_base::read (in_ptr, in_len); + ReleaseMutex (guard); + return res; +} + +int fhandler_pipe::close () +{ + int res = this->fhandler_base::close (); + if (guard) + CloseHandle (guard); + return res; +} + +int +fhandler_pipe::dup (fhandler_base *child) +{ + int res = this->fhandler_base::dup (child); + if (res) + return res; + + fhandler_pipe *ftp = (fhandler_pipe *) child; + + if (guard == NULL) + ftp->guard = NULL; + else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1, + DUPLICATE_SAME_ACCESS)) + return -1; + return 0; +} + static int make_pipe (int fildes[2], unsigned int psize, int mode) { @@ -53,6 +107,7 @@ make_pipe (int fildes[2], unsigned int psize, int mode) fildes[1] = fdw; res = 0; + fhr->create_guard (sa); } syscall_printf ("%d = make_pipe ([%d, %d], %d, %p)", res, fdr, fdw, psize, mode); diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 94326dc41..67365d925 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -123,14 +123,6 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set *dummy_exceptfds = allocfd_set (maxfds); sigframe thisframe (mainthread); -#if 0 - if (n > FD_SETSIZE) - { - set_errno (EINVAL); - return -1; - } -#endif - select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to); if (!readfds) @@ -407,7 +399,7 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *) } static int -peek_pipe (select_record *s, int ignra) +peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL) { int n = 0; int gotone = 0; @@ -454,8 +446,15 @@ peek_pipe (select_record *s, int ignra) } } - if (fh->get_device() != FH_PIPEW && - !PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL)) + if (fh->get_device () == FH_PIPEW) + /* nothing */; + else if (guard_mutex && WaitForSingleObject (guard_mutex, 0) != WAIT_OBJECT_0) + { + select_printf ("%s, couldn't get mutex %p, %E", fh->get_name (), + guard_mutex); + n = 0; + } + else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL)) { select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ()); n = -1; @@ -496,8 +495,20 @@ poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds, set_bits (me, readfds, writefds, exceptfds) : 0; } - -MAKEready(pipe) +int +fhandler_pipe::ready_for_read (int fd, DWORD howlong, int ignra) +{ + select_record me (this); + me.fd = fd; + (void) select_read (&me); + while (!peek_pipe (&me, ignra, guard) && howlong == INFINITE) + if (fd >= 0 && cygheap->fdtab.not_open (fd)) + break; + else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) + break; + select_printf ("returning %d", me.read_ready); + return me.read_ready; +} static int start_thread_pipe (select_record *me, select_stuff *stuff); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 607fa81ab..7f621d3ea 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -819,7 +819,7 @@ subproc_init (void) * the hchildren array. */ events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); - if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "+proc"))) + if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "proc"))) system_printf ("cannot create wait_subproc thread, %E"); ProtectHandle (events[0]); ProtectHandle (hwait_subproc); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 1453f4fed..a98b23a50 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -295,7 +295,7 @@ _read (int fd, void *ptr, size_t len) /* Could block, so let user know we at least got here. */ syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); - if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) + if (wait && (/*!sigcatchers || */!fh->is_slow () || fh->get_r_no_interrupt ())) debug_printf ("non-interruptible read\n"); else if (!fh->ready_for_read (fd, wait, 0)) {