diff options
Diffstat (limited to 'winsup/cygwin/signal.cc')
-rw-r--r-- | winsup/cygwin/signal.cc | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 70671b884..5b42a1ff1 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -1,6 +1,6 @@ /* signal.cc - Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com Significant changes by Sergey Okhapkin <sos@prospect.com.ru> @@ -13,9 +13,9 @@ details. */ #include "winsup.h" #include <errno.h> +#include <stdlib.h> #include "cygerrno.h" #include <sys/cygwin.h> -#include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -56,6 +56,9 @@ signal (int sig, _sig_func_ptr func) prev = myself->getsig (sig).sa_handler; myself->getsig (sig).sa_handler = func; myself->getsig (sig).sa_mask = 0; + /* SA_RESTART is set to maintain BSD compatible signal behaviour by default. + This is also compatible to the behaviour of signal(2) in Linux. */ + myself->getsig (sig).sa_flags |= SA_RESTART; set_sigcatchers (prev, func); syscall_printf ("%p = signal (%d, %p)", prev, sig, func); @@ -187,6 +190,7 @@ _raise (int sig) int _kill (pid_t pid, int sig) { + sigframe thisframe (mainthread); syscall_printf ("kill (%d, %d)", pid, sig); /* check that sig is in right range */ if (sig < 0 || sig >= NSIG) @@ -211,6 +215,7 @@ kill_pgrp (pid_t pid, int sig) int res = 0; int found = 0; int killself = 0; + sigframe thisframe (mainthread); sigproc_printf ("pid %d, signal %d", pid, sig); @@ -254,6 +259,31 @@ killpg (pid_t pgrp, int sig) return _kill (-pgrp, sig); } +extern "C" void +abort (void) +{ + sigframe thisframe (mainthread); + /* Flush all streams as per SUSv2. + From my reading of this document, this isn't strictly correct. + The streams are supposed to be flushed prior to exit. However, + if there is I/O in any signal handler that will not necessarily + be flushed. + However this is the way FreeBSD does it, and it is much easier to + do things this way, so... */ + if (_reent_clib ()->__cleanup) + _reent_clib ()->__cleanup (_reent_clib ()); + + /* Ensure that SIGABRT can be caught regardless of blockage. */ + sigset_t sig_mask; + sigfillset (&sig_mask); + sigdelset (&sig_mask, SIGABRT); + set_process_mask (sig_mask); + + _raise (SIGABRT); + (void) thisframe.call_signal_handler (); /* Call any signal handler */ + do_exit (1); /* signal handler didn't exit. Goodbye. */ +} + extern "C" int sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) { |