diff options
author | Christopher Faylor <cgf@redhat.com> | 2004-01-17 04:13:19 +0000 |
---|---|---|
committer | Christopher Faylor <cgf@redhat.com> | 2004-01-17 04:13:19 +0000 |
commit | 8c787ff0563a59590599763b54b24e4f59e90908 (patch) | |
tree | f186933d2018ce409bd744da2c3218a9acc580bd | |
parent | f45e9b4d5654d6667b3f6e06903f47df713f1052 (diff) | |
download | gdb-8c787ff0563a59590599763b54b24e4f59e90908.tar.gz |
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 70 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.cc | 7 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 10 | ||||
-rw-r--r-- | winsup/cygwin/dtable.cc | 4 | ||||
-rw-r--r-- | winsup/cygwin/dtable.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_console.cc | 3 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 225 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/signal.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/pipe.cc | 294 | ||||
-rw-r--r-- | winsup/cygwin/signal.cc | 15 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 10 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/tlsoffsets.h | 50 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 2 |
17 files changed, 659 insertions, 43 deletions
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 <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 + for vfork_cleanup. + * pipe.cc (fhandler_pipe::close): Add comment. + +2004-01-16 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (init_cygheap::close_ctty): Don't NULL ctty if it is still + active. + +2004-01-16 Christopher Faylor <cgf@redhat.com> + + * 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 <cgf@redhat.com> * 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 (<IN>) { + push(@top, $_); + last if /^\s*exports\s*$/i; +} +my $libline = <IN>; +my @in = <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 = <<EOF; + .extern _siglist_index + .extern _siglist + .extern $func + .global $fe +$fe: + pushl \$$func + jmp __sigfe + +EOF + if (!$main::first++) { + $res = <<EOF . longjmp () . $res; + .text + .global __sigbe + .global _sigreturn + .global _sigdelayed + + .stabs "_sigfe:F(0,1)",36,0,0,__sigbe +__sigfe: + pushl %edx + movl %fs:4,%eax + movl \$4,%edx + xadd %edx,$tls::stackptr(%eax) + leal __sigbe,%eax + xchg %eax,8(%esp) + movl %eax,(%edx) + popl %edx + ret + + .stabs "_sigbe:F(0,1)",36,0,0,__sigbe +__sigbe: + pushl %eax + pushl %edx + movl \$-4,%edx +1: movl %fs:4,%eax + xadd %edx,$tls::stackptr(%eax) + xorl %eax,%eax + lock xchg %eax,-4(%edx) + testl %eax,%eax + jnz 2f + call _low_priority_sleep + xorl %edx,%edx + jmp 1b +2: xchg %eax,4(%esp) + popl %edx + ret + + .stabs "sigreturn:F(0,1)",36,0,0,_sigreturn +_sigreturn: + addl \$4,%esp # Remove argument + call _set_process_mask\@4 + + movl %fs:4,%eax + + cmpl \$0,$tls::sig(%eax) # Did a signal come in? + jnz 3f # Yes, if non-zero + +1: popl %edx # saved errno + testl %edx,%edx # Is it < 0 + jl 2f # yup. ignore it + movl $tls::errno_addr(%eax),%eax + movl %edx,(%eax) +2: popl %eax + popl %ebx + popl %ecx + popl %edx + popl %edi + popl %esi + popf + popl %ebp + jmp __sigbe + + .stabs "sigdelayed:F(0,1)",36,0,0,_sigdelayed +_sigdelayed: + pushl %ebp + movl %esp,%ebp + pushf + pushl %esi + pushl %edi + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + movl %fs:4,%ebx + pushl $tls::saved_errno(%ebx) # saved errno +3: pushl $tls::oldmask(%ebx) # oldmask + pushl $tls::sig(%ebx) # signal argument + pushl \$_sigreturn + + call _reset_signal_arrived\@0 + pushl $tls::func(%ebx) # signal func + 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 +4: popl %ebx + jmp *%ebx + +EOF + } + return $res; +} + +sub longjmp { + return <<EOF; + + .globl _longjmp + +_longjmp: + pushl %ebp + movl %esp,%ebp + movl 8(%ebp),%edi + movl 12(%ebp),%eax + testl %eax,%eax + jne 0f + incl %eax +0: + movl %eax,0(%edi) + movl 24(%edi),%ebp + pushfl + popl %ebx + movw 42(%edi),%ax + movw %ax,%ss + movl 28(%edi),%esp + pushl 32(%edi) + pushl %ebx + movw 36(%edi),%ax + movw %ax,%es + movw 40(%edi),%ax + movw %ax,%gs + movl %fs:4,%eax + leal ($tls::stack)(%eax),%edx + movl %edx,($tls::stackptr)(%eax) + movl 0(%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%esi + movl 20(%edi),%edi + popfl + ret + +EOF +} diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h index 5e26bf42ff3..767f86b01bf 100644 --- a/winsup/cygwin/include/cygwin/signal.h +++ b/winsup/cygwin/include/cygwin/signal.h @@ -29,7 +29,7 @@ typedef struct union { - __uint32_t __pad[120]; /* plan for future growth */ + __uint32_t __pad[32]; /* plan for future growth */ union { /* timers */ diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc new file mode 100644 index 00000000000..abc9a81a3e4 --- /dev/null +++ b/winsup/cygwin/pipe.cc @@ -0,0 +1,294 @@ +/* pipe.cc: pipe for Cygwin. + + Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003 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. */ + +/* FIXME: Should this really be fhandler_pipe.cc? */ + +#include "winsup.h" +#include <unistd.h> +#include <sys/socket.h> +#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<fhandler_base *>(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); |