summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--Completion/Zsh/Command/_kill9
-rw-r--r--Doc/Zsh/builtins.yo6
-rw-r--r--Doc/Zsh/params.yo5
-rw-r--r--Src/Modules/parameter.c2
-rw-r--r--Src/builtin.c30
-rw-r--r--Src/exec.c2
-rw-r--r--Src/hashtable.c20
-rw-r--r--Src/init.c3
-rw-r--r--Src/jobs.c113
-rw-r--r--Src/params.c14
-rw-r--r--Src/signals.c84
-rw-r--r--Src/signals.h9
-rw-r--r--Src/signames2.awk6
14 files changed, 249 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 684820f92..53038c221 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Completion/Zsh/Command/_kill b/Completion/Zsh/Command/_kill
index 084cf42c8..3b5c02151 100644
--- a/Completion/Zsh/Command/_kill
+++ b/Completion/Zsh/Command/_kill
@@ -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
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 784089594..6318053d8 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -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
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index a6fbe6723..8c5e67e70 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -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>)(
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index a05ea2fe4..7441c30b8 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -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));
diff --git a/Src/builtin.c b/Src/builtin.c
index f72d14da4..44dfed651 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -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
diff --git a/Src/exec.c b/Src/exec.c
index 0750738ce..d85adbea5 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -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);
diff --git a/Src/hashtable.c b/Src/hashtable.c
index bb165505e..75b06c4ad 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -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);
}
}
}
diff --git a/Src/init.c b/Src/init.c
index 83b79d3d4..ec21521b1 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -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));
diff --git a/Src/jobs.c b/Src/jobs.c
index 118c5e61b..49decc661 100644
--- a/Src/jobs.c
+++ b/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);
diff --git a/Src/params.c b/Src/params.c
index 225acb8a1..7c5e9d8ff 100644
--- a/Src/params.c
+++ b/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;
}
diff --git a/Src/signals.c b/Src/signals.c
index b1a843e2c..d28853ea6 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -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
diff --git a/Src/signals.h b/Src/signals.h
index 41ac88cce..391f11fed 100644
--- a/Src/signals.h
+++ b/Src/signals.h
@@ -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
diff --git a/Src/signames2.awk b/Src/signames2.awk
index 4d1557cd8..5738030c6 100644
--- a/Src/signames2.awk
+++ b/Src/signames2.awk
@@ -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