Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-01-19 08:46:54 +0300
committerChristopher Faylor <me@cgf.cx>2004-01-19 08:46:54 +0300
commitf6936c48f382a12b7b67fda40352b8e377662743 (patch)
tree7626bb0ad181997983640b51113c01231992c729
parent49fec4c011d14ee74fa4811559009c623ceab82e (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog88
-rw-r--r--winsup/cygwin/Makefile.in2
-rw-r--r--winsup/cygwin/cygthread.cc2
-rw-r--r--winsup/cygwin/cygthread.h2
-rw-r--r--winsup/cygwin/cygtls.cc7
-rw-r--r--winsup/cygwin/cygtls.h6
-rw-r--r--winsup/cygwin/cygwin.din9
-rw-r--r--winsup/cygwin/dcrt0.cc16
-rw-r--r--winsup/cygwin/dtable.h2
-rw-r--r--winsup/cygwin/exceptions.cc193
-rw-r--r--winsup/cygwin/fhandler_termios.cc16
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rw-r--r--winsup/cygwin/fork.cc2
-rwxr-xr-xwinsup/cygwin/gendef4
-rw-r--r--winsup/cygwin/include/cygwin/signal.h83
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/signal.cc99
-rw-r--r--winsup/cygwin/sigproc.cc140
-rw-r--r--winsup/cygwin/sigproc.h24
-rw-r--r--winsup/cygwin/syscalls.cc2
-rw-r--r--winsup/cygwin/thread.cc7
-rw-r--r--winsup/cygwin/timer.cc275
-rw-r--r--winsup/cygwin/times.cc27
-rw-r--r--winsup/cygwin/tlsoffsets.h50
-rw-r--r--winsup/cygwin/winsup.h6
25 files changed, 818 insertions, 252 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 746730b15..b8100186a 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,91 @@
+2004-01-19 Christopher Faylor <cgf@redhat.com>
+
+ * 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.
+
+2004-01-17 Christopher Faylor <cgf@redhat.com>
+
+ * signal.cc (sigwaitinfo): Define new function.
+ (sigwait): Redefine based on sigwaitinfo.
+ * include/cygwin/signal.h (sigwaitinfo): Declare.
+ (sigwait): Ditto.
+
+2004-01-17 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::vfork_parent_restore): Avoid double close of ctty
+ when ctty == ctty_on_hold.
+
+2004-01-16 Christopher Faylor <cgf@redhat.com>
+
+ * 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.
+
+2004-01-16 Christopher Faylor <cgf@redhat.com>
+
+ 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.
+
2004-01-16 Christopher Faylor <cgf@redhat.com>
* fhandler_console.cc (fhandler_console::close): Remove obsolete test
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index cf15b320d..5cd0938f4 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -134,7 +134,7 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o cygtls.o \
resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o \
- termios.o thread.o times.o tty.o uinfo.o uname.o v8_regexp.o \
+ termios.o thread.o timer.o times.o tty.o uinfo.o uname.o v8_regexp.o \
v8_regerror.o v8_regsub.o wait.o wincap.o window.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index e83019663..309bd51ed 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -20,7 +20,7 @@ details. */
#undef CloseHandle
-static cygthread NO_COPY threads[18];
+static cygthread NO_COPY threads[32];
#define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id;
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index 76604b471..9d10bb266 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -1,6 +1,6 @@
/* cygthread.h
- Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index 5c9fa615f..ecec3f52b 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 779e42b89..0fa1b1b4c 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -102,6 +102,7 @@ struct _threadinfo
sigset_t sigmask;
sigset_t sigwait_mask;
siginfo_t *sigwait_info;
+ unsigned threadkill;
siginfo_t infodata;
struct pthread *tid;
struct _reent local_clib;
@@ -120,7 +121,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 +132,9 @@ 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)));
+ void set_threadkill () {threadkill = true;}
+ void reset_threadkill () {threadkill = false;}
/*gentls_offsets*/
};
#pragma pack(pop)
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 1f3fe08c9..7d4c352d1 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -246,8 +246,9 @@ _chroot = chroot SIGFE
cleanup_glue NOSIGFE
clearerr NOSIGFE
_clearerr = clearerr NOSIGFE
-clock NOSIGFE
-_clock = clock NOSIGFE
+clock SIGFE
+_clock = clock SIGFE
+clock_gettime SIGFE
close SIGFE
_close = close SIGFE
closedir SIGFE
@@ -1234,6 +1235,7 @@ sigpending SIGFE
sigprocmask SIGFE
sigsuspend SIGFE
sigwait SIGFE
+sigwaitinfo SIGFE
sin NOSIGFE
_sin = sin NOSIGFE
sincos NOSIGFE
@@ -1407,6 +1409,9 @@ tgamma NOSIGFE
tgammaf NOSIGFE
time SIGFE
_time = time SIGFE
+timer_create SIGFE
+timer_delete SIGFE
+timer_settime SIGFE
times SIGFE
_times = times SIGFE
timezone SIGFE
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 3d6b7a89b..29d11f8e4 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -542,8 +542,12 @@ initial_env ()
buf[0] = '\0';
len = GetModuleFileName (NULL, buf, CYG_MAX_PATH);
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
- while (ms--)
- Sleep (1);
+ Sleep (ms);
+ if (!strace.active)
+ {
+ strace.inited = 0;
+ strace.hello ();
+ }
}
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
{
@@ -573,7 +577,6 @@ void __stdcall
dll_crt0_0 ()
{
wincap.init ();
- initial_env ();
char zeros[sizeof (child_proc_info->zero)] = {0};
@@ -719,6 +722,7 @@ dll_crt0_1 (char *)
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
+ initial_env ();
check_sanity_and_sync (user_data);
malloc_init ();
@@ -1042,9 +1046,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/dtable.h b/winsup/cygwin/dtable.h
index 573467d01..8f3cbea40 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -1,6 +1,6 @@
/* dtable.h: fd table definition.
- Copyright 2000, 2001, 2003 Red Hat, Inc.
+ Copyright 2000, 2001, 2003, 2004 Red Hat, Inc.
This file is part of Cygwin.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 597c58e47..1e9745b22 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,14 @@ 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
}
+ si.si_addr = ebp;
+ si.si_code = SI_KERNEL;
+ si.si_errno = si.si_pid = si.si_uid = 0;
_my_tls.push ((__stack_t) ebp, true);
- sig_send (NULL, sig, &_my_tls); // Signal myself
+ sig_send (NULL, si, &_my_tls); // Signal myself
return 1;
}
#endif /* __i386__ */
@@ -605,7 +632,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 +848,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 +883,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 +918,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 +935,56 @@ 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 special_case = ISSTATE (myself, PID_STOPPED) || main_vfork->pid;
- bool masked = sigismember (&mask, sig);
- if (sig != SIGKILL && sig != SIGSTOP
- && (special_case || main_vfork->pid || masked || insigwait_mask
- || (tls && sigismember (&tls->sigmask, sig))))
+
+ sigproc_printf ("signal %d processing", si.si_signo);
+ struct sigaction thissig = global_sigs[si.si_signo];
+
+ myself->rusage_self.ru_nsignals++;
+
+ if (si.si_signo == SIGKILL)
+ goto exit_sig;
+ if ( si.si_signo == SIGSTOP)
{
- sigproc_printf ("signal %d blocked", sig);
- if ((!special_case && !masked)
- && (insigwait_mask || (tls = _threadinfo::find_tls (sig)) != NULL))
- goto thread_specific;
+ sig_clear (SIGCONT);
+ goto stop;
+ }
+
+ bool masked;
+ bool special_case;
+ bool insigwait_mask;
+ insigwait_mask = masked = false;
+ if (special_case = (main_vfork->pid || ISSTATE (myself, PID_STOPPED)))
+ /* nothing to do */;
+ else if (tls && sigismember (&tls->sigwait_mask, si.si_signo))
+ insigwait_mask = true;
+ else if (!tls && (tls = _threadinfo::find_tls (si.si_signo)))
+ insigwait_mask = true;
+ else if (!(masked = sigismember (mask, si.si_signo)) && tls)
+ masked = sigismember (&tls->sigmask, si.si_signo);
+
+ if (insigwait_mask)
+ goto thread_specific;
+
+ if (!tls)
+ tls = _main_tls;
+
+ if (special_case || masked)
+ {
+ sigproc_printf ("signal %d blocked", si.si_signo);
rc = -1;
goto done;
}
- /* Clear pending SIGCONT on stop signals */
- if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
- sig_clear (SIGCONT);
-
- sigproc_printf ("signal %d processing", sig);
- struct sigaction thissig = global_sigs[sig];
void *handler;
handler = (void *) thissig.sa_handler;
- myself->rusage_self.ru_nsignals++;
-
- if (sig == SIGKILL)
- goto exit_sig;
-
- if (sig == SIGSTOP)
- goto stop;
+ /* Clear pending SIGCONT on stop signals */
+ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
+ sig_clear (SIGCONT);
#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 +992,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 +1007,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 +1022,38 @@ 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;
+ tls->set_siginfo (this);
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 edb8354ef..398dabd9e 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 ef308b09a..33c7f379d 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/fork.cc b/winsup/cygwin/fork.cc
index 407a47ddd..2471ad225 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -231,6 +231,7 @@ sync_with_parent (const char *s, bool hang_self)
static int __stdcall
fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
{
+ extern void fixup_timers_after_fork ();
debug_printf ("child is running. pid %d, ppid %d, stack here %p",
myself->pid, myself->ppid, __builtin_frame_address (0));
@@ -316,6 +317,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
(*t)->set ();
pthread::atforkchild ();
+ fixup_timers_after_fork ();
wait_for_sigthread ();
cygbench ("fork-child");
return 0;
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index df810cb06..5addf91e2 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -169,10 +169,12 @@ _sigdelayed:
pushl $tls::newmask(%ebx) # newmask - eaten by set_process_mask
call _set_process_mask\@4
+ cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal?
+ jnz 4f #yes. Callee clears signal number
movl \$0,$tls::sig(%ebx) # zero the signal number as a
# flag to the signal handler thread
# that it is ok to set up sigsave
- popl %ebx
+4: popl %ebx
jmp *%ebx
EOF
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index 1e2863404..87af7c883 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -1,6 +1,20 @@
+/* signal.h
+
+ Copyright 2004 Red Hat, Inc.
+
+ This file is part of Cygwin.
+
+ This software is a copyrighted work licensed under the terms of the
+ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+ details. */
+
#ifndef _CYGWIN_SIGNAL_H
#define _CYGWIN_SIGNAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if 0
struct ucontext
{
@@ -8,7 +22,7 @@ struct ucontext
void *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
- sigset_t uc_sigmask;
+ sigset_t uc_sigmask;
};
#endif
@@ -18,49 +32,55 @@ typedef union sigval
void *sival_ptr; /* pointer signal value */
} sigval_t;
+typedef struct sigevent
+{
+ sigval_t sigev_value; /* signal value */
+ 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 */
+} sigevent_t;
+
#pragma pack(push,4)
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[32]; /* plan for future growth */
union
{
- /* timers */
+ /* timers */
struct
{
- unsigned int si_tid; /* timer id */
- unsigned int si_overrun; /* overrun count */
+ union
+ {
+ struct
+ {
+ timer_t si_tid; /* timer id */
+ unsigned int si_overrun; /* overrun count */
+ };
+ sigval_t si_sigval; /* signal value */
+ sigval_t si_value; /* 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 +97,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*/
@@ -110,15 +130,6 @@ enum
CLD_CONTINUED /* stopped child has continued */
};
-typedef struct sigevent
-{
- sigval_t sigev_value; /* signal value */
- 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 */
-} sigevent_t;
-
enum
{
SIGEV_SIGNAL = 0, /* a queued signal, with an application
@@ -133,7 +144,7 @@ enum
typedef void (*_sig_func_ptr)(int);
-struct sigaction
+struct sigaction
{
union
{
@@ -188,4 +199,10 @@ struct sigaction
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define NSIG 32 /* signal 0 implied */
+
+int sigwait (const sigset_t *, int *);
+int sigwaitinfo (const sigset_t *, siginfo_t *);
+#ifdef __cplusplus
+}
+#endif
#endif /*_CYGWIN_SIGNAL_H*/
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 1a91721ef..e8b557797 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -233,12 +233,14 @@ details. */
106: Export flock.
107: Export fcntl64.
108: Remove unused (hopefully) reent_data export.
+ 109: Export clock_gettime, sigwaitinfo, timer_create, timer_delete,
+ timer_settime
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 108
+#define CYGWIN_VERSION_API_MINOR 109
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 311e7303b..d442b17f3 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, sig) : kill_pgrp (-pid, sig);
+ return (pid > 0) ? kill_worker (pid, si) : kill_pgrp (-pid, si);
+}
+
+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;
}
@@ -452,12 +478,21 @@ siginterrupt (int sig, int flag)
return sigaction (sig, &act, NULL);
}
+extern "C" int
+sigwait (const sigset_t *set, int *sig_ptr)
+{
+ int sig = sigwaitinfo (set, NULL);
+ if (sig > 0)
+ *sig_ptr = sig;
+ return sig > 0 ? 0 : -1;
+}
extern "C" int
-sigwait (const sigset_t *set, int *sig)
+sigwaitinfo (const sigset_t *set, siginfo_t *info)
{
pthread_testcancel ();
- _my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
+ HANDLE h;
+ h = _my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
if (!_my_tls.event)
{
__seterrno ();
@@ -466,16 +501,22 @@ sigwait (const sigset_t *set, int *sig)
_my_tls.sigwait_mask = *set;
+ int res;
switch (WaitForSingleObject (_my_tls.event, INFINITE))
{
case WAIT_OBJECT_0:
- CloseHandle (_my_tls.event);
- _my_tls.event = NULL;
- *sig = InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0);
+ res = _my_tls.infodata.si_signo;
+ sigproc_printf ("returning sig %d", res);
+ if (info)
+ *info = _my_tls.infodata;
break;
default:
__seterrno ();
- return -1;
+ res = -1;
}
- return 0;
+ _my_tls.event = NULL;
+ InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0);
+ CloseHandle (h);
+ sig_dispatch_pending ();
+ return res;
}
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");
}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index f34dfa208..03ee1b89b 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/syscalls.cc b/winsup/cygwin/syscalls.cc
index 5abe0caf9..e704d1451 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -85,7 +85,7 @@ static int __stdcall stat_worker (const char *name, struct __stat64 *buf,
ensure we don't leave any such files lying around. */
void __stdcall
-close_all_files (void)
+close_all_files ()
{
cygheap->fdtab.lock ();
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index ae03dc626..b04dfa116 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -2736,7 +2736,12 @@ 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;
+ thread->cygtls->set_threadkill ();
+ int rval = sig ? sig_send (NULL, si, thread->cygtls) : 0;
// unlock myself
return rval;
diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc
new file mode 100644
index 000000000..8e836e9d4
--- /dev/null
+++ b/winsup/cygwin/timer.cc
@@ -0,0 +1,275 @@
+/* timer.cc
+
+ Copyright 2004 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#include <time.h>
+#include <stdlib.h>
+#include "cygerrno.h"
+#include "security.h"
+#include "hires.h"
+#include "thread.h"
+#include "cygtls.h"
+#include "cygthread.h"
+#include "sigproc.h"
+#include "sync.h"
+
+#define TT_MAGIC 0x513e4a1c
+struct timer_tracker
+{
+ static muto *protect;
+ unsigned magic;
+ clockid_t clock_id;
+ sigevent evp;
+ itimerspec it;
+ HANDLE cancel;
+ int flags;
+ cygthread *th;
+ struct timer_tracker *next;
+ int settime (int, const itimerspec *, itimerspec *);
+ timer_tracker (clockid_t, const sigevent *);
+ timer_tracker ();
+};
+
+timer_tracker ttstart;
+
+muto *timer_tracker::protect;
+
+timer_tracker::timer_tracker ()
+{
+ new_muto (protect);
+}
+
+timer_tracker::timer_tracker (clockid_t c, const sigevent *e)
+{
+ if (e != NULL)
+ evp = *e;
+ else
+ {
+ evp.sigev_notify = SIGEV_SIGNAL;
+ evp.sigev_signo = SIGALRM;
+ evp.sigev_value.sival_ptr = this;
+ }
+ clock_id = c;
+ cancel = NULL;
+ flags = 0;
+ memset (&it, 0, sizeof (it));
+ protect->acquire ();
+ next = ttstart.next;
+ ttstart.next = this;
+ protect->release ();
+ magic = TT_MAGIC;
+}
+
+static long long
+to_us (timespec& ts)
+{
+ long long res = ts.tv_sec;
+ res *= 1000000;
+ res += ts.tv_nsec / 1000 + ((ts.tv_nsec % 1000) >= 500 ? 1 : 0);
+ return res;
+}
+
+static NO_COPY itimerspec itzero;
+static NO_COPY timespec tzero;
+
+static DWORD WINAPI
+timer_thread (VOID *x)
+{
+ timer_tracker *tp = ((timer_tracker *) x);
+ timer_tracker tt = *tp;
+ for (bool first = true; ; first = false)
+ {
+ long long sleep_us = to_us (first ? tt.it.it_value : tt.it.it_interval);
+ long long sleep_to = sleep_us;
+ long long now = gtod.usecs (false);
+ if (tt.flags & TIMER_ABSTIME)
+ sleep_us -= now;
+ else
+ sleep_to += now;
+
+ DWORD sleep_ms = (sleep_us < 0) ? 0 : (sleep_us / 1000);
+ debug_printf ("%p waiting for %u ms, first %d", x, sleep_ms, first);
+ tp->it.it_value = tzero;
+ switch (WaitForSingleObject (tt.cancel, sleep_ms))
+ {
+ case WAIT_TIMEOUT:
+ debug_printf ("timed out");
+ break;
+ case WAIT_OBJECT_0:
+ now = gtod.usecs (false);
+ sleep_us = sleep_to - now;
+ if (sleep_us < 0)
+ sleep_us = 0;
+ tp->it.it_value.tv_sec = sleep_us / 1000000;
+ tp->it.it_value.tv_nsec = (sleep_us % 1000000) * 1000;
+ debug_printf ("%p cancelled, elapsed %D", x, sleep_us);
+ goto out;
+ default:
+ debug_printf ("%p timer wait failed, %E", x);
+ goto out;
+ }
+
+ switch (tt.evp.sigev_notify)
+ {
+ case SIGEV_SIGNAL:
+ {
+ siginfo_t si;
+ memset (&si, 0, sizeof (si));
+ si.si_signo = tt.evp.sigev_signo;
+ si.si_sigval.sival_ptr = tt.evp.sigev_value.sival_ptr;
+ debug_printf ("%p sending sig %d", x, tt.evp.sigev_signo);
+ sig_send (NULL, si);
+ break;
+ }
+ case SIGEV_THREAD:
+ {
+ pthread_t notify_thread;
+ debug_printf ("%p starting thread", x);
+ int rc = pthread_create (&notify_thread, tt.evp.sigev_notify_attributes,
+ (void * (*) (void *)) tt.evp.sigev_notify_function,
+ &tt.evp.sigev_value);
+ if (rc)
+ {
+ debug_printf ("thread creation failed, %E");
+ return 0;
+ }
+ // FIXME: pthread_join?
+ break;
+ }
+ }
+ if (!tt.it.it_interval.tv_sec && !tt.it.it_interval.tv_nsec)
+ break;
+ tt.flags = 0;
+ debug_printf ("looping");
+ }
+
+out:
+ CloseHandle (tt.cancel);
+ // FIXME: race here but is it inevitable?
+ if (tt.cancel == tp->cancel)
+ tp->cancel = NULL;
+ return 0;
+}
+
+static bool
+it_bad (const timespec& t)
+{
+ if (t.tv_nsec < 0 || t.tv_nsec >= 1000000000 || t.tv_sec < 0)
+ {
+ set_errno (EINVAL);
+ return true;
+ }
+ return false;
+}
+
+int
+timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
+{
+ if (!value)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ if (__check_invalid_read_ptr_errno (value, sizeof (*value)))
+ return -1;
+
+ if (ovalue && check_null_invalid_struct_errno (ovalue))
+ return -1;
+
+ itimerspec *elapsed;
+ if (!cancel)
+ elapsed = &itzero;
+ else
+ {
+ SetEvent (cancel); // should be closed when the thread exits
+ th->detach ();
+ elapsed = &it;
+ }
+
+ if (ovalue)
+ *ovalue = *elapsed;
+
+ if (value->it_value.tv_sec || value->it_value.tv_nsec)
+ {
+ if (it_bad (value->it_value))
+ return -1;
+ if (it_bad (value->it_interval))
+ return -1;
+ flags = in_flags;
+ cancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
+ it = *value;
+ th = new cygthread (timer_thread, this, "itimer");
+ }
+
+ return 0;
+}
+
+extern "C" int
+timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
+{
+ if (evp && check_null_invalid_struct_errno (evp))
+ return -1;
+ if (check_null_invalid_struct_errno (timerid))
+ return -1;
+
+ if (clock_id != CLOCK_REALTIME)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ *timerid = (timer_t) new timer_tracker (clock_id, evp);
+ return 0;
+}
+
+extern "C" int
+timer_settime (timer_t timerid, int flags, const struct itimerspec *value,
+ struct itimerspec *ovalue)
+{
+ timer_tracker *tt = (timer_tracker *) timerid;
+ if (check_null_invalid_struct_errno (tt) || tt->magic != TT_MAGIC)
+ return -1;
+ return tt->settime (flags, value, ovalue);
+}
+
+extern "C" int
+timer_delete (timer_t timerid)
+{
+ timer_tracker *in_tt = (timer_tracker *) timerid;
+ if (check_null_invalid_struct_errno (in_tt) || in_tt->magic != TT_MAGIC)
+ return -1;
+
+ timer_tracker::protect->acquire ();
+ for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
+ if (tt->next == in_tt)
+ {
+ timer_tracker *deleteme = tt->next;
+ tt->next = deleteme->next;
+ delete deleteme;
+ timer_tracker::protect->release ();
+ return 0;
+ }
+ timer_tracker::protect->release ();
+
+ set_errno (EINVAL);
+ return 0;
+}
+
+void
+fixup_timers_after_fork ()
+{
+ for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */)
+ {
+ timer_tracker *deleteme = tt->next;
+ tt->next = deleteme->next;
+ delete deleteme;
+ }
+}
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 46e02436b..635d05a37 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -1,6 +1,6 @@
/* times.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
This file is part of Cygwin.
@@ -15,6 +15,7 @@ details. */
#include <utime.h>
#include <stdio.h>
#include <stdlib.h>
+#include <pthread.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
@@ -22,6 +23,9 @@ details. */
#include "pinfo.h"
#include "hires.h"
#include "cygtls.h"
+#include "cygthread.h"
+#include "sigproc.h"
+#include "sync.h"
#define FACTOR (0x19db1ded53e8000LL)
#define NSPERSEC 10000000LL
@@ -612,7 +616,8 @@ hires_us::usecs (bool justdelta)
// FIXME: Use round() here?
now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
- return justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
+ LONGLONG res = justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
+ return res;
}
UINT
@@ -657,3 +662,21 @@ hires_ms::usecs (bool justdelta)
LONGLONG res = initime_us.QuadPart + ((LONGLONG) (now - initime_ms) * 1000);
return res;
}
+
+extern "C" int
+clock_gettime (clockid_t clk_id, struct timespec *tp)
+{
+ if (clk_id != CLOCK_REALTIME)
+ {
+ set_errno (ENOSYS);
+ return -1;
+ }
+
+ LONGLONG now = gtod.usecs (false);
+ if (now == (LONGLONG) -1)
+ return -1;
+
+ tp->tv_sec = now / 1000000;
+ tp->tv_nsec = (now % 1000000) * 1000;
+ return 0;
+}
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index 6aeea68d5..51c79561e 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -1,17 +1,18 @@
//;# autogenerated: Do not edit.
-//; $tls::func = -4076;
-//; $tls::saved_errno = -4072;
-//; $tls::sa_flags = -4068;
-//; $tls::oldmask = -4064;
-//; $tls::newmask = -4060;
-//; $tls::event = -4056;
-//; $tls::errno_addr = -4052;
-//; $tls::initialized = -4048;
-//; $tls::sigmask = -4044;
-//; $tls::sigwait_mask = -4040;
-//; $tls::sigwait_info = -4036;
-//; $tls::infodata = -4032;
+//; $tls::func = -3704;
+//; $tls::saved_errno = -3700;
+//; $tls::sa_flags = -3696;
+//; $tls::oldmask = -3692;
+//; $tls::newmask = -3688;
+//; $tls::event = -3684;
+//; $tls::errno_addr = -3680;
+//; $tls::initialized = -3676;
+//; $tls::sigmask = -3672;
+//; $tls::sigwait_mask = -3668;
+//; $tls::sigwait_info = -3664;
+//; $tls::threadkill = -3660;
+//; $tls::infodata = -3656;
//; $tls::tid = -3508;
//; $tls::local_clib = -3504;
//; $tls::locals = -2576;
@@ -23,18 +24,19 @@
//; $tls::padding = 0;
//; __DATA__
-#define tls_func (-4076)
-#define tls_saved_errno (-4072)
-#define tls_sa_flags (-4068)
-#define tls_oldmask (-4064)
-#define tls_newmask (-4060)
-#define tls_event (-4056)
-#define tls_errno_addr (-4052)
-#define tls_initialized (-4048)
-#define tls_sigmask (-4044)
-#define tls_sigwait_mask (-4040)
-#define tls_sigwait_info (-4036)
-#define tls_infodata (-4032)
+#define tls_func (-3704)
+#define tls_saved_errno (-3700)
+#define tls_sa_flags (-3696)
+#define tls_oldmask (-3692)
+#define tls_newmask (-3688)
+#define tls_event (-3684)
+#define tls_errno_addr (-3680)
+#define tls_initialized (-3676)
+#define tls_sigmask (-3672)
+#define tls_sigwait_mask (-3668)
+#define tls_sigwait_info (-3664)
+#define tls_threadkill (-3660)
+#define tls_infodata (-3656)
#define tls_tid (-3508)
#define tls_local_clib (-3504)
#define tls_locals (-2576)
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 6c2e58faf..980f661e7 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -219,7 +219,7 @@ void uinfo_init (void);
void events_init (void);
void events_terminate (void);
-void __stdcall close_all_files (void);
+void __stdcall close_all_files ();
/* Invisible window initialization/termination. */
HWND __stdcall gethwnd (void);
@@ -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);