diff options
author | Christopher Faylor <me@cgf.cx> | 2001-04-01 00:06:17 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-04-01 00:06:17 +0000 |
commit | f611148366ee3934d16824f8a973177aaece0aa8 (patch) | |
tree | b27e26f288e5497966f358cb47783a1bff9a5d19 | |
parent | ab57d1463946e37a5b7ce25498b3b42c3f617666 (diff) | |
download | newlib-f611148366ee3934d16824f8a973177aaece0aa8.zip newlib-f611148366ee3934d16824f8a973177aaece0aa8.tar.gz newlib-f611148366ee3934d16824f8a973177aaece0aa8.tar.bz2 |
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 15 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 11 | ||||
-rw-r--r-- | winsup/cygwin/signal.cc | 16 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.h | 22 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 75 | ||||
-rw-r--r-- | winsup/cygwin/wait.cc | 123 |
7 files changed, 151 insertions, 117 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bede4b6..3a88771 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +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 diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 8374032..7efba7f 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -864,10 +864,10 @@ setup_handler (int sig, void *handler, struct sigaction& siga) } else { - res = SetEvent (signal_arrived); // For an EINTR case - sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); /* Clear any waiting threads prior to dispatching to handler function */ proc_subproc (PROC_CLEARWAIT, 1); + res = SetEvent (signal_arrived); // For an EINTR case + sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); } if (th) @@ -1127,6 +1127,13 @@ reset_signal_arrived () sigproc_printf ("reset signal_arrived"); } +int +sigframe::call_signal_handler () +{ + unregister (); + ::call_signal_handler (); +} + int __stdcall call_signal_handler () { diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index ea4a439..bc3746b 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -99,7 +99,7 @@ sigprocmask (int sig, const sigset_t *set, sigset_t *oldset) if (sig < 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("SIG_ERR = sigprocmask sig %d out of range", sig); + syscall_printf ("SIG_ERR = sigprocmask signal %d out of range", sig); return -1; } @@ -182,7 +182,7 @@ _kill (pid_t pid, int sig) if (sig < 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("sig %d out of range", sig); + syscall_printf ("signal %d out of range", sig); return -1; } @@ -202,7 +202,7 @@ kill_pgrp (pid_t pid, int sig) int found = 0; int killself = 0; - sigproc_printf ("pid %d, sig %d", pid, sig); + sigproc_printf ("pid %d, signal %d", pid, sig); winpids pids; for (unsigned i = 0; i < pids.npids; i++) @@ -247,12 +247,12 @@ killpg (pid_t pgrp, int sig) extern "C" int sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) { - sigproc_printf ("sig %d, newact %p, oldact %p", sig, newact, oldact); + sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact); /* check that sig is in right range */ if (sig < 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("SIG_ERR = sigaction sig %d out of range", sig); + syscall_printf ("SIG_ERR = sigaction signal %d out of range", sig); return -1; } @@ -286,7 +286,7 @@ sigaddset (sigset_t *set, const int sig) if (sig <= 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("SIG_ERR = sigaddset sig %d out of range", sig); + syscall_printf ("SIG_ERR = sigaddset signal %d out of range", sig); return -1; } @@ -301,7 +301,7 @@ sigdelset (sigset_t *set, const int sig) if (sig <= 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("SIG_ERR = sigdelset sig %d out of range", sig); + syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig); return -1; } @@ -316,7 +316,7 @@ sigismember (const sigset_t *set, int sig) if (sig <= 0 || sig >= NSIG) { set_errno (EINVAL); - syscall_printf ("SIG_ERR = sigdelset sig %d out of range", sig); + syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig); return -1; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 9eae394..9a8f602 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -736,7 +736,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp) if (!wait_for_completion) { rc = WAIT_OBJECT_0; - sigproc_printf ("Not waiting for sigcomplete. its_me %d sig %d", its_me, sig); + sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d", its_me, sig); if (!its_me) ForceCloseHandle (thiscatch); } @@ -765,7 +765,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp) { /* It's an error unless sig_loop_wait == 0 (the process is exiting). */ if (!no_signals_available ()) - system_printf ("wait for sig_complete event failed, sig %d, rc %d, %E", + system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E", sig, rc); set_errno (ENOSYS); rc = -1; @@ -1144,7 +1144,7 @@ wait_sig (VOID *) (sigismember (&myself->getsigmask (), sig) || (sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) { - sigproc_printf ("sig %d blocked", sig); + sigproc_printf ("signal %d blocked", sig); break; } diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index c67574d..1543aa1 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -49,6 +49,17 @@ class sigframe { private: sigthread *st; + void unregister () + { + if (st) + { + EnterCriticalSection (&st->lock); + st->frame = 0; + st->release_winapi_lock (); + LeaveCriticalSection (&st->lock); + st = NULL; + } + } public: void set (sigthread &t, DWORD ebp) @@ -70,15 +81,10 @@ public: } ~sigframe () { - if (st) - { - EnterCriticalSection (&st->lock); - st->frame = 0; - st->release_winapi_lock (); - LeaveCriticalSection (&st->lock); - st = NULL; - } + unregister (); } + + int call_signal_handler (); }; extern sigthread mainthread; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 625d150..a79f88d 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -229,51 +229,54 @@ setsid (void) extern "C" ssize_t _read (int fd, void *ptr, size_t len) { - sigframe thisframe (mainthread); + int res; + fhandler_base *fh; extern int sigcatchers; - bool sawsig; -beg: - sawsig = 0; - if (fdtab.not_open (fd)) + while (1) { - set_errno (EBADF); - return -1; - } + sigframe thisframe (mainthread); - // set_sig_errno (0); - fhandler_base *fh = fdtab[fd]; - DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; + if (fdtab.not_open (fd)) + { + set_errno (EBADF); + return -1; + } - /* 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); + // set_sig_errno (0); + fh = fdtab[fd]; + DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; - int res; - 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)) - { - if (!wait) - set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */ - else - set_sig_errno (EINTR); - res = -1; - goto out; - } + /* 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); - /* Check to see if this is a background read from a "tty", - sending a SIGTTIN, if appropriate */ - res = fh->bg_check (SIGTTIN); - if (res > bg_eof) - { - myself->process_state |= PID_TTYIN; - res = fh->read (ptr, len); - myself->process_state &= ~PID_TTYIN; + 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)) + { + if (!wait) + set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */ + else + set_sig_errno (EINTR); + res = -1; + goto out; + } + + /* Check to see if this is a background read from a "tty", + sending a SIGTTIN, if appropriate */ + res = fh->bg_check (SIGTTIN); + if (res > bg_eof) + { + myself->process_state |= PID_TTYIN; + res = fh->read (ptr, len); + myself->process_state &= ~PID_TTYIN; + } + + out: + if (res >= 0 || get_errno () == EINTR || !thisframe.call_signal_handler ()) + break; } -out: - if (res < 0 && get_errno () == EINTR && call_signal_handler ()) - goto beg; syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (), ptr, len, fh->get_r_binary (), get_errno ()); MALLOC_CHECK; diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc index a5ed68c..0fa3005 100644 --- a/winsup/cygwin/wait.cc +++ b/winsup/cygwin/wait.cc @@ -50,71 +50,74 @@ wait4 (int intpid, int *status, int options, struct rusage *r) int res; waitq *w; HANDLE waitfor; - sigframe thisframe (mainthread); bool sawsig; -beg: - sawsig = 0; - if (options & ~(WNOHANG | WUNTRACED)) + while (1) { - set_errno (EINVAL); - return -1; + sigframe thisframe (mainthread); + sawsig = 0; + if (options & ~(WNOHANG | WUNTRACED)) + { + set_errno (EINVAL); + return -1; + } + + if (r) + memset (r, 0, sizeof (*r)); + + if ((w = (waitq *) waitq_storage.get ()) == NULL) + w = (waitq *) waitq_storage.create (); + + w->pid = intpid; + w->options = options; + w->rusage = r; + sigproc_printf ("calling proc_subproc, pid %d, options %d", + w->pid, w->options); + if (!proc_subproc (PROC_WAIT, (DWORD)w)) + { + set_errno (ENOSYS); + paranoid_printf ("proc_subproc returned 0"); + res = -1; + goto done; + } + + if ((waitfor = w->ev) == NULL) + goto nochildren; + + res = WaitForSingleObject (waitfor, INFINITE); + + sigproc_printf ("%d = WaitForSingleObject (...)", res); + + if (w->ev == NULL) + { + nochildren: + /* found no children */ + set_errno (ECHILD); + res = -1; + goto done; + } + + if (w->status == -1) + { + set_sig_errno (EINTR); + sawsig = 1; + res = -1; + } + else if (res != WAIT_OBJECT_0) + { + /* We shouldn't set errno to any random value if we can help it. + See the Posix manual for a list of valid values for `errno'. */ + set_errno (EINVAL); + res = -1; + } + else if ((res = w->pid) != 0 && status) + *status = w->status; + + done: + if (!sawsig || !thisframe.call_signal_handler ()) + break; } - if (r) - memset (r, 0, sizeof (*r)); - - if ((w = (waitq *) waitq_storage.get ()) == NULL) - w = (waitq *) waitq_storage.create (); - - w->pid = intpid; - w->options = options; - w->rusage = r; - sigproc_printf ("calling proc_subproc, pid %d, options %d", - w->pid, w->options); - if (!proc_subproc (PROC_WAIT, (DWORD)w)) - { - set_errno (ENOSYS); - paranoid_printf ("proc_subproc returned 0"); - res = -1; - goto done; - } - - if ((waitfor = w->ev) == NULL) - goto nochildren; - - res = WaitForSingleObject (waitfor, INFINITE); - - sigproc_printf ("%d = WaitForSingleObject (...)", res); - - if (w->ev == NULL) - { - nochildren: - /* found no children */ - set_errno (ECHILD); - res = -1; - goto done; - } - - if (w->status == -1) - { - set_sig_errno (EINTR); - sawsig = 1; - res = -1; - } - else if (res != WAIT_OBJECT_0) - { - /* We shouldn't set errno to any random value if we can help it. - See the Posix manual for a list of valid values for `errno'. */ - set_errno (EINVAL); - res = -1; - } - else if ((res = w->pid) != 0 && status) - *status = w->status; - -done: - if (sawsig && call_signal_handler ()) - goto beg; sigproc_printf ("intpid %d, status %p, w->status %d, options %d, res %d", intpid, status, w->status, options, res); w->status = -1; |