summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/sigproc.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-01-19 05:46:54 +0000
committerChristopher Faylor <me@cgf.cx>2004-01-19 05:46:54 +0000
commitf6936c48f382a12b7b67fda40352b8e377662743 (patch)
tree7626bb0ad181997983640b51113c01231992c729 /winsup/cygwin/sigproc.cc
parent49fec4c011d14ee74fa4811559009c623ceab82e (diff)
downloadcygnal-f6936c48f382a12b7b67fda40352b8e377662743.tar.gz
cygnal-f6936c48f382a12b7b67fda40352b8e377662743.tar.bz2
cygnal-f6936c48f382a12b7b67fda40352b8e377662743.zip
* cygwin/include/signal.h: Add copyright notice.
* cygwin.din: Make clock SIGFE. Add clock_gettime, sigwaitinfo, timer_create, timer_delete, timer_settime. * include/cygwin/version.h: Reflect above additions. * fork.cc (fork_child): Call fixup_timers_after_fork. * signal.cc (sigwait): Remove unused variable. * timer.cc: New file. (clock_gettime): Define new function. (timer_tracker): Define new struct used by timer functions. (timer_tracker::timer_tracker): New function. (to_us): New function. (timer_thread): New function. (timer_tracker::settime): New function. (timer_create): New function. (timer_settime): New function. (timer_delete): New function. (fixup_timers_after_fork): New function. * cygthread.cc: Bump thread count. * signal.cc (sigwaitinfo): Define new function. (sigwait): Redefine based on sigwaitinfo. * include/cygwin/signal.h (sigwaitinfo): Declare. (sigwait): Ditto. * dtable.cc (dtable::vfork_parent_restore): Avoid double close of ctty when ctty == ctty_on_hold. * cygtls.h (_threadinfo::threadkill): New element. (_threadinfo::set_threadkill): Declare new function. (_threadinfo::reset_threadkill): Declare new function. * dcrt0.cc (dcrt0_1): Call here so that it will be possible to attach to running process with #(*& Windows Me/9x. (initial_env): Try to initialize strace if uninitialized. * gendef: Don't zero signal if threadkill is set since that will happen in the called function. * signal.cc (sigwait): Ensure cleanup in error conditions. * sigproc.cc (sig_send): Clear packet mask storage. (wait_subproc): Fill in child exit code in siginfo_t structure. * thread.cc (pthread_kill): Set threadkill flag. * tlsoffsets.h: Regenerate. Throughout, use siginfo_t to fill out all signal information for "kernel" signals. * cygtls.h (_threadinfo::set_siginfo): Declare new function. * cygtls.cc (_threadinfo::set_siginfo): Define new function. * dcrt0.cc (do_exit): Accommodate siginfo_t considerations. * exceptions.cc (handle_exceptions): Ditto. (sig_handle_tty_stop): Ditto. (ctrl_c_handler): Use killsys() to send signal. (sigpacket::process): Rename from sig_handle. Use siginfo_t field from sigpacket for everything. (tty_min::kill_pgrp): Accommodate siginfo_t considerations. (fhandler_termios::bg_check): Ditto. * fhandler_tty.cc (fhandler_tty_slave::ioctl): Use killsys() to send signal. * signal.cc (kill_worker): Rewrite to use siginfo_t second argument. (kill_pgrp): Ditto. (kill0): Define new function pulled from kill(). (kill): Rewrite as frontend to kill0. (killsys): Define new function. * sigproc.cc (sigelem): Eliminate. (sigpacket): Move to sigproc.h. Subsume sigelem. (pending_signals): Use sigpacket rather than sigelem for everything. (sig_clear): Ditto. (wait_sig): Ditto. (sig_send): Rewrite to use siginfo_t argument. (sig_send): New function wratpper to sig_send with siginfo_t argument. (wait_subproc): Accommodate siginfo_t considerations. * thread.cc (pthread_kill): Ditto. * sigproc.h (sigpacket): Move here. (sigpacket::process): Declare "new" function. (sig_handle): Eliminate declaration. (sig_send): Declare with new paramaters. (killsys): Declare new function. (kill_pgrp): Declare. * winsup.h: Move some signal-specific stuff to sigproc.h. * include/cygwin/signal.h: Tweak some siginfo_t stuff.
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc140
1 files changed, 75 insertions, 65 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e143a8239..a1c2d305d 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -48,41 +48,22 @@ details. */
#define NZOMBIES 256
-struct sigelem
-{
- int sig;
- int pid;
- _threadinfo *tls;
- class sigelem *next;
- friend class pending_signals;
- friend int __stdcall sig_dispatch_pending ();
-};
-
class pending_signals
{
- sigelem sigs[NSIG + 1];
- sigelem start;
- sigelem *end;
- sigelem *prev;
- sigelem *curr;
+ sigpacket sigs[NSIG + 1];
+ sigpacket start;
+ sigpacket *end;
+ sigpacket *prev;
+ sigpacket *curr;
int empty;
public:
void reset () {curr = &start; prev = &start;}
- void add (int sig, int pid, _threadinfo *tls);
+ void add (sigpacket&);
void del ();
- sigelem *next ();
+ sigpacket *next ();
friend int __stdcall sig_dispatch_pending ();
};
-struct sigpacket
-{
- int sig;
- pid_t pid;
- HANDLE wakeup;
- sigset_t *mask;
- _threadinfo *tls;
-};
-
static pending_signals sigqueue;
struct sigaction *global_sigs;
@@ -563,9 +544,9 @@ sig_clear (int target_sig)
else
{
sigqueue.reset ();
- sigelem *q;
+ sigpacket *q;
while ((q = sigqueue.next ()))
- if (q->sig == target_sig)
+ if (q->si.si_signo == target_sig)
{
sigqueue.del ();
break;
@@ -670,13 +651,22 @@ sigproc_terminate (void)
return;
}
+int __stdcall
+sig_send (_pinfo *p, int sig)
+{
+ siginfo_t si;
+ si.si_signo = sig;
+ si.si_code = SI_KERNEL;
+ si.si_pid = si.si_uid = si.si_errno = 0;
+ return sig_send (p, si);
+}
+
/* Send a signal to another process by raising its signal semaphore.
- * If pinfo *p == NULL, send to the current process.
- * If sending to this process, wait for notification that a signal has
- * completed before returning.
- */
+ If pinfo *p == NULL, send to the current process.
+ If sending to this process, wait for notification that a signal has
+ completed before returning. */
int __stdcall
-sig_send (_pinfo *p, int sig, void *tls)
+sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls)
{
int rc = 1;
bool its_me;
@@ -703,11 +693,11 @@ sig_send (_pinfo *p, int sig, void *tls)
if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
{
sigproc_printf ("invalid pid %d(%x), signal %d",
- p->pid, p->process_state, sig);
+ p->pid, p->process_state, si.si_signo);
goto out;
}
- sigproc_printf ("pid %d, signal %d, its_me %d", p->pid, sig, its_me);
+ sigproc_printf ("pid %d, signal %d, its_me %d", p->pid, si.si_signo, its_me);
if (its_me)
{
@@ -740,16 +730,21 @@ sig_send (_pinfo *p, int sig, void *tls)
sigset_t pending;
if (!its_me)
pack.mask = NULL;
- else if (sig == __SIGPENDING)
+ else if (si.si_signo == __SIGPENDING)
pack.mask = &pending;
- else if (sig == __SIGFLUSH || sig > 0)
+ else if (si.si_signo == __SIGFLUSH || si.si_signo > 0)
pack.mask = &myself->getsigmask ();
else
pack.mask = NULL;
- pack.sig = sig;
+ pack.si = si;
+ if (!pack.si.si_pid)
+ pack.si.si_pid = myself->pid;
+ if (!pack.si.si_uid)
+ pack.si.si_uid = myself->uid;
pack.pid = myself->pid;
pack.tls = (_threadinfo *) tls;
+ pack.mask_storage = 0;
DWORD nb;
if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
{
@@ -767,7 +762,7 @@ sig_send (_pinfo *p, int sig, void *tls)
sigproc_printf ("I'm going away now");
else
system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
- sig, p->pid, sendsig);
+ si.si_signo, p->pid, sendsig);
}
goto out;
}
@@ -787,7 +782,8 @@ sig_send (_pinfo *p, int sig, void *tls)
else
{
rc = WAIT_OBJECT_0;
- sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d", its_me, sig);
+ sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d",
+ its_me, si.si_signo);
if (!its_me)
ForceCloseHandle (sendsig);
}
@@ -798,7 +794,7 @@ sig_send (_pinfo *p, int sig, void *tls)
{
if (!no_signals_available ())
system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E",
- sig, rc);
+ si.si_signo, rc);
set_errno (ENOSYS);
rc = -1;
}
@@ -807,13 +803,13 @@ sig_send (_pinfo *p, int sig, void *tls)
call_signal_handler_now ();
out:
- if (sig != __SIGPENDING)
+ if (si.si_signo != __SIGPENDING)
/* nothing */;
else if (!rc)
rc = (int) pending;
else
rc = SIG_BAD_MASK;
- sigproc_printf ("returning %p from sending signal %d", rc, sig);
+ sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo);
return rc;
}
@@ -1009,20 +1005,20 @@ talktome ()
has been handled, as per POSIX. */
void
-pending_signals::add (int sig, int pid, _threadinfo *tls)
+pending_signals::add (sigpacket& pack)
{
- sigelem *se;
+ sigpacket *se;
for (se = start.next; se; se = se->next)
- if (se->sig == sig)
+ if (se->si.si_signo == pack.si.si_signo)
return;
- while (sigs[empty].sig)
+ while (sigs[empty].si.si_signo)
if (++empty == NSIG)
empty = 0;
se = sigs + empty;
- se->sig = sig;
+ *se = pack;
+ se->mask_storage = *(pack.mask);
+ se->mask = &se->mask_storage;
se->next = NULL;
- se->tls = tls;
- se->pid = pid;
if (end)
end->next = se;
end = se;
@@ -1034,9 +1030,9 @@ pending_signals::add (int sig, int pid, _threadinfo *tls)
void
pending_signals::del ()
{
- sigelem *next = curr->next;
+ sigpacket *next = curr->next;
prev->next = next;
- curr->sig = 0;
+ curr->si.si_signo = 0;
#ifdef DEBUGGING
curr->next = NULL;
#endif
@@ -1046,10 +1042,10 @@ pending_signals::del ()
curr = next;
}
-sigelem *
+sigpacket *
pending_signals::next ()
{
- sigelem *res;
+ sigpacket *res;
prev = curr;
if (!curr || !(curr = curr->next))
res = NULL;
@@ -1125,7 +1121,7 @@ wait_sig (VOID *self)
continue;
}
- if (!pack.sig)
+ if (!pack.si.si_signo)
{
#ifdef DEBUGGING
system_printf ("zero signal?");
@@ -1140,8 +1136,8 @@ wait_sig (VOID *self)
pack.mask = &dummy_mask;
}
- sigelem *q;
- switch (pack.sig)
+ sigpacket *q;
+ switch (pack.si.si_signo)
{
case __SIGCOMMUNE:
talktome ();
@@ -1154,30 +1150,30 @@ wait_sig (VOID *self)
unsigned bit;
sigqueue.reset ();
while ((q = sigqueue.next ()))
- if (myself->getsigmask () & (bit = SIGTOMASK (q->sig)))
+ if (myself->getsigmask () & (bit = SIGTOMASK (q->si.si_signo)))
*pack.mask |= bit;
break;
case __SIGFLUSH:
sigqueue.reset ();
while ((q = sigqueue.next ()))
- if (sig_handle (q->sig, *pack.mask, q->pid, q->tls) > 0)
+ if (q->process () > 0)
sigqueue.del ();
break;
default:
- if (pack.sig < 0)
- sig_clear (-pack.sig);
+ if (pack.si.si_signo < 0)
+ sig_clear (-pack.si.si_signo);
else
{
- int sigres = sig_handle (pack.sig, *pack.mask, pack.pid, pack.tls);
+ int sigres = pack.process ();
if (sigres <= 0)
{
#ifdef DEBUGGING2
if (!sigres)
system_printf ("Failed to arm signal %d from pid %d", pack.sig, pack.pid);
#endif
- sigqueue.add (pack.sig, pack.pid, pack.tls);// FIXME: Shouldn't add this in !sh condition
+ sigqueue.add (pack); // FIXME: Shouldn't add this in !sh condition
}
- if (pack.sig == SIGCHLD)
+ if (pack.si.si_signo == SIGCHLD)
proc_subproc (PROC_CLEARWAIT, 0);
}
break;
@@ -1245,6 +1241,20 @@ wait_subproc (VOID *)
rc -= WAIT_OBJECT_0;
if (rc-- != 0)
{
+ siginfo_t si;
+ si.si_signo = SIGCHLD;
+ si.si_code = SI_KERNEL;
+ si.si_pid = pchildren[rc]->pid;
+ si.si_uid = pchildren[rc]->uid;
+ si.si_errno = 0;
+ GetExitCodeProcess (hchildren[rc], (DWORD *) &si.si_status);
+#if 0 // FIXME: This is tricky to get right
+ si.si_utime = pchildren[rc]->rusage_self.ru_utime;
+ si.si_stime = pchildren[rc].rusage_self.ru_stime;
+#else
+ si.si_utime = 0;
+ si.si_stime = 0;
+#endif
rc = proc_subproc (PROC_CHILDTERMINATED, rc);
if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting
@@ -1253,7 +1263,7 @@ wait_subproc (VOID *)
to avoid the proc_subproc lock since the signal thread will eventually
be calling proc_subproc and could unnecessarily block. */
if (rc)
- sig_send (myself_nowait, SIGCHLD);
+ sig_send (myself_nowait, si);
}
sigproc_printf ("looping");
}