From 8c787ff0563a59590599763b54b24e4f59e90908 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 17 Jan 2004 04:13:19 +0000 Subject: * 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. * fhandler_console.cc (fhandler_console::close): Remove obsolete test for vfork_cleanup. * pipe.cc (fhandler_pipe::close): Add comment. * cygheap.cc (init_cygheap::close_ctty): Don't NULL ctty if it is still active. * dtable.cc (dtable::vfork_parent_restore): Store ctty_on_hold prior to calling close_all_files since it will be zeroed. --- winsup/cygwin/ChangeLog | 70 ++++++++ winsup/cygwin/cygheap.cc | 7 +- winsup/cygwin/cygtls.h | 3 + winsup/cygwin/dcrt0.cc | 10 +- winsup/cygwin/dtable.cc | 4 +- winsup/cygwin/dtable.h | 3 +- winsup/cygwin/exceptions.cc | 1 + winsup/cygwin/fhandler_console.cc | 3 +- winsup/cygwin/gendef | 225 ++++++++++++++++++++++++++ winsup/cygwin/include/cygwin/signal.h | 2 +- winsup/cygwin/pipe.cc | 294 ++++++++++++++++++++++++++++++++++ winsup/cygwin/signal.cc | 15 +- winsup/cygwin/sigproc.cc | 10 +- winsup/cygwin/syscalls.cc | 2 +- winsup/cygwin/thread.cc | 1 + winsup/cygwin/tlsoffsets.h | 50 +++--- winsup/cygwin/winsup.h | 2 +- 17 files changed, 659 insertions(+), 43 deletions(-) create mode 100755 winsup/cygwin/gendef create mode 100644 winsup/cygwin/pipe.cc diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 16aa73fe5b4..bb39a3dee4c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,73 @@ +2004-01-16 Christopher Faylor + + * 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 + + 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 + + * fhandler_console.cc (fhandler_console::close): Remove obsolete test + for vfork_cleanup. + * pipe.cc (fhandler_pipe::close): Add comment. + +2004-01-16 Christopher Faylor + + * cygheap.cc (init_cygheap::close_ctty): Don't NULL ctty if it is still + active. + +2004-01-16 Christopher Faylor + + * dtable.cc (dtable::vfork_parent_restore): Store ctty_on_hold prior to + calling close_all_files since it will be zeroed. + 2004-01-15 Christopher Faylor * gentls_offsets: Reinstate unlink of temp files. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 0171f99f687..0e46c731706 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -176,10 +176,15 @@ void init_cygheap::close_ctty () { debug_printf ("closing cygheap->ctty %p", cygheap->ctty); + int usecount = cygheap->ctty->usecount; cygheap->ctty->close (); if (cygheap->ctty_on_hold == cygheap->ctty) cygheap->ctty_on_hold = NULL; - cygheap->ctty = NULL; + if (usecount == 1) + { + cygheap->ctty = NULL; + debug_printf ("setting cygheap->ctty to NULL"); + } } #define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1))) diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index ab82bac9dfe..0fa1b1b4c92 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; @@ -132,6 +133,8 @@ struct _threadinfo 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/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 4b905b77488..29d11f8e4d3 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 (); diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index ac9146cdcd5..c8d80e09156 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -63,7 +63,6 @@ void dtable::init_lock () { new_muto (lock_cs); - // InitializeCriticalSection (&lock_cs); } int @@ -751,6 +750,7 @@ dtable::vfork_parent_restore () { lock (); + fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold; close_all_files (); fhandler_base **deleteme = fds; fds = fds_on_hold; @@ -758,7 +758,7 @@ dtable::vfork_parent_restore () cfree (deleteme); unlock (); - cygheap->ctty = cygheap->ctty_on_hold; // revert + cygheap->ctty = ctty_on_hold; // revert if (cygheap->ctty) cygheap->ctty->close (); // Undo previous bump of this archetype cygheap->ctty_on_hold = NULL; diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 45de441d081..8f3cbea4045 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. @@ -21,7 +21,6 @@ class fhandler_fifo; class dtable { muto *lock_cs; - //CRITICAL_SECTION lock_cs; fhandler_base **fds; fhandler_base **fds_on_hold; fhandler_base **archetypes; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 1fea4cd7c23..cdb20f20c67 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -559,6 +559,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) 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, si, &_my_tls); // Signal myself return 1; } diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index af825defb32..c1d8c938482 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -677,8 +677,7 @@ fhandler_console::close (void) CloseHandle (get_output_handle ()); set_io_handle (NULL); set_output_handle (NULL); - if (!cygheap->fdtab.in_vfork_cleanup () && --(cygheap->open_fhs) <= 0 - && myself->ctty != TTY_CONSOLE) + if (--(cygheap->open_fhs) <= 0 && myself->ctty != TTY_CONSOLE) { syscall_printf ("open_fhs %d", cygheap->open_fhs); FreeConsole (); diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef new file mode 100755 index 00000000000..5addf91e2b6 --- /dev/null +++ b/winsup/cygwin/gendef @@ -0,0 +1,225 @@ +#!/usr/bin/perl +use strict; +my $in = shift; +my $tls_offsets = shift; +my $out = shift; +my $sigfe = shift; + +$main::first = 0; +if (!defined($in) || !defined($out) || !defined($sigfe)) { + die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n"; +} + +require $tls_offsets; + +open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n"; +my @top = (); +while () { + push(@top, $_); + last if /^\s*exports\s*$/i; +} +my $libline = ; +my @in = ; +close(IN); + +my %sigfe = (); +my @data = (); +my @nosigfuncs = (); +my @out = (); +for (@in) { + /\sDATA$/o and do { + push(@data, $_); + next; + }; + chomp; + if (/=/o) { + if (s/\s+NOSIGFE\s*$//) { + } elsif (s/ SIGFE$//) { + my $func = (split(' '))[2]; + $sigfe{$func} = '_sigfe_' . $func; + } + } else { + my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGR?FE))?$%o; + if (defined($sigfe) && $sigfe =~ /^NO/o) { + $_ = $func; + } else { + $sigfe ||= 'sigfe'; + $_ = '_' . lc($sigfe) . '_' . $func; + $sigfe{$func} = $_; + $_ = $func . ' = ' . $_; + } + } + s/(\S)\s+(\S)/$1 $2/go; + s/(\S)\s+$/$1/o; + s/^\s+(\S)/$1/o; + push(@out, $_ . "\n"); +} + +for (@out) { + my ($alias, $func) = /^(\S+) = (\S+)\s*$/o; + $_ = $alias . ' = ' . $sigfe{$func} . "\n" + if defined($func) && $sigfe{$func}; +} +open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n"; +print OUT @top, @data, @out; +close OUT; + +open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n"; + +for my $k (sort keys %sigfe) { + print SIGFE fefunc($k, $sigfe{$k}); +} +close SIGFE; + +sub fefunc { + my $func = '_' . shift; + my $fe = '_' . shift; + my $extra; + my $res = < +#include +#include "cygerrno.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "dtable.h" +#include "cygheap.h" +#include "thread.h" +#include "pinfo.h" +#include "cygthread.h" + +static unsigned pipecount; +static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u"; + +fhandler_pipe::fhandler_pipe () + : fhandler_base (), guard (NULL), broken_pipe (false), writepipe_exists(0), + orig_pid (0), id (0) +{ +} + +_off64_t +fhandler_pipe::lseek (_off64_t offset, int whence) +{ + debug_printf ("(%d, %d)", offset, whence); + set_errno (ESPIPE); + return -1; +} + +void +fhandler_pipe::set_close_on_exec (int val) +{ + fhandler_base::set_close_on_exec (val); + if (guard) + set_inheritance (guard, val); + if (writepipe_exists) + set_inheritance (writepipe_exists, val); +} + +struct pipeargs +{ + fhandler_base *fh; + void *ptr; + size_t *len; +}; + +static DWORD WINAPI +read_pipe (void *arg) +{ + pipeargs *pi = (pipeargs *) arg; + pi->fh->fhandler_base::read (pi->ptr, *pi->len); + return 0; +} + +void __stdcall +fhandler_pipe::read (void *in_ptr, size_t& in_len) +{ + if (broken_pipe) + in_len = 0; + else + { + pipeargs pi = {dynamic_cast(this), in_ptr, &in_len}; + ResetEvent (read_state); + cygthread *th = new cygthread (read_pipe, &pi, "read_pipe"); + if (th->detach (read_state) && !in_len) + in_len = (size_t) -1; /* received a signal */ + } + (void) ReleaseMutex (guard); + return; +} + +int +fhandler_pipe::close () +{ + if (guard) + CloseHandle (guard); + if (writepipe_exists) + CloseHandle (writepipe_exists); + // FIXME is this vfork_cleanup test right? Is it responsible for some of + // the strange pipe behavior that has been reported in the cygwin mailing + // list? + if (read_state && !cygheap->fdtab.in_vfork_cleanup ()) + CloseHandle (read_state); + if (get_handle ()) + { + CloseHandle (get_handle ()); + set_io_handle (NULL); + } + return 0; +} + +bool +fhandler_pipe::hit_eof () +{ + char buf[80]; + HANDLE ev; + if (broken_pipe) + return 1; + if (!orig_pid) + return false; + __small_sprintf (buf, pipeid_fmt, orig_pid, id); + if ((ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf))) + CloseHandle (ev); + debug_printf ("%s %p", buf, ev); + return ev == NULL; +} + +void +fhandler_pipe::fixup_after_exec (HANDLE parent) +{ + if (read_state) + read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); +} + +void +fhandler_pipe::fixup_after_fork (HANDLE parent) +{ + fhandler_base::fixup_after_fork (parent); + if (guard) + fork_fixup (parent, guard, "guard"); + if (writepipe_exists) + fork_fixup (parent, writepipe_exists, "guard"); + fixup_after_exec (parent); +} + +int +fhandler_pipe::dup (fhandler_base *child) +{ + if (get_handle ()) + { + int res = fhandler_base::dup (child); + if (res) + return res; + } + + fhandler_pipe *ftp = (fhandler_pipe *) child; + + /* FIXME: This leaks handles in the failing condition */ + if (guard == NULL) + ftp->guard = NULL; + else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1, + DUPLICATE_SAME_ACCESS)) + { + debug_printf ("couldn't duplicate guard %p, %E", guard); + return -1; + } + + if (writepipe_exists == NULL) + ftp->writepipe_exists = NULL; + else if (!DuplicateHandle (hMainProc, writepipe_exists, hMainProc, + &ftp->writepipe_exists, 0, 1, + DUPLICATE_SAME_ACCESS)) + { + debug_printf ("couldn't duplicate writepipe_exists %p, %E", writepipe_exists); + return -1; + } + + if (read_state == NULL) + ftp->read_state = NULL; + else if (!DuplicateHandle (hMainProc, read_state, hMainProc, + &ftp->read_state, 0, 1, + DUPLICATE_SAME_ACCESS)) + { + debug_printf ("couldn't duplicate read_state %p, %E", writepipe_exists); + return -1; + } + + ftp->id = id; + ftp->orig_pid = orig_pid; + return 0; +} + +int +fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fifo) +{ + HANDLE r, w; + SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ? &sec_none_nih : &sec_none; + int res = -1; + + if (!CreatePipe (&r, &w, sa, psize)) + __seterrno (); + else + { + fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev); + fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev); + + int binmode = mode & O_TEXT ?: O_BINARY; + fhs[0]->init (r, GENERIC_READ, binmode); + fhs[1]->init (w, GENERIC_WRITE, binmode); + if (mode & O_NOINHERIT) + { + fhs[0]->set_close_on_exec_flag (1); + fhs[1]->set_close_on_exec_flag (1); + } + + fhs[0]->read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + fhs[0]->set_need_fork_fixup (); + + res = 0; + fhs[0]->create_guard (sa); + if (wincap.has_unreliable_pipes ()) + { + char buf[80]; + int count = pipecount++; /* FIXME: Should this be InterlockedIncrement? */ + __small_sprintf (buf, pipeid_fmt, myself->pid, count); + fhs[1]->writepipe_exists = CreateEvent (sa, TRUE, FALSE, buf); + fhs[0]->orig_pid = myself->pid; + fhs[0]->id = count; + } + } + + syscall_printf ("%d = ([%p, %p], %d, %p)", res, fhs[0], fhs[1], psize, mode); + return res; +} + +int +fhandler_pipe::ioctl (unsigned int cmd, void *p) +{ + int n; + + switch (cmd) + { + case FIONREAD: + if (get_device () == FH_PIPEW) + { + set_errno (EINVAL); + return -1; + } + if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, (DWORD *) &n, NULL)) + { + __seterrno (); + return -1; + } + break; + default: + return fhandler_base::ioctl (cmd, p); + break; + } + *(int *) p = n; + return 0; +} + +extern "C" int +pipe (int filedes[2]) +{ + extern DWORD binmode; + fhandler_pipe *fhs[2]; + int res = fhandler_pipe::create (fhs, 16384, (!binmode || binmode == O_BINARY) + ? O_BINARY : O_TEXT); + if (res == 0) + { + cygheap_fdnew fdin; + cygheap_fdnew fdout (fdin, false); + fdin = fhs[0]; + fdout = fhs[1]; + filedes[0] = fdin; + filedes[1] = fdout; + } + + return res; +} + +extern "C" int +_pipe (int filedes[2], unsigned int psize, int mode) +{ + fhandler_pipe *fhs[2]; + int res = fhandler_pipe::create (fhs, psize, mode); + /* This type of pipe is not interruptible so set the appropriate flag. */ + if (!res) + { + cygheap_fdnew fdin; + cygheap_fdnew fdout (fdin, false); + fhs[0]->set_r_no_interrupt (1); + fdin = fhs[0]; + fdout = fhs[1]; + filedes[0] = fdin; + filedes[1] = fdout; + } + + return res; +} diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 492ca3b24da..72664b10d1e 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -483,7 +483,8 @@ extern "C" int sigwait (const sigset_t *set, int *sig) { 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 (); @@ -492,16 +493,20 @@ 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 = 0; break; default: __seterrno (); - return -1; + res = -1; } - return 0; + _my_tls.event = NULL; + _my_tls.sig = 0; + CloseHandle (h); + sig_dispatch_pending (); + return res; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 70129f6c289..a1c2d305d6f 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -744,6 +744,7 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls) 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)) { @@ -1246,7 +1247,14 @@ wait_subproc (VOID *) 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 + 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 diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 5abe0caf937..e704d1451eb 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 0b1782530fb..b04dfa11653 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2740,6 +2740,7 @@ pthread_kill (pthread_t thread, int sig) 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 diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 6aeea68d5fc..51c79561edc 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 f8bb9ec94be..980f661e785 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); -- cgit v1.2.1