mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-05-18 21:51:02 +02:00
52594: support for POSIX real-time signals with kill and trap
Also add new -L option to kill for a more verbose listing of signals
This commit is contained in:
parent
b68002d927
commit
5331ff11c6
14 changed files with 249 additions and 63 deletions
|
@ -1,3 +1,12 @@
|
|||
2024-02-28 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 52594: Completion/Zsh/Command/_kill, Doc/Zsh/builtins.yo,
|
||||
Doc/Zsh/params.yo, Src/Modules/parameter.c, Src/builtin.c,
|
||||
Src/exec.c, Src/hashtable.c, Src/init.c, Src/jobs.c, Src/params.c,
|
||||
Src/signals.c, Src/signals.h, Src/signames2.awk: support for
|
||||
POSIX real-time signals with kill and trap and add -L option to
|
||||
kill for more verbose listing of signals
|
||||
|
||||
2024-02-24 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 52597: Src/math.c: fix multibyte and metafied character counts
|
||||
|
|
|
@ -4,10 +4,11 @@ local curcontext="$curcontext" line state ret=1
|
|||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'(-s -l 1)-n[specify signal number]:signal number' \
|
||||
'(-l)-q[send the specified integer with the signal using sigqueue]:value' \
|
||||
'(-n -l 1)-s[specify signal name]:signal:_signals -s' \
|
||||
'(-n -s)-l[list signal names or numbers of specified signals]:*:signal:_signals' \
|
||||
'(-s -l -L 1)-n[specify signal number]:signal number' \
|
||||
'(-l -L)-q[send the specified integer with the signal using sigqueue]:value' \
|
||||
'(-n -l -L 1)-s[specify signal name]:signal:_signals -s' \
|
||||
'-l[list signal names or numbers of specified signals]:*:signal:_signals' \
|
||||
'(- *)-L[list each signal and corresponding number]' \
|
||||
'(-n -s -l)1::signal:_signals -p -s' \
|
||||
'*:processes:->processes' && ret=0
|
||||
|
||||
|
|
|
@ -1144,7 +1144,8 @@ cindex(killing jobs)
|
|||
cindex(jobs, killing)
|
||||
xitem(tt(kill) [ tt(-s) var(signal_name) | tt(-n) var(signal_number) | \
|
||||
tt(-)var(sig) ] [ tt(-q) var(value) ] var(job) ...)
|
||||
item(tt(kill) tt(-l) [ var(sig) ... ])(
|
||||
xitem(tt(kill) tt(-l) [ var(sig) ... ])
|
||||
item(tt(kill) tt(-L))(
|
||||
Sends either tt(SIGTERM) or the specified signal to the given
|
||||
jobs or processes.
|
||||
Signals are given by number or by names, with or without the `tt(SIG)'
|
||||
|
@ -1158,7 +1159,8 @@ specified the signal names are listed. Otherwise, for each
|
|||
var(sig) that is a name, the corresponding signal number is
|
||||
listed. For each var(sig) that is a signal number or a number
|
||||
representing the exit status of a process which was terminated or
|
||||
stopped by a signal the name of the signal is printed.
|
||||
stopped by a signal the name of the signal is printed. The final
|
||||
form with tt(-L) lists each signal name with its corresponding number.
|
||||
|
||||
On some systems, alternative signal names are allowed for a few signals.
|
||||
Typical examples are tt(SIGCHLD) and tt(SIGCLD) or tt(SIGPOLL) and
|
||||
|
|
|
@ -953,7 +953,10 @@ has index 1, the signals are offset by 1 from the signal number
|
|||
used by the operating system. For example, on typical Unix-like systems
|
||||
tt(HUP) is signal number 1, but is referred to as tt($signals[2]). This
|
||||
is because of tt(EXIT) at position 1 in the array, which is used
|
||||
internally by zsh but is not known to the operating system.
|
||||
internally by zsh but is not known to the operating system. On many systems
|
||||
there is a block of reserved or unused signal numbers before the POSIX
|
||||
real-time signals so the array index can't be used as an accurate indicator
|
||||
of their signal number. Use, for example, tt(kill -l SIGRTMIN) instead.
|
||||
)
|
||||
vindex(TRY_BLOCK_ERROR)
|
||||
item(tt(TRY_BLOCK_ERROR) <S>)(
|
||||
|
|
|
@ -309,7 +309,7 @@ setfunction(char *name, char *val, int dis)
|
|||
shfunc_set_sticky(shf);
|
||||
|
||||
if (!strncmp(name, "TRAP", 4) &&
|
||||
(sn = getsignum(name + 4)) != -1) {
|
||||
(sn = getsigidx(name + 4)) != -1) {
|
||||
if (settrap(sn, NULL, ZSIG_FUNC)) {
|
||||
freeeprog(shf->funcdef);
|
||||
zfree(shf, sizeof(*shf));
|
||||
|
|
|
@ -3425,16 +3425,16 @@ bin_functions(char *name, char **argv, Options ops, int func)
|
|||
newsh->sticky = sticky_emulation_dup(shf->sticky, 0);
|
||||
/* is newsh a signal trap? (adapted from exec.c) */
|
||||
if (!strncmp(s, "TRAP", 4)) {
|
||||
int signum = getsignum(s + 4);
|
||||
if (signum != -1) {
|
||||
if (settrap(signum, NULL, ZSIG_FUNC)) {
|
||||
int sigidx = getsigidx(s + 4);
|
||||
if (sigidx != -1) {
|
||||
if (settrap(sigidx, NULL, ZSIG_FUNC)) {
|
||||
freeeprog(newsh->funcdef);
|
||||
dircache_set(&newsh->filename, NULL);
|
||||
zfree(newsh, sizeof(*newsh));
|
||||
return 1;
|
||||
}
|
||||
/* Remove any old node explicitly */
|
||||
removetrapnode(signum);
|
||||
removetrapnode(sigidx);
|
||||
}
|
||||
}
|
||||
shfunctab->addnode(shfunctab, ztrdup(s), &newsh->node);
|
||||
|
@ -3713,15 +3713,15 @@ bin_functions(char *name, char **argv, Options ops, int func)
|
|||
/* no flags, so just print */
|
||||
printshfuncexpand(&shf->node, pflags, expand);
|
||||
} else if (on & PM_UNDEFINED) {
|
||||
int signum = -1, ok = 1;
|
||||
int sigidx = -1, ok = 1;
|
||||
|
||||
if (!strncmp(*argv, "TRAP", 4) &&
|
||||
(signum = getsignum(*argv + 4)) != -1) {
|
||||
(sigidx = getsigidx(*argv + 4)) != -1) {
|
||||
/*
|
||||
* Because of the possibility of alternative names,
|
||||
* we must remove the trap explicitly.
|
||||
*/
|
||||
removetrapnode(signum);
|
||||
removetrapnode(sigidx);
|
||||
}
|
||||
|
||||
if (**argv == '/') {
|
||||
|
@ -3757,8 +3757,8 @@ bin_functions(char *name, char **argv, Options ops, int func)
|
|||
shfunc_set_sticky(shf);
|
||||
add_autoload_function(shf, *argv);
|
||||
|
||||
if (signum != -1) {
|
||||
if (settrap(signum, NULL, ZSIG_FUNC)) {
|
||||
if (sigidx != -1) {
|
||||
if (settrap(sigidx, NULL, ZSIG_FUNC)) {
|
||||
shfunctab->removenode(shfunctab, *argv);
|
||||
shfunctab->freenode(&shf->node);
|
||||
returnval = 1;
|
||||
|
@ -7346,7 +7346,7 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
/* If given no arguments, list all currently-set traps */
|
||||
if (!*argv) {
|
||||
queue_signals();
|
||||
for (sig = 0; sig < VSIGCOUNT; sig++) {
|
||||
for (sig = 0; sig < TRAPCOUNT; sig++) {
|
||||
if (sigtrapped[sig] & ZSIG_FUNC) {
|
||||
HashNode hn;
|
||||
|
||||
|
@ -7372,13 +7372,13 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
|
||||
/* If we have a signal number, unset the specified *
|
||||
* signals. With only -, remove all traps. */
|
||||
if ((getsignum(*argv) != -1) || (!strcmp(*argv, "-") && argv++)) {
|
||||
if ((getsigidx(*argv) != -1) || (!strcmp(*argv, "-") && argv++)) {
|
||||
if (!*argv) {
|
||||
for (sig = 0; sig < VSIGCOUNT; sig++)
|
||||
for (sig = 0; sig < TRAPCOUNT; sig++)
|
||||
unsettrap(sig);
|
||||
} else {
|
||||
for (; *argv; argv++) {
|
||||
sig = getsignum(*argv);
|
||||
sig = getsigidx(*argv);
|
||||
if (sig == -1) {
|
||||
zwarnnam(name, "undefined signal: %s", *argv);
|
||||
break;
|
||||
|
@ -7403,12 +7403,12 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
Eprog t;
|
||||
int flags;
|
||||
|
||||
sig = getsignum(*argv);
|
||||
sig = getsigidx(*argv);
|
||||
if (sig == -1) {
|
||||
zwarnnam(name, "undefined signal: %s", *argv);
|
||||
break;
|
||||
}
|
||||
if (idigit(**argv) ||
|
||||
if (idigit(**argv) || (sig >= VSIGCOUNT) ||
|
||||
!strcmp(sigs[sig], *argv) ||
|
||||
(!strncmp("SIG", *argv, 3) && !strcmp(sigs[sig], *argv+3))) {
|
||||
/* The signal was specified by number or by canonical name (with
|
||||
|
|
|
@ -5427,7 +5427,7 @@ execfuncdef(Estate state, Eprog redir_prog)
|
|||
} else {
|
||||
/* is this shell function a signal trap? */
|
||||
if (!strncmp(s, "TRAP", 4) &&
|
||||
(signum = getsignum(s + 4)) != -1) {
|
||||
(signum = getsigidx(s + 4)) != -1) {
|
||||
if (settrap(signum, NULL, ZSIG_FUNC)) {
|
||||
freeeprog(shf->funcdef);
|
||||
dircache_set(&shf->filename, NULL);
|
||||
|
|
|
@ -836,10 +836,10 @@ static HashNode
|
|||
removeshfuncnode(UNUSED(HashTable ht), const char *nam)
|
||||
{
|
||||
HashNode hn;
|
||||
int signum;
|
||||
int sigidx;
|
||||
|
||||
if (!strncmp(nam, "TRAP", 4) && (signum = getsignum(nam + 4)) != -1)
|
||||
hn = removetrap(signum);
|
||||
if (!strncmp(nam, "TRAP", 4) && (sigidx = getsigidx(nam + 4)) != -1)
|
||||
hn = removetrap(sigidx);
|
||||
else
|
||||
hn = removehashnode(shfunctab, nam);
|
||||
|
||||
|
@ -856,10 +856,10 @@ disableshfuncnode(HashNode hn, UNUSED(int flags))
|
|||
{
|
||||
hn->flags |= DISABLED;
|
||||
if (!strncmp(hn->nam, "TRAP", 4)) {
|
||||
int signum = getsignum(hn->nam + 4);
|
||||
if (signum != -1) {
|
||||
sigtrapped[signum] &= ~ZSIG_FUNC;
|
||||
unsettrap(signum);
|
||||
int sigidx = getsigidx(hn->nam + 4);
|
||||
if (sigidx != -1) {
|
||||
sigtrapped[sigidx] &= ~ZSIG_FUNC;
|
||||
unsettrap(sigidx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -876,9 +876,9 @@ enableshfuncnode(HashNode hn, UNUSED(int flags))
|
|||
|
||||
shf->node.flags &= ~DISABLED;
|
||||
if (!strncmp(shf->node.nam, "TRAP", 4)) {
|
||||
int signum = getsignum(shf->node.nam + 4);
|
||||
if (signum != -1) {
|
||||
settrap(signum, NULL, ZSIG_FUNC);
|
||||
int sigidx = getsigidx(shf->node.nam + 4);
|
||||
if (sigidx != -1) {
|
||||
settrap(sigidx, NULL, ZSIG_FUNC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1382,6 +1382,9 @@ setupshin(char *runscript)
|
|||
void
|
||||
init_signals(void)
|
||||
{
|
||||
sigtrapped = (int *) hcalloc(TRAPCOUNT * sizeof(int));
|
||||
siglists = (Eprog *) hcalloc(TRAPCOUNT * sizeof(Eprog));
|
||||
|
||||
if (interact) {
|
||||
int i;
|
||||
signal_setmask(signal_mask(0));
|
||||
|
|
113
Src/jobs.c
113
Src/jobs.c
|
@ -1073,6 +1073,21 @@ should_report_time(Job j)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
char *
|
||||
sigmsg(int sig)
|
||||
{
|
||||
static char *unknown = "unknown signal";
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
static char rtmsg[] = "real-time event XXX";
|
||||
if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
|
||||
sprintf(rtmsg + sizeof(rtmsg) - 4, "%u", sig - SIGRTMIN + 1);
|
||||
return rtmsg;
|
||||
}
|
||||
#endif
|
||||
return sig <= SIGCOUNT ? sig_msg[sig] : unknown;
|
||||
}
|
||||
|
||||
/* !(lng & 3) means jobs *
|
||||
* (lng & 1) means jobs -l *
|
||||
* (lng & 2) means jobs -p
|
||||
|
@ -2694,7 +2709,7 @@ static const struct {
|
|||
int
|
||||
bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||
{
|
||||
int sig = SIGTERM;
|
||||
int status, sig = SIGTERM;
|
||||
int returnval = 0;
|
||||
#ifdef HAVE_SIGQUEUE
|
||||
union sigval sigqueue_info;
|
||||
|
@ -2740,23 +2755,29 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
if ((*argv)[1] == 'l' && (*argv)[2] == '\0') {
|
||||
if (argv[1]) {
|
||||
while (*++argv) {
|
||||
sig = zstrtol(*argv, &signame, 10);
|
||||
status = zstrtol(*argv, &signame, 10);
|
||||
if (signame == *argv) {
|
||||
signame = casemodify(signame, CASMOD_UPPER);
|
||||
if (!strncmp(signame, "SIG", 3))
|
||||
signame += 3;
|
||||
for (sig = 1; sig <= SIGCOUNT; sig++)
|
||||
if (!strcasecmp(sigs[sig], signame))
|
||||
if (!strcmp(sigs[sig], signame))
|
||||
break;
|
||||
if (sig > SIGCOUNT) {
|
||||
int i;
|
||||
|
||||
for (i = 0; alt_sigs[i].name; i++)
|
||||
if (!strcasecmp(alt_sigs[i].name, signame))
|
||||
if (!strcmp(alt_sigs[i].name, signame))
|
||||
{
|
||||
sig = alt_sigs[i].num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (sig > SIGCOUNT && (sig = rtsigno(signame))) {
|
||||
printf("%d\n", sig);
|
||||
} else
|
||||
#endif
|
||||
if (sig > SIGCOUNT) {
|
||||
zwarnnam(nam, "unknown signal: SIG%s",
|
||||
signame);
|
||||
|
@ -2769,14 +2790,15 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
signame);
|
||||
returnval++;
|
||||
} else {
|
||||
if (WIFSIGNALED(sig))
|
||||
sig = WTERMSIG(sig);
|
||||
else if (WIFSTOPPED(sig))
|
||||
sig = WSTOPSIG(sig);
|
||||
sig = status & ~0200;
|
||||
if (1 <= sig && sig <= SIGCOUNT)
|
||||
printf("%s\n", sigs[sig]);
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
else if ((signame = rtsigname(sig, 0)))
|
||||
printf("%s\n", signame);
|
||||
#endif
|
||||
else
|
||||
printf("%d\n", sig);
|
||||
printf("%d\n", status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2785,10 +2807,42 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
printf("%s", sigs[1]);
|
||||
for (sig = 2; sig <= SIGCOUNT; sig++)
|
||||
printf(" %s", sigs[sig]);
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
for (sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
|
||||
printf(" %s", rtsigname(sig, 0));
|
||||
#endif
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* with argument "-L" list signals with their numbers in a table */
|
||||
if ((*argv)[1] == 'L' && (*argv)[2] == '\0') {
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
const int width = SIGRTMAX >= 100 ? 3 : 2;
|
||||
#else
|
||||
const int width = SIGCOUNT >= 100 ? 3 : 2;
|
||||
#endif
|
||||
for (sig = 1; sig < SIGCOUNT
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
+ 1
|
||||
#endif
|
||||
; sig++)
|
||||
{
|
||||
printf("%*d) %-10s%c", width, sig, sigs[sig],
|
||||
sig % 5 ? ' ' : '\n');
|
||||
}
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
for (sig = SIGRTMIN; sig < SIGRTMAX; sig++) {
|
||||
printf("%*d) %-10s%c", width, sig, rtsigname(sig, 0),
|
||||
(sig - SIGRTMIN + SIGCOUNT + 1) % 5 ? ' ' : '\n');
|
||||
}
|
||||
printf("%*d) RTMAX\n", width, sig);
|
||||
#else
|
||||
printf("%*d) %s\n", width, sig, sigs[sig]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((*argv)[1] == 'n' && (*argv)[2] == '\0') {
|
||||
char *endp;
|
||||
|
||||
|
@ -2833,9 +2887,13 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (sig > SIGCOUNT) {
|
||||
if (sig > SIGCOUNT
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
&& !(sig = rtsigno(signame))
|
||||
#endif
|
||||
) {
|
||||
zwarnnam(nam, "unknown signal: SIG%s", signame);
|
||||
zwarnnam(nam, "type kill -l for a list of signals");
|
||||
zwarnnam(nam, "type kill -L for a list of signals");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -2916,18 +2974,19 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
|
||||
return returnval < 126 ? returnval : 1;
|
||||
}
|
||||
/* Get a signal number from a string */
|
||||
|
||||
/* Get index into table of traps from a string describing a signal */
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
getsignum(const char *s)
|
||||
getsigidx(const char *s)
|
||||
{
|
||||
int x, i;
|
||||
|
||||
/* check for a signal specified by number */
|
||||
x = atoi(s);
|
||||
if (idigit(*s) && x >= 0 && x < VSIGCOUNT)
|
||||
return x;
|
||||
if (idigit(*s) && x >= 0)
|
||||
return SIGIDX(x);
|
||||
|
||||
/* search for signal by name */
|
||||
if (!strncmp(s, "SIG", 3))
|
||||
|
@ -2943,11 +3002,16 @@ getsignum(const char *s)
|
|||
return alt_sigs[i].num;
|
||||
}
|
||||
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if ((x = rtsigno(s)))
|
||||
return SIGIDX(x);
|
||||
#endif
|
||||
|
||||
/* no matching signal */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the name for a signal. */
|
||||
/* Get the name for a signal given the index into the traps table. */
|
||||
|
||||
/**/
|
||||
mod_export const char *
|
||||
|
@ -2961,6 +3025,11 @@ getsigname(int sig)
|
|||
return alt_sigs[i].name;
|
||||
}
|
||||
else
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (sig >= VSIGCOUNT)
|
||||
return rtsigname(SIGNUM(sig), 0);
|
||||
else
|
||||
#endif
|
||||
return sigs[sig];
|
||||
|
||||
/* shouldn't reach here */
|
||||
|
@ -2985,10 +3054,22 @@ gettrapnode(int sig, int ignoredisable)
|
|||
else
|
||||
getptr = shfunctab->getnode;
|
||||
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (sig >= VSIGCOUNT)
|
||||
sprintf(fname, "TRAP%s", rtsigname(SIGNUM(sig), 0));
|
||||
else
|
||||
#endif
|
||||
sprintf(fname, "TRAP%s", sigs[sig]);
|
||||
if ((hn = getptr(shfunctab, fname)))
|
||||
return hn;
|
||||
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (sig >= VSIGCOUNT) {
|
||||
sprintf(fname, "TRAP%s", rtsigname(SIGNUM(sig), 1));
|
||||
return getptr(shfunctab, fname);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; alt_sigs[i].name; i++) {
|
||||
if (alt_sigs[i].num == sig) {
|
||||
sprintf(fname, "TRAP%s", alt_sigs[i].name);
|
||||
|
|
14
Src/params.c
14
Src/params.c
|
@ -946,8 +946,18 @@ createparamtable(void)
|
|||
setsparam("ZSH_ARGZERO", ztrdup(posixzero));
|
||||
setsparam("ZSH_VERSION", ztrdup_metafy(ZSH_VERSION));
|
||||
setsparam("ZSH_PATCHLEVEL", ztrdup_metafy(ZSH_PATCHLEVEL));
|
||||
setaparam("signals", sigptr = zalloc((SIGCOUNT+4) * sizeof(char *)));
|
||||
for (t = sigs; (*sigptr++ = ztrdup_metafy(*t++)); );
|
||||
setaparam("signals", sigptr = zalloc((TRAPCOUNT + 1) * sizeof(char *)));
|
||||
t = sigs;
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
while (t - sigs <= SIGCOUNT)
|
||||
*sigptr++ = ztrdup_metafy(*t++);
|
||||
{
|
||||
int sig;
|
||||
for (sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
|
||||
*sigptr++ = ztrdup_metafy(rtsigname(sig, 0));
|
||||
}
|
||||
#endif
|
||||
while ((*sigptr++ = ztrdup_metafy(*t++))) /* empty */ ;
|
||||
|
||||
noerrs = 0;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
#include "signals.pro"
|
||||
|
||||
/* Array describing the state of each signal: an element contains *
|
||||
* 0 for the default action or some ZSIG_* flags ored together. */
|
||||
* 0 for the default action or some ZSIG_* flags ored together. *
|
||||
* Contains TRAPCOUNT elements but can't be allocated statically *
|
||||
* because that's a dynamic value on Linux */
|
||||
|
||||
/**/
|
||||
mod_export int sigtrapped[VSIGCOUNT];
|
||||
mod_export int *sigtrapped;
|
||||
|
||||
/*
|
||||
* Trap programme lists for each signal.
|
||||
|
@ -48,7 +50,7 @@ mod_export int sigtrapped[VSIGCOUNT];
|
|||
*/
|
||||
|
||||
/**/
|
||||
mod_export Eprog siglists[VSIGCOUNT];
|
||||
mod_export Eprog *siglists;
|
||||
|
||||
/* Total count of trapped signals */
|
||||
|
||||
|
@ -892,7 +894,7 @@ dosavetrap(int sig, int level)
|
|||
* Set a trap: note this does not handle manipulation of
|
||||
* the function table for TRAPNAL functions.
|
||||
*
|
||||
* sig is the signal number.
|
||||
* sig is index into the table of trapped signals.
|
||||
*
|
||||
* l is the list to be eval'd for a trap defined with the "trap"
|
||||
* builtin and should be NULL for a function trap.
|
||||
|
@ -931,6 +933,10 @@ settrap(int sig, Eprog l, int flags)
|
|||
#endif
|
||||
sig != SIGCHLD)
|
||||
signal_ignore(sig);
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
else if (sig >= VSIGCOUNT && sig < TRAPCOUNT)
|
||||
signal_ignore(SIGNUM(sig));
|
||||
#endif
|
||||
} else {
|
||||
nsigtrapped++;
|
||||
sigtrapped[sig] = ZSIG_TRAPPED;
|
||||
|
@ -940,6 +946,10 @@ settrap(int sig, Eprog l, int flags)
|
|||
#endif
|
||||
sig != SIGCHLD)
|
||||
install_handler(sig);
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (sig >= VSIGCOUNT && sig < TRAPCOUNT)
|
||||
install_handler(SIGNUM(sig));
|
||||
#endif
|
||||
}
|
||||
sigtrapped[sig] |= flags;
|
||||
/*
|
||||
|
@ -1019,6 +1029,11 @@ removetrap(int sig)
|
|||
#endif
|
||||
sig != SIGCHLD)
|
||||
signal_default(sig);
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
else if (sig >= VSIGCOUNT && sig < TRAPCOUNT)
|
||||
signal_default(SIGNUM(sig));
|
||||
#endif
|
||||
|
||||
if (sig == SIGEXIT)
|
||||
exit_trap_posix = 0;
|
||||
|
||||
|
@ -1172,7 +1187,7 @@ endtrapscope(void)
|
|||
static int
|
||||
handletrap(int sig)
|
||||
{
|
||||
if (!sigtrapped[sig])
|
||||
if (!sigtrapped[SIGIDX(sig)])
|
||||
return 0;
|
||||
|
||||
if (trap_queueing_enabled)
|
||||
|
@ -1189,7 +1204,7 @@ handletrap(int sig)
|
|||
return 1;
|
||||
}
|
||||
|
||||
dotrap(sig);
|
||||
dotrap(SIGIDX(sig));
|
||||
|
||||
if (sig == SIGALRM)
|
||||
{
|
||||
|
@ -1481,3 +1496,60 @@ dotrap(int sig)
|
|||
|
||||
restore_queue_signals(q);
|
||||
}
|
||||
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
|
||||
/* Realtime signals, these are a contiguous block that can
|
||||
* be separated from the other signals with an unused gap. */
|
||||
|
||||
/**/
|
||||
int
|
||||
rtsigno(const char* signame)
|
||||
{
|
||||
const int maxofs = SIGRTMAX - SIGRTMIN;
|
||||
const char *end = signame + 5;
|
||||
int offset;
|
||||
struct rtdir { int sig; int dir; char op; } x = { 0, 0, 0 };
|
||||
if (!strncmp(signame, "RTMIN", 5)) {
|
||||
x = (struct rtdir) { SIGRTMIN, 1, '+' };
|
||||
} else if (!strncmp(signame, "RTMAX", 5)) {
|
||||
x = (struct rtdir) { SIGRTMAX, -1, '-' };
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (signame[5] == x.op) {
|
||||
if ((offset = strtol(signame + 6, (char **) &end, 10)) > maxofs)
|
||||
return 0;
|
||||
x.sig += offset * x.dir;
|
||||
}
|
||||
if (*end)
|
||||
return 0;
|
||||
|
||||
return x.sig;
|
||||
}
|
||||
|
||||
/**/
|
||||
char *
|
||||
rtsigname(int signo, int alt)
|
||||
{
|
||||
char* buf = (char *) zhalloc(10);
|
||||
int minofs = signo - SIGRTMIN;
|
||||
int maxofs = SIGRTMAX - signo;
|
||||
int offset;
|
||||
int form = alt ^ (maxofs < minofs);
|
||||
|
||||
if (signo < SIGRTMIN || signo > SIGRTMAX)
|
||||
return NULL;
|
||||
|
||||
strcpy(buf, "RT");
|
||||
strcpy(buf+2, form ? "MAX-" : "MIN+");
|
||||
offset = form ? maxofs : minofs;
|
||||
if (offset) {
|
||||
snprintf(buf + 6, 4, "%d", offset);
|
||||
} else {
|
||||
buf[5] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,15 @@
|
|||
#define SIGZERR (SIGCOUNT+1)
|
||||
#define SIGDEBUG (SIGCOUNT+2)
|
||||
#define VSIGCOUNT (SIGCOUNT+3)
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
# define TRAPCOUNT (VSIGCOUNT + SIGRTMAX - SIGRTMIN + 1)
|
||||
# define SIGNUM(x) ((x) >= VSIGCOUNT ? (x) - VSIGCOUNT + SIGRTMIN : (x))
|
||||
# define SIGIDX(x) ((x) >= SIGRTMIN && (x) <= SIGRTMAX ? (x) - SIGRTMIN + VSIGCOUNT : (x))
|
||||
#else
|
||||
# define TRAPCOUNT VSIGCOUNT
|
||||
# define SIGNUM(x) (x)
|
||||
# define SIGIDX(x) (x)
|
||||
#endif
|
||||
#define SIGEXIT 0
|
||||
|
||||
#ifdef SV_BSDSIG
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
if (signam == "CHLD" && sig[signum] == "CLD") sig[signum] = ""
|
||||
if (signam == "POLL" && sig[signum] == "IO") sig[signum] = ""
|
||||
if (signam == "ABRT" && sig[signum] == "IOT") sig[signum] = ""
|
||||
if (sig[signum] == "") {
|
||||
if (signam !~ /RTM(IN|AX)/ && sig[signum] == "") {
|
||||
sig[signum] = signam
|
||||
if (0 + max < 0 + signum && signum < 60)
|
||||
max = signum
|
||||
|
@ -66,10 +66,6 @@ END {
|
|||
printf "#include %czsh.mdh%c\n", 34, 34
|
||||
printf "\n"
|
||||
printf "/**/\n"
|
||||
printf "#define sigmsg(sig) ((sig) <= SIGCOUNT ? sig_msg[sig]"
|
||||
printf " : %c%s%c)", 34, "unknown signal", 34
|
||||
printf "\n"
|
||||
printf "/**/\n"
|
||||
printf "mod_export char *sig_msg[SIGCOUNT+2] = {\n"
|
||||
printf "\t%c%s%c,\n", 34, "done", 34
|
||||
|
||||
|
|
Loading…
Reference in a new issue