diff options
-rw-r--r-- | lib/lib.c | 91 | ||||
-rw-r--r-- | lib/lib.h | 2 | ||||
-rw-r--r-- | lib/portability.c | 101 | ||||
-rw-r--r-- | lib/portability.h | 9 |
4 files changed, 114 insertions, 89 deletions
@@ -842,33 +842,6 @@ int yesno(int def) return def; } -struct signame { - int num; - char *name; -}; - -// Signals required by POSIX 2008: -// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - -#define SIGNIFY(x) {SIG##x, #x} - -static struct signame signames[] = { - // POSIX - SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), - SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), - SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(TERM), - SIGNIFY(USR1), SIGNIFY(USR2), SIGNIFY(SYS), SIGNIFY(TRAP), - SIGNIFY(VTALRM), SIGNIFY(XCPU), SIGNIFY(XFSZ), - // Non-POSIX terminal signals - SIGNIFY(STKFLT), SIGNIFY(PROF), SIGNIFY(POLL), SIGNIFY(IO), SIGNIFY(PWR), - - // POSIX non-terminal signals - SIGNIFY(CHLD), SIGNIFY(CONT), SIGNIFY(STOP), SIGNIFY(TSTP), - SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(URG), - // Non-POSIX non-terminal signals - SIGNIFY(WINCH), -}; - // Handler that sets toys.signal, and writes to toys.signalfd if set void generic_signal(int sig) { @@ -891,15 +864,11 @@ void exit_signal(int sig) // adds the handlers to a list, to be called in order. void sigatexit(void *handler) { - struct arg_list *al; - int i; - - for (i=0; signames[i].num != SIGCHLD; i++) - if (signames[i].num != SIGKILL) - xsignal(signames[i].num, handler ? exit_signal : SIG_DFL); + xsignal_all_killers(handler ? exit_signal : SIG_DFL); if (handler) { - al = xmalloc(sizeof(struct arg_list)); + struct arg_list *al = xmalloc(sizeof(struct arg_list)); + al->next = toys.xexit; al->arg = handler; toys.xexit = al; @@ -909,65 +878,13 @@ void sigatexit(void *handler) } } -// Convert a string like "9", "KILL", "SIGHUP", or "SIGRTMIN+2" to a number. -int sig_to_num(char *pidstr) -{ - int i, offset; - char *s; - - // Numeric? - i = estrtol(pidstr, &s, 10); - if (!errno && !*s) return i; - - // Skip leading "SIG". - strcasestart(&pidstr, "sig"); - - // Named signal? - for (i=0; i<ARRAY_LEN(signames); i++) - if (!strcasecmp(pidstr, signames[i].name)) return signames[i].num; - - // Real-time signal? - if (strcasestart(&pidstr, "rtmin")) i = SIGRTMIN; - else if (strcasestart(&pidstr, "rtmax")) i = SIGRTMAX; - else return -1; - // No offset? - if (!*pidstr) return i; - // We allow any offset that's still a real-time signal: SIGRTMIN+20 is fine. - // Others are more restrictive, only accepting what they show with -l. - offset = estrtol(pidstr, &s, 10); - if (errno || *s) return -1; - i += offset; - if (i >= SIGRTMIN && i <= SIGRTMAX) return i; - - return -1; -} - -char *num_to_sig(int sig) -{ - int i; - - // A named signal? - for (i=0; i<ARRAY_LEN(signames); i++) - if (signames[i].num == sig) return signames[i].name; - - // A real-time signal? - if (sig == SIGRTMIN) return "RTMIN"; - if (sig == SIGRTMAX) return "RTMAX"; - if (sig > SIGRTMIN && sig < SIGRTMAX) { - if (sig-SIGRTMIN <= SIGRTMAX-sig) sprintf(libbuf, "RTMIN+%d", sig-SIGRTMIN); - else sprintf(libbuf, "RTMAX-%d", SIGRTMAX-sig); - return libbuf; - } - return NULL; -} - // Output a nicely formatted 80-column table of all the signals. void list_signals() { int i = 0, count = 0; char *name; - for (; i<=SIGRTMAX; i++) { + for (; i<=NSIG; i++) { if ((name = num_to_sig(i))) { printf("%2d) SIG%-9s", i, name); if (++count % 5 == 0) putchar('\n'); @@ -388,9 +388,7 @@ struct mtab_list *xgetmountlist(char *path); void generic_signal(int signal); void exit_signal(int signal); void sigatexit(void *handler); -int sig_to_num(char *pidstr); void list_signals(); -char *num_to_sig(int sig); mode_t string_to_mode(char *mode_str, mode_t base); void mode_to_string(mode_t mode, char *buf); diff --git a/lib/portability.c b/lib/portability.c index 088b90e1..d48a3b4d 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -397,3 +397,104 @@ int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev) return result; } #endif + +// Signals required by POSIX 2008: +// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html + +#define SIGNIFY(x) {SIG##x, #x} + +static const struct signame signames[] = { + // POSIX + SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), + SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), + SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(TERM), + SIGNIFY(USR1), SIGNIFY(USR2), SIGNIFY(SYS), SIGNIFY(TRAP), + SIGNIFY(VTALRM), SIGNIFY(XCPU), SIGNIFY(XFSZ), + // Non-POSIX signals that cause termination + SIGNIFY(PROF), SIGNIFY(IO), +#ifdef __linux__ + SIGNIFY(STKFLT), SIGNIFY(POLL), SIGNIFY(PWR), +#elif defined(__APPLE__) + SIGNIFY(EMT), SIGNIFY(INFO), +#endif + + // Note: sigatexit relies on all the signals with a default disposition that + // terminates the process coming *before* SIGCHLD. + + // POSIX signals that don't cause termination + SIGNIFY(CHLD), SIGNIFY(CONT), SIGNIFY(STOP), SIGNIFY(TSTP), + SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(URG), + // Non-POSIX signals that don't cause termination + SIGNIFY(WINCH), +}; +int signames_len = ARRAY_LEN(signames); + +#undef SIGNIFY + +void xsignal_all_killers(void *handler) +{ + int i; + + for (i=0; signames[i].num != SIGCHLD; i++) + if (signames[i].num != SIGKILL) + xsignal(signames[i].num, handler ? exit_signal : SIG_DFL); +} + +// Convert a string like "9", "KILL", "SIGHUP", or "SIGRTMIN+2" to a number. +int sig_to_num(char *sigstr) +{ + int i, offset; + char *s; + + // Numeric? + i = estrtol(sigstr, &s, 10); + if (!errno && !*s) return i; + + // Skip leading "SIG". + strcasestart(&sigstr, "sig"); + + // Named signal? + for (i=0; i<ARRAY_LEN(signames); i++) + if (!strcasecmp(sigstr, signames[i].name)) return signames[i].num; + + // Real-time signal? +#ifdef SIGRTMIN + if (strcasestart(&sigstr, "rtmin")) i = SIGRTMIN; + else if (strcasestart(&sigstr, "rtmax")) i = SIGRTMAX; + else return -1; + + // No offset? + if (!*sigstr) return i; + + // We allow any offset that's still a real-time signal: SIGRTMIN+20 is fine. + // Others are more restrictive, only accepting what they show with -l. + offset = estrtol(sigstr, &s, 10); + if (errno || *s) return -1; + i += offset; + if (i >= SIGRTMIN && i <= SIGRTMAX) return i; +#endif + + return -1; +} + +char *num_to_sig(int sig) +{ + int i; + + // A named signal? + for (i=0; i<signames_len; i++) + if (signames[i].num == sig) return signames[i].name; + + // A real-time signal? +#ifdef SIGRTMIN + if (sig == SIGRTMIN) return "RTMIN"; + if (sig == SIGRTMAX) return "RTMAX"; + if (sig > SIGRTMIN && sig < SIGRTMAX) { + if (sig-SIGRTMIN <= SIGRTMAX-sig) sprintf(libbuf, "RTMIN+%d", sig-SIGRTMIN); + else sprintf(libbuf, "RTMAX-%d", SIGRTMAX-sig); + return libbuf; + } +#endif + + return NULL; +} diff --git a/lib/portability.h b/lib/portability.h index c955eddf..69580da5 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -332,3 +332,12 @@ int xnotify_wait(struct xnotify *not, char **path); #ifdef __APPLE__ #define f_frsize f_iosize #endif + +int sig_to_num(char *s); +char *num_to_sig(int sig); + +struct signame { + int num; + char *name; +}; +void xsignal_all_killers(void *handler); |