aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c91
-rw-r--r--lib/lib.h2
-rw-r--r--lib/portability.c101
-rw-r--r--lib/portability.h9
4 files changed, 114 insertions, 89 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 17af3c35..b488407e 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -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');
diff --git a/lib/lib.h b/lib/lib.h
index 7f79bdb8..c3b3671c 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -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);