summaryrefslogtreecommitdiff
path: root/Src/jobs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/jobs.c')
-rw-r--r--Src/jobs.c349
1 files changed, 288 insertions, 61 deletions
diff --git a/Src/jobs.c b/Src/jobs.c
index a91ef787f..ad14f6312 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -136,7 +136,7 @@ int numpipestats, pipestats[MAX_PIPESTATS];
/**/
static struct timeval *
-dtime(struct timeval *dt, struct timeval *t1, struct timeval *t2)
+dtime_tv(struct timeval *dt, struct timeval *t1, struct timeval *t2)
{
dt->tv_sec = t2->tv_sec - t1->tv_sec;
dt->tv_usec = t2->tv_usec - t1->tv_usec;
@@ -147,6 +147,21 @@ dtime(struct timeval *dt, struct timeval *t1, struct timeval *t2)
return dt;
}
+/* As above, but with timespecs */
+
+/**/
+static struct timespec *
+dtime_ts(struct timespec *dt, struct timespec *t1, struct timespec *t2)
+{
+ dt->tv_sec = t2->tv_sec - t1->tv_sec;
+ dt->tv_nsec = t2->tv_nsec - t1->tv_nsec;
+ if (dt->tv_nsec < 0) {
+ dt->tv_nsec += 1000000000.0;
+ dt->tv_sec -= 1.0;
+ }
+ return dt;
+}
+
/* change job table entry from stopped to running */
/**/
@@ -349,7 +364,6 @@ get_usage(void)
void
update_process(Process pn, int status)
{
- struct timezone dummy_tz;
#ifdef HAVE_GETRUSAGE
struct timeval childs = child_usage.ru_stime;
struct timeval childu = child_usage.ru_utime;
@@ -360,12 +374,12 @@ update_process(Process pn, int status)
/* get time-accounting info */
get_usage();
- gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */
+ zgettime_monotonic_if_available(&pn->endtime); /* record time process exited */
pn->status = status; /* save the status returned by WAIT */
#ifdef HAVE_GETRUSAGE
- dtime(&pn->ti.ru_stime, &childs, &child_usage.ru_stime);
- dtime(&pn->ti.ru_utime, &childu, &child_usage.ru_utime);
+ dtime_tv(&pn->ti.ru_stime, &childs, &child_usage.ru_stime);
+ dtime_tv(&pn->ti.ru_utime, &childu, &child_usage.ru_utime);
#else
pn->ti.st = shtms.tms_cstime - childs; /* compute process system space time */
pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */
@@ -414,7 +428,7 @@ storepipestats(Job jn, int inforeground, int fixlastval)
jpipestats[i] = (WIFSIGNALED(p->status) ?
0200 | WTERMSIG(p->status) :
(WIFSTOPPED(p->status) ?
- 0200 | WEXITSTATUS(p->status) :
+ 0200 | WSTOPSIG(p->status) :
WEXITSTATUS(p->status)));
if (jpipestats[i])
pipefail = jpipestats[i];
@@ -427,11 +441,17 @@ storepipestats(Job jn, int inforeground, int fixlastval)
}
if (fixlastval) {
- if (jn->stat & STAT_CURSH) {
- if (!lastval && isset(PIPEFAIL))
- lastval = pipefail;
- } else if (isset(PIPEFAIL))
- lastval = pipefail;
+ if (jn->stat & STAT_CURSH) {
+ if (!lastval && isset(PIPEFAIL)) {
+ if (inforeground)
+ this_noerrexit = 0;
+ lastval = pipefail;
+ }
+ } else if (isset(PIPEFAIL)) {
+ if (inforeground)
+ this_noerrexit = 0;
+ lastval = pipefail;
+ }
}
}
@@ -471,7 +491,7 @@ update_job(Job jn)
val = (WIFSIGNALED(pn->status) ?
0200 | WTERMSIG(pn->status) :
(WIFSTOPPED(pn->status) ?
- 0200 | WEXITSTATUS(pn->status) :
+ 0200 | WSTOPSIG(pn->status) :
WEXITSTATUS(pn->status)));
signalled = WIFSIGNALED(pn->status);
}
@@ -544,16 +564,14 @@ update_job(Job jn)
if (isset(MONITOR)) {
pid_t pgrp = gettygrp(); /* get process group of tty */
+ int deadpgrp = (mypgrp != pgrp && inforeground && pgrp > 1 &&
+ kill(-pgrp, 0) == -1 && errno == ESRCH);
/* is this job in the foreground of an interactive shell? */
if (mypgrp != pgrp && inforeground &&
- (jn->gleader == pgrp ||
- (pgrp > 1 &&
- (kill(-pgrp, 0) == -1 && errno == ESRCH)))) {
+ ((jn->gleader == pgrp && signalled) || deadpgrp)) {
if (list_pipe) {
- if (somestopped || (pgrp > 1 &&
- kill(-pgrp, 0) == -1 &&
- errno == ESRCH)) {
+ if (somestopped || deadpgrp) {
attachtty(mypgrp);
/* check window size and adjust if necessary */
adjustwinsize(0);
@@ -656,6 +674,25 @@ update_job(Job jn)
}
}
+/**/
+void
+update_bg_job(Job jn, pid_t pid, int status)
+{
+ /*
+ * Accumulate a list of older jobs. We only do this for
+ * background jobs, which is something in the job table
+ * that's not marked as in the current shell or as shell builtin
+ * and is not equal to the current foreground job.
+ */
+ if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) &&
+ jn - jobtab != thisjob) {
+ if (WIFEXITED(status))
+ addbgstatus(pid, WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ addbgstatus(pid, 0200 | WTERMSIG(status));
+ }
+}
+
/* set the previous job to something reasonable */
/**/
@@ -730,7 +767,7 @@ printhhmmss(double secs)
}
static void
-printtime(struct timeval *real, child_times_t *ti, char *desc)
+printtime(struct timespec *real, child_times_t *ti, char *desc)
{
char *s;
double elapsed_time, user_time, system_time;
@@ -751,21 +788,21 @@ printtime(struct timeval *real, child_times_t *ti, char *desc)
}
/* go ahead and compute these, since almost every TIMEFMT will have them */
- elapsed_time = real->tv_sec + real->tv_usec / 1000000.0;
+ elapsed_time = real->tv_sec + real->tv_nsec / 1000000000.0;
#ifdef HAVE_GETRUSAGE
user_time = ti->ru_utime.tv_sec + ti->ru_utime.tv_usec / 1000000.0;
system_time = ti->ru_stime.tv_sec + ti->ru_stime.tv_usec / 1000000.0;
total_time = user_time + system_time;
percent = 100.0 * total_time
- / (real->tv_sec + real->tv_usec / 1000000.0);
+ / (real->tv_sec + real->tv_nsec / 1000000000.0);
#else
{
long clktck = get_clktck();
user_time = ti->ut / (double) clktck;
system_time = ti->st / (double) clktck;
percent = 100.0 * (ti->ut + ti->st)
- / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
+ / (clktck * real->tv_sec + clktck * real->tv_nsec / 1000000000.0);
}
#endif
@@ -821,6 +858,23 @@ printtime(struct timeval *real, child_times_t *ti, char *desc)
break;
}
break;
+ case 'n':
+ switch (*++s) {
+ case 'E':
+ fprintf(stderr, "%0.fns", elapsed_time * 1000000000.0);
+ break;
+ case 'U':
+ fprintf(stderr, "%0.fns", user_time * 1000000000.0);
+ break;
+ case 'S':
+ fprintf(stderr, "%0.fns", system_time * 1000000000.0);
+ break;
+ default:
+ fprintf(stderr, "%%n");
+ s--;
+ break;
+ }
+ break;
case '*':
switch (*++s) {
case 'E':
@@ -890,8 +944,13 @@ printtime(struct timeval *real, child_times_t *ti, char *desc)
break;
#endif
#ifdef HAVE_STRUCT_RUSAGE_RU_MAXRSS
+#ifdef RU_MAXRSS_IS_IN_BYTES
+# define MAXRSS_IN_KB(x) ((x)/1024)
+#else
+# define MAXRSS_IN_KB(x) (x)
+#endif
case 'M':
- fprintf(stderr, "%ld", ti->ru_maxrss / 1024);
+ fprintf(stderr, "%ld", MAXRSS_IN_KB(ti->ru_maxrss));
break;
#endif
#ifdef HAVE_STRUCT_RUSAGE_RU_MAJFLT
@@ -963,12 +1022,12 @@ static void
dumptime(Job jn)
{
Process pn;
- struct timeval dtimeval;
+ struct timespec dtimespec;
if (!jn->procs)
return;
for (pn = jn->procs; pn; pn = pn->next)
- printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti,
+ printtime(dtime_ts(&dtimespec, &pn->bgtime, &pn->endtime), &pn->ti,
pn->text);
}
@@ -1029,7 +1088,7 @@ should_report_time(Job j)
return 1;
#else
{
- clktck = get_clktck();
+ long clktck = get_clktck();
if ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime)
return 1;
}
@@ -1038,13 +1097,28 @@ should_report_time(Job j)
#ifdef HAVE_GETRUSAGE
if (reportmemory >= 0 &&
- j->procs->ti.ru_maxrss / 1024 > reportmemory)
+ MAXRSS_IN_KB(j->procs->ti.ru_maxrss) > reportmemory)
return 1;
#endif
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
@@ -1374,8 +1448,10 @@ cleanfilelists(void)
DPUTS(shell_exiting >= 0, "BUG: cleanfilelists() before exit");
- for (i = 1; i <= maxjob; i++)
+ for (i = 1; i <= maxjob; i++) {
deletefilelist(jobtab[i].filelist, 0);
+ jobtab[i].filelist = 0;
+ }
}
/**/
@@ -1461,7 +1537,7 @@ deletejob(Job jn, int disowning)
/**/
void
-addproc(pid_t pid, char *text, int aux, struct timeval *bgtime,
+addproc(pid_t pid, char *text, int aux, struct timespec *bgtime,
int gleader, int list_pipe_job_used)
{
Process pn, *pnlist;
@@ -1488,10 +1564,7 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime,
* set it for that, too.
*/
if (gleader != -1) {
- if (jobtab[thisjob].stat & STAT_CURSH)
- jobtab[thisjob].gleader = gleader;
- else
- jobtab[thisjob].gleader = pid;
+ jobtab[thisjob].gleader = gleader;
if (list_pipe_job_used != -1)
jobtab[list_pipe_job_used].gleader = gleader;
/*
@@ -1500,7 +1573,7 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime,
*/
last_attached_pgrp = gleader;
} else if (!jobtab[thisjob].gleader)
- jobtab[thisjob].gleader = pid;
+ jobtab[thisjob].gleader = pid;
/* attach this process to end of process list of current job */
pnlist = &jobtab[thisjob].procs;
}
@@ -1536,8 +1609,10 @@ havefiles(void)
int i;
for (i = 1; i <= maxjob; i++)
- if (jobtab[i].stat && jobtab[i].filelist)
+ if (jobtab[i].stat && jobtab[i].filelist &&
+ peekfirst(jobtab[i].filelist)) {
return 1;
+ }
return 0;
}
@@ -1850,16 +1925,15 @@ spawnjob(void)
/**/
void
-shelltime(void)
+shelltime(child_times_t *shell, child_times_t *kids, struct timespec *then, int delta)
{
- struct timezone dummy_tz;
- struct timeval dtimeval, now;
+ struct timespec dtimespec, now;
child_times_t ti;
#ifndef HAVE_GETRUSAGE
struct tms buf;
#endif
- gettimeofday(&now, &dummy_tz);
+ zgettime_monotonic_if_available(&now);
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_SELF, &ti);
@@ -1869,7 +1943,28 @@ shelltime(void)
ti.ut = buf.tms_utime;
ti.st = buf.tms_stime;
#endif
- printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
+ if (shell) {
+ if (delta) {
+#ifdef HAVE_GETRUSAGE
+ dtime_tv(&ti.ru_utime, &shell->ru_utime, &ti.ru_utime);
+ dtime_tv(&ti.ru_stime, &shell->ru_stime, &ti.ru_stime);
+#else
+ ti.ut -= shell->ut;
+ ti.st -= shell->st;
+#endif
+ } else
+ *shell = ti;
+ }
+ if (delta)
+ dtime_ts(&dtimespec, then, &now);
+ else {
+ if (then)
+ *then = now;
+ dtime_ts(&dtimespec, &shtimer, &now);
+ }
+
+ if (!delta == !shell)
+ printtime(&dtimespec, &ti, "shell");
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_CHILDREN, &ti);
@@ -1877,8 +1972,20 @@ shelltime(void)
ti.ut = buf.tms_cutime;
ti.st = buf.tms_cstime;
#endif
- printtime(&dtimeval, &ti, "children");
-
+ if (kids) {
+ if (delta) {
+#ifdef HAVE_GETRUSAGE
+ dtime_tv(&ti.ru_utime, &kids->ru_utime, &ti.ru_utime);
+ dtime_tv(&ti.ru_stime, &kids->ru_stime, &ti.ru_stime);
+#else
+ ti.ut -= shell->ut;
+ ti.st -= shell->st;
+#endif
+ } else
+ *kids = ti;
+ }
+ if (!delta == !kids)
+ printtime(&dtimespec, &ti, "children");
}
/* see if jobs need printing */
@@ -2221,6 +2328,9 @@ addbgstatus(pid_t pid, int status)
{
static long child_max;
Bgstatus bgstatus_entry;
+#ifdef DEBUG
+ LinkNode node;
+#endif
if (!child_max) {
#ifdef _SC_CHILD_MAX
@@ -2244,6 +2354,21 @@ addbgstatus(pid_t pid, int status)
if (!bgstatus_list)
return;
}
+#ifdef DEBUG
+ /* See if an entry already exists for the pid */
+ for (node = firstnode(bgstatus_list); node; incnode(node)) {
+ bgstatus_entry = (Bgstatus)getdata(node);
+ if (bgstatus_entry->pid == pid) {
+ /* In theory this should not happen because addbgstatus() is
+ * called only once when the process exits or gets killed. */
+ dputs("addbgstatus called again: pid %d: status %d -> %d",
+ pid, bgstatus_entry->status, status);
+ bgstatus_entry->status = status;
+ return;
+ }
+ }
+#endif
+ /* Add an entry for the pid */
if (bgstatus_count == child_max) {
/* Overflow. List is in order, remove first */
rembgstatus(firstnode(bgstatus_list));
@@ -2384,7 +2509,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
int curmaxjob, ignorejob;
if (unset(MONITOR) && oldmaxjob) {
jobptr = oldjobtab;
- curmaxjob = oldmaxjob ? oldmaxjob - 1 : 0;
+ curmaxjob = oldmaxjob;
ignorejob = 0;
} else {
jobptr = jobtab;
@@ -2488,6 +2613,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
jobtab[job].stat &= ~STAT_CURSH;
}
if ((stopped = (jobtab[job].stat & STAT_STOPPED))) {
+ /* WIFCONTINUED will makerunning() again at killjb() */
makerunning(jobtab + job);
if (func == BIN_BG) {
/* Set $! to indicate this was backgrounded */
@@ -2646,11 +2772,37 @@ 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;
+#endif
+ int use_sigqueue = 0, got_sig = 0;
+
+ while (*argv && **argv == '-') {
+ if (!use_sigqueue && (*argv)[1] == 'q' && (*argv)[2] == '\0') {
+ char *endp;
+
+ if (!*++argv) {
+ zwarnnam(nam, "-q: argument expected");
+ return 1;
+ }
+#ifdef HAVE_SIGQUEUE
+ sigqueue_info.sival_int =
+#endif
+ zstrtol(*argv, &endp, 10);
+ if (*endp) {
+ zwarnnam(nam, "invalid number: %s", *argv);
+ return 1;
+ }
+ use_sigqueue = 1;
+ argv++;
+ continue;
+ }
+ if (got_sig)
+ break;
/* check for, and interpret, a signal specifier */
- if (*argv && **argv == '-') {
if (idigit((*argv)[1])) {
char *endp;
/* signal specified by number */
@@ -2666,23 +2818,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);
@@ -2695,14 +2853,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);
}
}
}
@@ -2711,10 +2870,45 @@ 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
+ const int cols = zterm_columns >= 30 ?
+ (zterm_columns < 90 ? zterm_columns / 15 : 6) : 1;
+
+ for (sig = 1; sig < SIGCOUNT
+#if defined(SIGRTMIN) && defined(SIGRTMAX)
+ + 1
+#endif
+ ; sig++)
+ {
+ printf("%*d %-10s%c", width, sig, sigs[sig],
+ sig % cols ? ' ' : '\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) % cols ? ' ' : '\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;
@@ -2759,14 +2953,19 @@ 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;
}
}
}
argv++;
+ got_sig = 1;
}
/* Discard the standard "-" and "--" option breaks */
@@ -2815,7 +3014,12 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
returnval++;
} else {
int pid = atoi(*argv);
- if (kill(pid, sig) == -1) {
+ if (
+#ifdef HAVE_SIGQUEUE
+ use_sigqueue ? sigqueue(pid, sig, sigqueue_info) :
+#endif
+ kill(pid, sig) == -1)
+ {
zwarnnam("kill", "kill %s failed: %e", *argv, errno);
returnval++;
}
@@ -2836,18 +3040,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))
@@ -2863,11 +3068,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 *
@@ -2881,6 +3091,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 */
@@ -2905,10 +3120,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);