aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-04-01 00:06:17 +0000
committerChristopher Faylor <me@cgf.cx>2001-04-01 00:06:17 +0000
commitf611148366ee3934d16824f8a973177aaece0aa8 (patch)
treeb27e26f288e5497966f358cb47783a1bff9a5d19
parentab57d1463946e37a5b7ce25498b3b42c3f617666 (diff)
downloadnewlib-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/ChangeLog15
-rw-r--r--winsup/cygwin/exceptions.cc11
-rw-r--r--winsup/cygwin/signal.cc16
-rw-r--r--winsup/cygwin/sigproc.cc6
-rw-r--r--winsup/cygwin/sigproc.h22
-rw-r--r--winsup/cygwin/syscalls.cc75
-rw-r--r--winsup/cygwin/wait.cc123
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;