* sigproc.cc (sigalloc): Don't set SA_RESTART here.
* signal.cc (_SA_NORESTART): New flag. (sigaction_worker): New function, derived from sigaction. Don't set internal flags unless called internally. (sigaction): Use sigaction_worker. (signal): Honor new _SA_NORESTART flag. (siginterrupt): Set _SA_NORESTART flag appropriately. Use sigaction_worker to set flags. * include/cygwin/signal.h: Define _SA_INTERNAL_MASK here.
This commit is contained in:
parent
5b2daa7c97
commit
dccd2abec6
@ -1,3 +1,15 @@
|
||||
2006-03-23 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* sigproc.cc (sigalloc): Don't set SA_RESTART here.
|
||||
* signal.cc (_SA_NORESTART): New flag.
|
||||
(sigaction_worker): New function, derived from sigaction. Don't set
|
||||
internal flags unless called internally.
|
||||
(sigaction): Use sigaction_worker.
|
||||
(signal): Honor new _SA_NORESTART flag.
|
||||
(siginterrupt): Set _SA_NORESTART flag appropriately. Use
|
||||
sigaction_worker to set flags.
|
||||
* include/cygwin/signal.h: Define _SA_INTERNAL_MASK here.
|
||||
|
||||
2006-03-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* thread.cc (pthread_mutex::is_good_initializer_or_bad_object): Delete.
|
||||
|
@ -215,6 +215,10 @@ struct sigaction
|
||||
#define SA_ONESHOT SA_RESETHAND /* Historical linux name */
|
||||
#define SA_NOMASK SA_NODEFER /* Historical linux name */
|
||||
|
||||
/* Used internally by cygwin. Included here to group everything in one place.
|
||||
Do not use. */
|
||||
#define _SA_INTERNAL_MASK 0xf000 /* bits in this range are internal */
|
||||
|
||||
#define SIGHUP 1 /* hangup */
|
||||
#define SIGINT 2 /* interrupt */
|
||||
#define SIGQUIT 3 /* quit */
|
||||
|
@ -28,6 +28,11 @@ details. */
|
||||
|
||||
int sigcatchers; /* FIXME: Not thread safe. */
|
||||
|
||||
#define _SA_NORESTART 0x8000
|
||||
|
||||
static int sigaction_worker (int, const struct sigaction *, struct sigaction *, bool)
|
||||
__attribute__ ((regparm (3)));
|
||||
|
||||
#define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
|
||||
|
||||
static inline void
|
||||
@ -62,9 +67,16 @@ signal (int sig, _sig_func_ptr func)
|
||||
}
|
||||
|
||||
prev = global_sigs[sig].sa_handler;
|
||||
global_sigs[sig].sa_handler = func;
|
||||
global_sigs[sig].sa_mask = 0;
|
||||
global_sigs[sig].sa_flags &= ~SA_SIGINFO;
|
||||
struct sigaction& gs = global_sigs[sig];
|
||||
if (gs.sa_flags & _SA_NORESTART)
|
||||
gs.sa_flags &= ~SA_RESTART;
|
||||
else
|
||||
gs.sa_flags |= SA_RESTART;
|
||||
|
||||
gs.sa_mask = 0;
|
||||
gs.sa_handler = func;
|
||||
gs.sa_flags &= ~SA_SIGINFO;
|
||||
|
||||
set_sigcatchers (prev, func);
|
||||
|
||||
syscall_printf ("%p = signal (%d, %p)", prev, sig, func);
|
||||
@ -336,8 +348,8 @@ abort (void)
|
||||
do_exit (SIGABRT); /* signal handler didn't exit. Goodbye. */
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
|
||||
static int
|
||||
sigaction_worker (int sig, const struct sigaction *newact, struct sigaction *oldact, bool isinternal)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
/* check that sig is in right range */
|
||||
@ -361,29 +373,41 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
struct sigaction& na = global_sigs[sig];
|
||||
na = *newact;
|
||||
if (!(na.sa_flags & SA_NODEFER))
|
||||
na.sa_mask |= SIGTOMASK(sig);
|
||||
if (na.sa_handler == SIG_IGN)
|
||||
struct sigaction na = *newact;
|
||||
struct sigaction& gs = global_sigs[sig];
|
||||
if (!isinternal)
|
||||
na.sa_flags &= ~_SA_INTERNAL_MASK;
|
||||
gs = na;
|
||||
if (!(gs.sa_flags & SA_NODEFER))
|
||||
gs.sa_mask |= SIGTOMASK(sig);
|
||||
if (gs.sa_handler == SIG_IGN)
|
||||
sig_clear (sig);
|
||||
if (na.sa_handler == SIG_DFL && sig == SIGCHLD)
|
||||
if (gs.sa_handler == SIG_DFL && sig == SIGCHLD)
|
||||
sig_clear (sig);
|
||||
set_sigcatchers (oa.sa_handler, na.sa_handler);
|
||||
set_sigcatchers (oa.sa_handler, gs.sa_handler);
|
||||
if (sig == SIGCHLD)
|
||||
{
|
||||
myself->process_state &= ~PID_NOCLDSTOP;
|
||||
if (na.sa_flags & SA_NOCLDSTOP)
|
||||
if (gs.sa_flags & SA_NOCLDSTOP)
|
||||
myself->process_state |= PID_NOCLDSTOP;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldact)
|
||||
*oldact = oa;
|
||||
{
|
||||
*oldact = oa;
|
||||
oa.sa_flags &= ~_SA_INTERNAL_MASK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
|
||||
{
|
||||
return sigaction_worker (sig, newact, oldact, false);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
sigaddset (sigset_t *set, const int sig)
|
||||
{
|
||||
@ -469,10 +493,16 @@ siginterrupt (int sig, int flag)
|
||||
struct sigaction act;
|
||||
sigaction (sig, NULL, &act);
|
||||
if (flag)
|
||||
act.sa_flags &= ~SA_RESTART;
|
||||
{
|
||||
act.sa_flags &= ~SA_RESTART;
|
||||
act.sa_flags |= _SA_NORESTART;
|
||||
}
|
||||
else
|
||||
act.sa_flags |= SA_RESTART;
|
||||
return sigaction (sig, &act, NULL);
|
||||
{
|
||||
act.sa_flags &= ~_SA_NORESTART;
|
||||
act.sa_flags |= SA_RESTART;
|
||||
}
|
||||
return sigaction_worker (sig, &act, NULL, true);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -115,10 +115,6 @@ sigalloc ()
|
||||
cygheap->sigs = global_sigs =
|
||||
(struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
|
||||
global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
|
||||
for (int i = 0; i < NSIG; i++)
|
||||
/* SA_RESTART is set to maintain BSD compatible signal behaviour by default.
|
||||
This is also compatible with the behaviour of signal(2) in Linux. */
|
||||
global_sigs[i].sa_flags = SA_RESTART;
|
||||
}
|
||||
|
||||
void __stdcall
|
||||
|
Loading…
Reference in New Issue
Block a user