aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/debug.h6
-rw-r--r--winsup/cygwin/exceptions.cc14
-rw-r--r--winsup/cygwin/perthread.h3
-rw-r--r--winsup/cygwin/signal.cc3
-rw-r--r--winsup/cygwin/sigproc.cc1
-rw-r--r--winsup/cygwin/sigproc.h1
-rw-r--r--winsup/cygwin/syscalls.cc9
8 files changed, 43 insertions, 8 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a44049f..506f522 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,17 @@
+Fri Jan 12 00:35:15 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * debug.h: Add regparm attributes to some functions.
+
+ * signal.cc (sigaction): Don't treat SIGCONT specially.
+
+ * exceptions.cc (interrupt_setup): Save sa_flags of interrupted signal for later use.
+ (sig_handler): Default any stopping signal to SIGSTOP.
+ (call_signal_handler): New function.
+ (sigdelayed0): New function.
+ * sigproc.cc (sigproc_init): Initialize SIGSTOP sigaction for special behavior.
+ * sigproc.h: Define call_signal_handler.
+ * syscalls.cc (_read): Allow restartable signal behavior.
+
Thu Jan 11 13:17:00 2001 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_base): New method `fixup_mmap_after_fork'.
diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h
index ff4313f..2f06286 100644
--- a/winsup/cygwin/debug.h
+++ b/winsup/cygwin/debug.h
@@ -27,9 +27,9 @@ DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regpar
#define _DEBUG_H_
void threadname_init ();
-HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *);
-const char * __stdcall threadname (DWORD, int lockit = TRUE);
-void __stdcall regthread (const char *, DWORD);
+HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *) __attribute__ ((regparm(3)));
+const char * __stdcall threadname (DWORD, int lockit = TRUE) __attribute__ ((regparm(2)));
+void __stdcall regthread (const char *, DWORD) __attribute__ ((regparm(1)));
int __stdcall iscygthread ();
#ifndef DEBUGGING
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index c053cd9..fd7de95 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -31,6 +31,7 @@ extern "C" {
static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
extern void sigreturn ();
extern void sigdelayed ();
+extern void sigdelayed0 ();
extern void siglast ();
extern DWORD __no_sig_start, __no_sig_end;
};
@@ -634,6 +635,7 @@ interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack,
sigsave.oldmask = myself->getsigmask (); // Remember for restoration
/* FIXME: Not multi-thread aware */
sigsave.newmask = myself->getsigmask () | siga.sa_mask | SIGTOMASK (sig);
+ sigsave.sa_flags = siga.sa_flags;
sigsave.func = (void (*)(int)) handler;
sigsave.sig = sig;
sigsave.saved_errno = -1; // Flag: no errno to save
@@ -987,6 +989,7 @@ sig_handle (int sig)
stop:
handler = (void *) sig_handle_tty_stop;
+ thissig = myself->getsig (SIGSTOP);
dosig:
/* Dispatch to the appropriate function. */
@@ -1091,6 +1094,16 @@ reset_signal_arrived ()
sigproc_printf ("reset signal_arrived");
}
+int __stdcall
+call_signal_handler ()
+{
+ int sa_flags = sigsave.sa_flags;
+ sigproc_printf ("sa_flags %p", sa_flags);
+ *sigsave.retaddr_on_stack = sigsave.retaddr;
+ sigdelayed0 ();
+ return sa_flags & SA_RESTART;
+}
+
void unused_sig_wrapper ()
{
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
@@ -1123,6 +1136,7 @@ _sigreturn:
__no_sig_start:
_sigdelayed:
pushl %2 # original return address
+_sigdelayed0:
pushl %%ebp
movl %%esp,%%ebp
pushf
diff --git a/winsup/cygwin/perthread.h b/winsup/cygwin/perthread.h
index 89b97d4..889a5d8 100644
--- a/winsup/cygwin/perthread.h
+++ b/winsup/cygwin/perthread.h
@@ -1,6 +1,6 @@
/* perthread.h: Header file for cygwin synchronization primitives.
- Copyright 2000 Cygnus Solutions.
+ Copyright 2000, 2001 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@@ -96,6 +96,7 @@ struct signal_dispatch
void (*func) (int);
int sig;
int saved_errno;
+ int sa_flags;
DWORD oldmask;
DWORD newmask;
DWORD retaddr;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index f1a5131..23bc9f4 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -262,8 +262,7 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
if (newact)
{
- if ((sig == SIGKILL || sig == SIGSTOP || sig == SIGCONT) &&
- newact->sa_handler != SIG_DFL)
+ if ((sig == SIGKILL || sig == SIGSTOP) && newact->sa_handler != SIG_DFL)
{
set_errno (EINVAL);
return -1;
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index ceea748..21b325d 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -562,6 +562,7 @@ sigproc_init ()
}
memset (w, 0, sizeof *w); // Just to be safe
+ myself->getsig (SIGSTOP).sa_flags = SA_RESTART | SA_NODEFER;
sigproc_printf ("process/signal handling enabled(%x)", myself->process_state);
return;
}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 6e471dd..a5b72bc 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -98,6 +98,7 @@ BOOL __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_address (0)) __attribute__ ((regparm(3)));
void __stdcall signal_fixup_after_fork ();
void __stdcall signal_fixup_after_exec (bool);
+extern "C" int __stdcall call_signal_handler ();
extern char myself_nowait_dummy[];
extern char myself_nowait_nonmain_dummy[];
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1cf7d62..0f68344 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -220,6 +220,8 @@ _read (int fd, void *ptr, size_t len)
{
sigframe thisframe (mainthread);
extern int sigcatchers;
+
+beg:
if (fdtab.not_open (fd))
{
set_errno (EBADF);
@@ -257,8 +259,11 @@ _read (int fd, void *ptr, size_t len)
}
out:
- syscall_printf ("%d = read (%d<%s>, %p, %d), errno %d", res, fd, fh->get_name (),
- ptr, len, get_errno ());
+ if (res < 0 && WaitForSingleObject (signal_arrived, 0) == WAIT_OBJECT_0 &&
+ call_signal_handler ())
+ goto beg;
+ syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (),
+ ptr, len, fh->get_r_binary (), get_errno ());
MALLOC_CHECK;
return res;
}