aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog4
-rw-r--r--winsup/cygwin/cygtls.cc7
-rw-r--r--winsup/cygwin/cygtls.h3
-rw-r--r--winsup/cygwin/dcrt0.cc6
-rw-r--r--winsup/cygwin/exceptions.cc157
-rw-r--r--winsup/cygwin/fhandler_termios.cc16
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rwxr-xr-xwinsup/cygwin/gentls_offsets4
-rw-r--r--winsup/cygwin/include/cygwin/signal.h46
-rw-r--r--winsup/cygwin/signal.cc70
-rw-r--r--winsup/cygwin/sigproc.cc132
-rw-r--r--winsup/cygwin/sigproc.h24
-rw-r--r--winsup/cygwin/thread.cc6
-rw-r--r--winsup/cygwin/winsup.h4
14 files changed, 294 insertions, 189 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f1e3f2f..16aa73f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,7 @@
+2004-01-15 Christopher Faylor <cgf@redhat.com>
+
+ * gentls_offsets: Reinstate unlink of temp files.
+
2004-01-14 Christopher Faylor <cgf@redhat.com>
* fhandler_console.cc (fhandler_console::close): Fix debugging output.
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index 5c9fa61..ecec3f5 100644
--- a/winsup/cygwin/cygtls.cc
+++ b/winsup/cygwin/cygtls.cc
@@ -20,6 +20,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "cygthread.h"
+#include "sigproc.h"
class sentry
{
@@ -189,6 +190,12 @@ _threadinfo::find_tls (int sig)
return res;
}
+void
+_threadinfo::set_siginfo (sigpacket *pack)
+{
+ infodata = pack->si;
+}
+
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
static int
handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *, void *)
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 779e42b..ab82bac 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -120,7 +120,7 @@ struct _threadinfo
static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
static struct _threadinfo *find_tls (int sig);
void remove (DWORD);
- void push (__stack_t, bool = false);
+ void push (__stack_t, bool = false) __attribute__ ((regparm (3)));
__stack_t pop ();
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
void set_state (bool);
@@ -131,6 +131,7 @@ struct _threadinfo
__attribute__((regparm(3)));
void init_threadlist_exceptions (struct _exception_list *);
operator HANDLE () const {return tid->win32_obj_id;}
+ void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3)));
/*gentls_offsets*/
};
#pragma pack(pop)
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 3d6b7a8..4b905b7 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1042,9 +1042,13 @@ do_exit (int status)
/* Kill orphaned children on group leader exit */
if (myself->has_pgid_children && myself->pid == myself->pgid)
{
+ siginfo_t si;
+ si.si_signo = -SIGHUP;
+ si.si_code = SI_KERNEL;
+ si.si_pid = si.si_uid = si.si_errno = 0;
sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children",
myself->pid, myself->pgid);
- kill_pgrp (myself->pgid, -SIGHUP);
+ kill_pgrp (myself->pgid, si);
}
}
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 597c58e..1fea4cd 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -419,30 +419,56 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
RtlUnwind (frame, ret_here, e0, 0);
__asm__ volatile (".equ _ret_here,.");
- int sig;
+ siginfo_t si;
/* Coerce win32 value to posix value. */
switch (e.ExceptionCode)
{
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
- case STATUS_FLOAT_INEXACT_RESULT:
case STATUS_FLOAT_INVALID_OPERATION:
- case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_STACK_CHECK:
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_FLTSUB;
+ break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_FLTRES;
+ break;
+ case STATUS_FLOAT_OVERFLOW:
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_FLTOVF;
+ break;
case STATUS_FLOAT_UNDERFLOW:
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_FLTUND;
+ break;
case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_INTDIV;
+ break;
case STATUS_INTEGER_OVERFLOW:
- sig = SIGFPE;
+ si.si_signo = SIGFPE;
+ si.si_sigval.sival_int = FPE_INTOVF;
break;
case STATUS_ILLEGAL_INSTRUCTION:
+ si.si_signo = SIGILL;
+ si.si_sigval.sival_int = ILL_ILLOPC;
+ break;
+
case STATUS_PRIVILEGED_INSTRUCTION:
+ si.si_signo = SIGILL;
+ si.si_sigval.sival_int = ILL_PRVOPC;
+ break;
+
case STATUS_NONCONTINUABLE_EXCEPTION:
- sig = SIGILL;
+ si.si_signo = SIGILL;
+ si.si_sigval.sival_int = ILL_ILLADR;
break;
case STATUS_TIMEOUT:
- sig = SIGALRM;
+ si.si_signo = SIGALRM;
+ si.si_sigval.sival_int = 0;
break;
case STATUS_ACCESS_VIOLATION:
@@ -453,11 +479,13 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
case STATUS_NO_MEMORY:
case STATUS_INVALID_DISPOSITION:
case STATUS_STACK_OVERFLOW:
- sig = SIGSEGV;
+ si.si_signo = SIGSEGV;
+ si.si_sigval.sival_int = SEGV_MAPERR;
break;
case STATUS_CONTROL_C_EXIT:
- sig = SIGINT;
+ si.si_signo = SIGINT;
+ si.si_sigval.sival_int = 0;
break;
case STATUS_INVALID_HANDLE:
@@ -476,13 +504,14 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
}
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e.ExceptionCode, in.Eip, in.Esp);
- debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in.Eip);
+ debug_printf ("In cygwin_except_handler sig = %d at %p", si.si_signo, in.Eip);
- if (global_sigs[sig].sa_mask & SIGTOMASK (sig))
- syscall_printf ("signal %d, masked %p", sig, global_sigs[sig].sa_mask);
+ if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo))
+ syscall_printf ("signal %d, masked %p", si.si_signo,
+ global_sigs[si.si_signo].sa_mask);
debug_printf ("In cygwin_except_handler calling %p",
- global_sigs[sig].sa_handler);
+ global_sigs[si.si_signo].sa_handler);
DWORD *ebp = (DWORD *)in.Esp;
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
@@ -494,23 +523,18 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
if (!myself->progname[0]
|| GetCurrentThreadId () == sigtid
- || (void *) global_sigs[sig].sa_handler == (void *) SIG_DFL
- || (void *) global_sigs[sig].sa_handler == (void *) SIG_IGN
- || (void *) global_sigs[sig].sa_handler == (void *) SIG_ERR)
+ || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
+ || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
+ || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
{
/* Print the exception to the console */
- if (1)
- {
- for (int i = 0; status_info[i].name; i++)
- {
- if (status_info[i].code == e.ExceptionCode)
- {
- if (!myself->ppid_handle)
- system_printf ("Exception: %s", status_info[i].name);
- break;
- }
- }
- }
+ for (int i = 0; status_info[i].name; i++)
+ if (status_info[i].code == e.ExceptionCode)
+ {
+ if (!myself->ppid_handle)
+ system_printf ("Exception: %s", status_info[i].name);
+ break;
+ }
/* Another exception could happen while tracing or while exiting.
Only do this once. */
@@ -529,11 +553,13 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
stackdump ((DWORD) ebp, 0, 1);
}
- signal_exit (0x80 | sig); // Flag signal + core dump
+ signal_exit (0x80 | si.si_signo); // Flag signal + core dump
}
- _my_tls.push ((__stack_t) ebp, true);
- sig_send (NULL, sig, &_my_tls); // Signal myself
+ si.si_addr = ebp;
+ si.si_code = SI_KERNEL;
+ si.si_errno = si.si_pid = si.si_uid = 0;
+ sig_send (NULL, si, &_my_tls); // Signal myself
return 1;
}
#endif /* __i386__ */
@@ -605,7 +631,14 @@ sig_handle_tty_stop (int sig)
{
pinfo parent (myself->ppid);
if (ISSTATE (parent, PID_NOCLDSTOP))
- sig_send (parent, SIGCHLD);
+ {
+ siginfo_t si;
+ si.si_signo = SIGCHLD;
+ si.si_code = SI_KERNEL;
+ si.si_sigval.sival_int = CLD_STOPPED;
+ si.si_errno = si.si_pid = si.si_uid = si.si_errno = 0;
+ sig_send (parent, si);
+ }
}
sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
myself->pid, sig, myself->ppid_handle);
@@ -814,8 +847,8 @@ ctrl_c_handler (DWORD type)
{
if (type == CTRL_CLOSE_EVENT)
{
- saw_close = true;
sig_send (NULL, SIGHUP);
+ saw_close = true;
return FALSE;
}
if (!saw_close && type == CTRL_LOGOFF_EVENT)
@@ -849,7 +882,7 @@ ctrl_c_handler (DWORD type)
a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
{
t->last_ctrl_c = GetTickCount ();
- kill (-myself->pid, SIGINT);
+ killsys (-myself->pid, SIGINT);
t->last_ctrl_c = GetTickCount ();
return TRUE;
}
@@ -884,9 +917,9 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask)
}
int __stdcall
-sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
+sigpacket::process ()
{
- if (sig == SIGCONT)
+ if (si.si_signo == SIGCONT)
{
DWORD stopped = myself->process_state & PID_STOPPED;
myself->stopsig = 0;
@@ -901,41 +934,44 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
}
int rc = 1;
- bool insigwait_mask = tls ? sigismember (&tls->sigwait_mask, sig) : false;
+ bool insigwait_mask = tls ? sigismember (&tls->sigwait_mask, si.si_signo) : false;
bool special_case = ISSTATE (myself, PID_STOPPED) || main_vfork->pid;
- bool masked = sigismember (&mask, sig);
- if (sig != SIGKILL && sig != SIGSTOP
+ bool masked = sigismember (mask, si.si_signo);
+ if (si.si_signo != SIGKILL && si.si_signo != SIGSTOP
&& (special_case || main_vfork->pid || masked || insigwait_mask
- || (tls && sigismember (&tls->sigmask, sig))))
+ || (tls && sigismember (&tls->sigmask, si.si_signo))))
{
- sigproc_printf ("signal %d blocked", sig);
+ sigproc_printf ("signal %d blocked", si.si_signo);
if ((!special_case && !masked)
- && (insigwait_mask || (tls = _threadinfo::find_tls (sig)) != NULL))
+ && (insigwait_mask || (tls = _threadinfo::find_tls (si.si_signo)) != NULL))
goto thread_specific;
rc = -1;
goto done;
}
/* Clear pending SIGCONT on stop signals */
- if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
+ if (si.si_signo == SIGSTOP || si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
sig_clear (SIGCONT);
- sigproc_printf ("signal %d processing", sig);
- struct sigaction thissig = global_sigs[sig];
+ sigproc_printf ("signal %d processing", si.si_signo);
+ struct sigaction thissig = global_sigs[si.si_signo];
void *handler;
handler = (void *) thissig.sa_handler;
myself->rusage_self.ru_nsignals++;
- if (sig == SIGKILL)
+ if (si.si_signo == SIGKILL)
goto exit_sig;
- if (sig == SIGSTOP)
+ if (!tls)
+ tls = _main_tls;
+
+ if (si.si_signo == SIGSTOP)
goto stop;
#if 0
char sigmsg[24];
- __small_sprintf (sigmsg, "cygwin: signal %d\n", sig);
+ __small_sprintf (sigmsg, "cygwin: signal %d\n", si.si_signo);
OutputDebugString (sigmsg);
#endif
@@ -943,14 +979,14 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
{
if (insigwait_mask)
goto thread_specific;
- if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
- || sig == SIGURG)
+ if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
+ || si.si_signo == SIGURG)
{
- sigproc_printf ("default signal %d ignored", sig);
+ sigproc_printf ("default signal %d ignored", si.si_signo);
goto done;
}
- if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
+ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
goto stop;
goto exit_sig;
@@ -958,7 +994,7 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
if (handler == (void *) SIG_IGN)
{
- sigproc_printf ("signal %d ignored", sig);
+ sigproc_printf ("signal %d ignored", si.si_signo);
goto done;
}
@@ -973,34 +1009,37 @@ stop:
goto done;
handler = (void *) sig_handle_tty_stop;
thissig = global_sigs[SIGSTOP];
+ goto dosig1;
dosig:
+ tls->set_siginfo (this);
+dosig1:
/* Dispatch to the appropriate function. */
- sigproc_printf ("signal %d, about to call %p", sig, handler);
- rc = setup_handler (sig, handler, thissig, tls ?: _main_tls);
+ sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
+ rc = setup_handler (si.si_signo, handler, thissig, tls);
done:
sigproc_printf ("returning %d", rc);
return rc;
thread_specific:
- tls->sig = sig;
+ tls->sig = si.si_signo;
sigproc_printf ("releasing sigwait for thread");
SetEvent (tls->event);
goto done;
exit_sig:
- if (sig == SIGQUIT || sig == SIGABRT)
+ if (si.si_signo == SIGQUIT || si.si_signo == SIGABRT)
{
CONTEXT c;
c.ContextFlags = CONTEXT_FULL;
GetThreadContext (hMainThread, &c);
if (!try_to_debug ())
stackdump (c.Ebp, 1, 1);
- sig |= 0x80;
+ si.si_signo |= 0x80;
}
- sigproc_printf ("signal %d, about to call do_exit", sig);
- signal_exit (sig);
+ sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
+ signal_exit (si.si_signo);
/* Never returns */
}
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index edb8354..398dabd 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -87,6 +87,10 @@ tty_min::kill_pgrp (int sig)
{
int killself = 0;
winpids pids ((DWORD) PID_MAP_RW);
+ siginfo_t si;
+ si.si_signo = sig;
+ si.si_code = SI_KERNEL;
+ si.si_pid = si.si_uid = si.si_errno = 0;
for (unsigned i = 0; i < pids.npids; i++)
{
_pinfo *p = pids[i];
@@ -95,10 +99,10 @@ tty_min::kill_pgrp (int sig)
if (p == myself)
killself++;
else
- (void) sig_send (p, sig);
+ (void) sig_send (p, si);
}
if (killself)
- sig_send (myself, sig);
+ sig_send (myself, si);
}
bg_check_types
@@ -144,7 +148,13 @@ fhandler_termios::bg_check (int sig)
/* Don't raise a SIGTT* signal if we have already been interrupted
by another signal. */
if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
- kill_pgrp (myself->pgid, sig);
+ {
+ siginfo_t si;
+ si.si_signo = sig;
+ si.si_code = SI_KERNEL;
+ si.si_pid = si.si_uid = si.si_errno = 0;
+ kill_pgrp (myself->pgid, si);
+ }
return bg_signalled;
setEIO:
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index ef308b0..33c7f37 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1109,7 +1109,7 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
get_ttyp ()->arg.winsize = *(struct winsize *) arg;
SetEvent (ioctl_request_event);
get_ttyp ()->winsize = *(struct winsize *) arg;
- kill (-get_ttyp ()->getpgid (), SIGWINCH);
+ killsys (-get_ttyp ()->getpgid (), SIGWINCH);
if (ioctl_done_event)
WaitForSingleObject (ioctl_done_event, INFINITE);
}
@@ -1307,7 +1307,7 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
|| get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
{
get_ttyp ()->winsize = *(struct winsize *) arg;
- kill (-get_ttyp ()->getpgid (), SIGWINCH);
+ killsys (-get_ttyp ()->getpgid (), SIGWINCH);
}
break;
case FIONBIO:
diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets
index 434707b..375b668 100755
--- a/winsup/cygwin/gentls_offsets
+++ b/winsup/cygwin/gentls_offsets
@@ -5,7 +5,7 @@ open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
my $struct = '';
my @fields = ();
my $def = '';
-my $tls = join('', <TLS>);
+$tls = join('', <TLS>);
$tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os;
my $pre = $`;
substr($tls, 0, length($pre)) = '';
@@ -75,5 +75,5 @@ open(OFFS, "/tmp/$$.a.out|") or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
print TLS_OUT <OFFS>;
close OFFS;
close TLS_OUT;
-# unlink "/tmp/$$.cc", "/tmp/$$.a.out";
+unlink "/tmp/$$.cc", "/tmp/$$.a.out";
exit(0);
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index 1e28634..5e26bf4 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -8,7 +8,7 @@ struct ucontext
void *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
- sigset_t uc_sigmask;
+ sigset_t uc_sigmask;
};
#endif
@@ -22,45 +22,41 @@ typedef union sigval
typedef struct
{
int si_signo; /* signal number */
- int si_errno; /* errno associated with signal */
int si_code; /* signal code */
+ pid_t si_pid; /* sender's pid */
+ uid_t si_uid; /* sender's uid */
+ int si_errno; /* errno associated with signal */
union
{
- int __pad[128]; /* plan for future growth */
-
+ __uint32_t __pad[120]; /* plan for future growth */
union
{
- /* timers */
+ /* timers */
struct
{
- unsigned int si_tid; /* timer id */
- unsigned int si_overrun; /* overrun count */
+ union
+ {
+ struct
+ {
+ unsigned int si_tid; /* timer id */
+ unsigned int si_overrun; /* overrun count */
+ };
+ };
+ sigval_t si_sigval; /* signal value */
};
-
- /* POSIX signals or signals invoked by kill() */
- struct
- {
- pid_t si_pid; /* sender's pid */
- uid_t si_uid; /* sender's uid */
- };
- sigval_t si_sigval; /* signal value */
};
+ /* SIGCHLD */
struct
{
- pid_t si_pid2; /* which child */
- uid_t si_uid2; /* sender's uid */
- int si_status; /* exit code */
+ int si_status; /* exit code */
clock_t si_utime; /* user time */
clock_t si_stime; /* system time */
};
/* core dumping signals */
- struct
- {
- void *si_addr; /* faulting address */
- };
+ void *si_addr; /* faulting address */
};
} siginfo_t;
#pragma pack(pop)
@@ -77,7 +73,7 @@ enum
unimplemented) */
SI_KERNEL, /* sent by system */
- ILL_ILLOP, /* illegal opcode */
+ ILL_ILLOPC, /* illegal opcode */
ILL_ILLOPN, /* illegal operand */
ILL_ILLADR, /* illegal addressing mode */
ILL_ILLTRP, /* illegal trap*/
@@ -113,7 +109,7 @@ enum
typedef struct sigevent
{
sigval_t sigev_value; /* signal value */
- int sigev_signo; /* signal number */
+ int sigev_signo; /* signal number */
int sigev_notify; /* notification type */
void (*sigev_notify_function) (sigval_t); /* notification function */
pthread_attr_t *sigev_notify_attributes; /* notification attributes */
@@ -133,7 +129,7 @@ enum
typedef void (*_sig_func_ptr)(int);
-struct sigaction
+struct sigaction
{
union
{
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 311e730..492ca3b 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -182,13 +182,13 @@ handle_sigprocmask (int sig, const sigset_t *set, sigset_t *oldset, sigset_t& op
}
static int
-kill_worker (pid_t pid, int sig)
+kill_worker (pid_t pid, siginfo_t& si)
{
sig_dispatch_pending ();
int res = 0;
pinfo dest (pid);
- BOOL sendSIGCONT;
+ bool sendSIGCONT;
if (!dest)
{
@@ -196,25 +196,32 @@ kill_worker (pid_t pid, int sig)
return -1;
}
- if ((sendSIGCONT = (sig < 0)))
- sig = -sig;
+ if ((sendSIGCONT = (si.si_signo < 0)))
+ si.si_signo = -si.si_signo;
DWORD process_state = dest->process_state;
- if (sig == 0)
+ if (si.si_signo == 0)
{
res = proc_exists (dest) ? 0 : -1;
if (res < 0)
set_errno (ESRCH);
}
- else if ((res = sig_send (dest, sig)))
+ else if ((res = sig_send (dest, si)))
{
sigproc_printf ("%d = sig_send, %E ", res);
res = -1;
}
else if (sendSIGCONT)
- (void) sig_send (dest, SIGCONT);
+ {
+ siginfo_t si2;
+ si2.si_signo = SIGCONT;
+ si2.si_code = SI_KERNEL;
+ si2.si_pid = si2.si_uid = si2.si_errno = 0;
+ (void) sig_send (dest, si2);
+ }
- syscall_printf ("%d = kill_worker (%d, %d), process_state %p", res, pid, sig, process_state);
+ syscall_printf ("%d = kill_worker (%d, %d), process_state %p", res, pid,
+ si.si_signo, process_state);
return res;
}
@@ -224,35 +231,54 @@ raise (int sig)
return kill (myself->pid, sig);
}
-int
-kill (pid_t pid, int sig)
+static int
+kill0 (pid_t pid, siginfo_t& si)
{
- syscall_printf ("kill (%d, %d)", pid, sig);
+ syscall_printf ("kill (%d, %d)", pid, si.si_signo);
/* check that sig is in right range */
- if (sig < 0 || sig >= NSIG)
+ if (si.si_signo < 0 || si.si_signo >= NSIG)
{
set_errno (EINVAL);
- syscall_printf ("signal %d out of range", sig);
+ syscall_printf ("signal %d out of range", si.si_signo);
return -1;
}
/* Silently ignore stop signals from a member of orphaned process group.
FIXME: Why??? */
if (ISSTATE (myself, PID_ORPHANED) &&
- (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU))
- sig = 0;
+ (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU))
+ si.si_signo = 0;
+
+ return (pid > 0) ? kill_worker (pid, si) : kill_pgrp (-pid, si);
+}
- return (pid > 0) ? kill_worker (pid, sig) : kill_pgrp (-pid, sig);
+int
+killsys (pid_t pid, 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 kill0 (pid, si);
+}
+int
+kill (pid_t pid, int sig)
+{
+ siginfo_t si;
+ si.si_signo = sig;
+ si.si_code = SI_USER;
+ si.si_pid = si.si_uid = si.si_errno = 0;
+ return kill0 (pid, si);
}
int
-kill_pgrp (pid_t pid, int sig)
+kill_pgrp (pid_t pid, siginfo_t& si)
{
int res = 0;
int found = 0;
int killself = 0;
- sigproc_printf ("pid %d, signal %d", pid, sig);
+ sigproc_printf ("pid %d, signal %d", pid, si.si_signo);
winpids pids ((DWORD) PID_MAP_RW);
for (unsigned i = 0; i < pids.npids; i++)
@@ -265,18 +291,18 @@ kill_pgrp (pid_t pid, int sig)
/* Is it a process we want to kill? */
if ((pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty)) ||
(pid > 1 && p->pgid != pid) ||
- (sig < 0 && NOTSTATE (p, PID_STOPPED)))
+ (si.si_signo < 0 && NOTSTATE (p, PID_STOPPED)))
continue;
sigproc_printf ("killing pid %d, pgrp %d, p->ctty %d, myself->ctty %d",
p->pid, p->pgid, p->ctty, myself->ctty);
if (p == myself)
killself++;
- else if (kill_worker (p->pid, sig))
+ else if (kill_worker (p->pid, si))
res = -1;
found++;
}
- if (killself && kill_worker (myself->pid, sig))
+ if (killself && kill_worker (myself->pid, si))
res = -1;
if (!found)
@@ -284,7 +310,7 @@ kill_pgrp (pid_t pid, int sig)
set_errno (ESRCH);
res = -1;
}
- syscall_printf ("%d = kill (%d, %d)", res, pid, sig);
+ syscall_printf ("%d = kill (%d, %d)", res, pid, si.si_signo);
return res;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e143a82..70129f6 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,14 +730,18 @@ 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;
DWORD nb;
@@ -767,7 +761,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 +781,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 +793,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 +802,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 +1004,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 +1029,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 +1041,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 +1120,7 @@ wait_sig (VOID *self)
continue;
}
- if (!pack.sig)
+ if (!pack.si.si_signo)
{
#ifdef DEBUGGING
system_printf ("zero signal?");
@@ -1140,8 +1135,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 +1149,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 +1240,13 @@ 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;
+ si.si_status = si.si_utime = si.si_stime = 0; // FIXME fill these in someday
rc = proc_subproc (PROC_CHILDTERMINATED, rc);
if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting
@@ -1253,7 +1255,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");
}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index f34dfa2..03ee1b8 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -48,6 +48,21 @@ typedef struct struct_waitq
HANDLE thread_ev;
} waitq;
+struct sigpacket
+{
+ siginfo_t si;
+ pid_t pid;
+ class _threadinfo *tls;
+ sigset_t *mask;
+ sigset_t mask_storage;
+ union
+ {
+ HANDLE wakeup;
+ struct sigpacket *next;
+ };
+ int __stdcall process () __attribute__ ((regparm (1)));
+};
+
extern HANDLE signal_arrived;
extern HANDLE sigCONT;
@@ -62,9 +77,6 @@ int __stdcall handle_sigprocmask (int sig, const sigset_t *set,
extern "C" void __stdcall reset_signal_arrived ();
extern "C" int __stdcall call_signal_handler_now ();
-#ifdef _CYGTLS_H
-int __stdcall sig_handle (int, sigset_t, int, _threadinfo *) __attribute__ ((regparm (3)));
-#endif
void __stdcall sig_clear (int) __attribute__ ((regparm (1)));
void __stdcall sig_set_pending (int) __attribute__ ((regparm (1)));
int __stdcall handle_sigsuspend (sigset_t);
@@ -78,12 +90,16 @@ void __stdcall subproc_init ();
void __stdcall sigproc_terminate ();
bool __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
-int __stdcall sig_send (_pinfo *, int, void * = NULL) __attribute__ ((regparm(3)));
+int __stdcall sig_send (_pinfo *, siginfo_t&, class _threadinfo *tls = NULL) __attribute__ ((regparm (3)));
+int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_fork ();
void __stdcall signal_fixup_after_exec ();
void __stdcall wait_for_sigthread ();
void __stdcall sigalloc ();
+int kill_pgrp (pid_t, siginfo_t&);
+int killsys (pid_t, int);
+
extern char myself_nowait_dummy[];
extern struct sigaction *global_sigs;
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index ae03dc6..0b17825 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -2736,7 +2736,11 @@ pthread_kill (pthread_t thread, int sig)
if (!pthread::is_good_object (&thread))
return EINVAL;
- int rval = sig ? sig_send (NULL, sig, thread->cygtls) : 0;
+ siginfo_t si;
+ si.si_signo = sig;
+ si.si_code = SI_USER;
+ si.si_pid = si.si_uid = si.si_errno = 0;
+ int rval = sig ? sig_send (NULL, si, thread->cygtls) : 0;
// unlock myself
return rval;
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 6c2e58f..f8bb9ec 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -318,10 +318,6 @@ int cygwin_select (int , fd_set *, fd_set *, fd_set *,
struct timeval *to);
int cygwin_gethostname (char *__name, size_t __len);
-int kill_pgrp (pid_t, int);
-int _kill (int, int);
-int _raise (int sig);
-
extern DWORD binmode;
extern char _data_start__, _data_end__, _bss_start__, _bss_end__;
extern void (*__CTOR_LIST__) (void);