* 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>
|
2006-03-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* thread.cc (pthread_mutex::is_good_initializer_or_bad_object): Delete.
|
* 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_ONESHOT SA_RESETHAND /* Historical linux name */
|
||||||
#define SA_NOMASK SA_NODEFER /* 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 SIGHUP 1 /* hangup */
|
||||||
#define SIGINT 2 /* interrupt */
|
#define SIGINT 2 /* interrupt */
|
||||||
#define SIGQUIT 3 /* quit */
|
#define SIGQUIT 3 /* quit */
|
||||||
|
@ -28,6 +28,11 @@ details. */
|
|||||||
|
|
||||||
int sigcatchers; /* FIXME: Not thread safe. */
|
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)
|
#define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -62,9 +67,16 @@ signal (int sig, _sig_func_ptr func)
|
|||||||
}
|
}
|
||||||
|
|
||||||
prev = global_sigs[sig].sa_handler;
|
prev = global_sigs[sig].sa_handler;
|
||||||
global_sigs[sig].sa_handler = func;
|
struct sigaction& gs = global_sigs[sig];
|
||||||
global_sigs[sig].sa_mask = 0;
|
if (gs.sa_flags & _SA_NORESTART)
|
||||||
global_sigs[sig].sa_flags &= ~SA_SIGINFO;
|
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);
|
set_sigcatchers (prev, func);
|
||||||
|
|
||||||
syscall_printf ("%p = signal (%d, %p)", prev, sig, 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. */
|
do_exit (SIGABRT); /* signal handler didn't exit. Goodbye. */
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
static int
|
||||||
sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
|
sigaction_worker (int sig, const struct sigaction *newact, struct sigaction *oldact, bool isinternal)
|
||||||
{
|
{
|
||||||
sig_dispatch_pending ();
|
sig_dispatch_pending ();
|
||||||
/* check that sig is in right range */
|
/* check that sig is in right range */
|
||||||
@ -361,29 +373,41 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
|
|||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct sigaction& na = global_sigs[sig];
|
struct sigaction na = *newact;
|
||||||
na = *newact;
|
struct sigaction& gs = global_sigs[sig];
|
||||||
if (!(na.sa_flags & SA_NODEFER))
|
if (!isinternal)
|
||||||
na.sa_mask |= SIGTOMASK(sig);
|
na.sa_flags &= ~_SA_INTERNAL_MASK;
|
||||||
if (na.sa_handler == SIG_IGN)
|
gs = na;
|
||||||
|
if (!(gs.sa_flags & SA_NODEFER))
|
||||||
|
gs.sa_mask |= SIGTOMASK(sig);
|
||||||
|
if (gs.sa_handler == SIG_IGN)
|
||||||
sig_clear (sig);
|
sig_clear (sig);
|
||||||
if (na.sa_handler == SIG_DFL && sig == SIGCHLD)
|
if (gs.sa_handler == SIG_DFL && sig == SIGCHLD)
|
||||||
sig_clear (sig);
|
sig_clear (sig);
|
||||||
set_sigcatchers (oa.sa_handler, na.sa_handler);
|
set_sigcatchers (oa.sa_handler, gs.sa_handler);
|
||||||
if (sig == SIGCHLD)
|
if (sig == SIGCHLD)
|
||||||
{
|
{
|
||||||
myself->process_state &= ~PID_NOCLDSTOP;
|
myself->process_state &= ~PID_NOCLDSTOP;
|
||||||
if (na.sa_flags & SA_NOCLDSTOP)
|
if (gs.sa_flags & SA_NOCLDSTOP)
|
||||||
myself->process_state |= PID_NOCLDSTOP;
|
myself->process_state |= PID_NOCLDSTOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldact)
|
if (oldact)
|
||||||
*oldact = oa;
|
{
|
||||||
|
*oldact = oa;
|
||||||
|
oa.sa_flags &= ~_SA_INTERNAL_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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
|
extern "C" int
|
||||||
sigaddset (sigset_t *set, const int sig)
|
sigaddset (sigset_t *set, const int sig)
|
||||||
{
|
{
|
||||||
@ -469,10 +493,16 @@ siginterrupt (int sig, int flag)
|
|||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
sigaction (sig, NULL, &act);
|
sigaction (sig, NULL, &act);
|
||||||
if (flag)
|
if (flag)
|
||||||
act.sa_flags &= ~SA_RESTART;
|
{
|
||||||
|
act.sa_flags &= ~SA_RESTART;
|
||||||
|
act.sa_flags |= _SA_NORESTART;
|
||||||
|
}
|
||||||
else
|
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
|
extern "C" int
|
||||||
|
@ -115,10 +115,6 @@ sigalloc ()
|
|||||||
cygheap->sigs = global_sigs =
|
cygheap->sigs = global_sigs =
|
||||||
(struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
|
(struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
|
||||||
global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
|
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
|
void __stdcall
|
||||||
|
Loading…
Reference in New Issue
Block a user