summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2004-01-17 04:13:19 +0000
committerChristopher Faylor <cgf@redhat.com>2004-01-17 04:13:19 +0000
commit8c787ff0563a59590599763b54b24e4f59e90908 (patch)
treef186933d2018ce409bd744da2c3218a9acc580bd
parentf45e9b4d5654d6667b3f6e06903f47df713f1052 (diff)
downloadgdb-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/ChangeLog70
-rw-r--r--winsup/cygwin/cygheap.cc7
-rw-r--r--winsup/cygwin/cygtls.h3
-rw-r--r--winsup/cygwin/dcrt0.cc10
-rw-r--r--winsup/cygwin/dtable.cc4
-rw-r--r--winsup/cygwin/dtable.h3
-rw-r--r--winsup/cygwin/exceptions.cc1
-rw-r--r--winsup/cygwin/fhandler_console.cc3
-rwxr-xr-xwinsup/cygwin/gendef225
-rw-r--r--winsup/cygwin/include/cygwin/signal.h2
-rw-r--r--winsup/cygwin/pipe.cc294
-rw-r--r--winsup/cygwin/signal.cc15
-rw-r--r--winsup/cygwin/sigproc.cc10
-rw-r--r--winsup/cygwin/syscalls.cc2
-rw-r--r--winsup/cygwin/thread.cc1
-rw-r--r--winsup/cygwin/tlsoffsets.h50
-rw-r--r--winsup/cygwin/winsup.h2
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);