• R/O
  • SSH
  • HTTPS

yash: Commit


Commit MetaInfo

Revision4112 (tree)
Time2020-10-11 23:01:12
Authormagicant

Log Message

Refactor sig.c

* original_sigmask is renamed to official_sigmask
* ignored_signals is renamed to officially_ignored_signals
* originally_defaulted_signals and originally_ignored_signals are added

Change Summary

Incremental Difference

--- yash/trunk/sig.c (revision 4111)
+++ yash/trunk/sig.c (revision 4112)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* sig.c: signal handling */
3-/* (C) 2007-2018 magicant */
3+/* (C) 2007-2020 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -82,6 +82,8 @@
8282 static int parse_signal_number(const wchar_t *number)
8383 __attribute__((pure));
8484
85+static int xsigaction(int signum, const struct sigaction *restrict newaction,
86+ struct sigaction *restrict oldaction);
8587 static void set_special_handler(int signum, void (*handler)(int signum));
8688 static void reset_special_handler(
8789 int signum, void (*handler)(int signum), bool leave);
@@ -262,17 +264,19 @@
262264 * If false, trap commands are real. */
263265 static bool is_phantom = false;
264266
265-/* The signal mask the shell inherited on invocation.
266- * This mask is inherited by commands the shell invokes.
267+/* Set of signals that should be blocked in commands invoked by the shell.
268+ * This is by default the same as the mask the shell inherited from the parent.
267269 * When a signal's trap is set, the signal is removed from this mask. */
268-static sigset_t original_sigmask;
269-/* Set of signals whose handler was "ignore" when the shell was invoked but
270- * currently is substituted with the shell's handler.
271- * The handler of these signals must be reset to "ignore" before the shell
272- * invokes another command so that the command inherits "ignore" as the handler.
273- * A signal is added to this set also when its trap handler is set to "ignore".
274- */
275-static sigset_t ignored_signals;
270+static sigset_t official_sigmask;
271+/* Set of signals that are known whose handler was "default"/"ignore" when the
272+ * shell was invoked, respectively. */
273+static sigset_t originally_defaulted_signals, originally_ignored_signals;
274+/* Set of signals whose handler has been installed for the purpose of the
275+ * shell's duty but should be treated as "ignore" in terms of observable
276+ * behavior of the shell. The handler of these signals must be reset to "ignore"
277+ * before the shell invokes a command so that the command inherits "ignore" as
278+ * the handler. */
279+static sigset_t officially_ignored_signals;
276280 /* Set of signals whose trap is set to other than "ignore".
277281 * These signals are almost always blocked. */
278282 static sigset_t trapped_signals;
@@ -301,11 +305,13 @@
301305 /* Initializes the signal module. */
302306 void init_signal(void)
303307 {
304- sigemptyset(&original_sigmask);
305- sigemptyset(&ignored_signals);
308+ sigemptyset(&official_sigmask);
309+ sigemptyset(&originally_defaulted_signals);
310+ sigemptyset(&originally_ignored_signals);
311+ sigemptyset(&officially_ignored_signals);
306312 sigemptyset(&trapped_signals);
307- sigprocmask(SIG_SETMASK, NULL, &original_sigmask);
308- accept_sigmask = original_sigmask;
313+ sigprocmask(SIG_SETMASK, NULL, &official_sigmask);
314+ accept_sigmask = official_sigmask;
309315 }
310316
311317 /* Installs signal handlers used by the shell according to the current settings.
@@ -365,7 +371,7 @@
365371 #endif
366372 }
367373 if (main_handler_set) {
368- sigset_t ss = original_sigmask;
374+ sigset_t ss = official_sigmask;
369375 if (leave) {
370376 main_handler_set = false;
371377 reset_special_handler(SIGCHLD, sig_handler, leave);
@@ -393,16 +399,45 @@
393399 }
394400 }
395401
402+/* Calls `sigaction' and, if the signal is not in either of
403+ * `originally_defaulted_signals' and `originally_ignored_signals', adds it to
404+ * one of them. */
405+int xsigaction(int signum, const struct sigaction *restrict newaction,
406+ struct sigaction *restrict oldaction)
407+{
408+ struct sigaction oldaction2;
409+ sigemptyset(&oldaction2.sa_mask);
410+
411+ if (sigaction(signum, newaction, &oldaction2) < 0)
412+ return -1;
413+
414+ if (oldaction != NULL)
415+ *oldaction = oldaction2;
416+
417+ if (sigismember(&originally_defaulted_signals, signum) ||
418+ sigismember(&originally_ignored_signals, signum))
419+ return 0;
420+
421+ if (oldaction2.sa_handler != SIG_IGN)
422+ sigaddset(&originally_defaulted_signals, signum);
423+ else
424+ sigaddset(&originally_ignored_signals, signum);
425+
426+ return 0;
427+}
428+
396429 /* Sets the signal handler of signal `signum' to function `handler', which must
397430 * be either SIG_IGN or `sig_handler'.
398- * If the old handler is SIG_IGN, `signum' is added to `ignored_signals'.
431+ * If the signal is not in either of `originally_defaulted_signals' and
432+ * `originally_ignored_signals', it is added to one of them.
433+ * If the previous signal handler was SIG_IGN, the signal is added to
434+ * `officially_ignored_signals'.
399435 * If `handler' is SIG_IGN and the trap for the signal is set, the signal
400436 * handler is not changed. */
401437 /* Note that this function does not block or unblock the specified signal. */
402438 void set_special_handler(int signum, void (*handler)(int signum))
403439 {
404- const wchar_t *trap = trap_command[sigindex(signum)];
405- if (!is_phantom && trap != NULL && trap[0] != L'\0')
440+ if (!is_phantom && sigismember(&trapped_signals, signum))
406441 return; /* The signal handler has already been set. */
407442
408443 struct sigaction action, oldaction;
@@ -410,9 +445,9 @@
410445 action.sa_handler = handler;
411446 sigemptyset(&action.sa_mask);
412447 sigemptyset(&oldaction.sa_mask);
413- if (sigaction(signum, &action, &oldaction) >= 0)
448+ if (xsigaction(signum, &action, &oldaction) >= 0)
414449 if (oldaction.sa_handler == SIG_IGN)
415- sigaddset(&ignored_signals, signum);
450+ sigaddset(&officially_ignored_signals, signum);
416451 }
417452
418453 /* Resets the signal handler for signal `signum' to what external commands
@@ -423,7 +458,7 @@
423458 void reset_special_handler(int signum, void (*handler)(int signum), bool leave)
424459 {
425460 struct sigaction action;
426- if (sigismember(&ignored_signals, signum))
461+ if (sigismember(&officially_ignored_signals, signum))
427462 action.sa_handler = SIG_IGN;
428463 else if (sigismember(&trapped_signals, signum))
429464 return;
@@ -463,12 +498,12 @@
463498 sigemptyset(&action.sa_mask);
464499 action.sa_flags = 0;
465500 action.sa_handler = SIG_IGN;
466- sigaction(SIGQUIT, &action, NULL);
467- sigaction(SIGINT, &action, NULL);
501+ xsigaction(SIGQUIT, &action, NULL);
502+ xsigaction(SIGINT, &action, NULL);
468503 } /* Don't set the handers if interactive because they are reset when
469504 `restore_signals' is called later. */
470- sigaddset(&ignored_signals, SIGQUIT);
471- sigaddset(&ignored_signals, SIGINT);
505+ sigaddset(&officially_ignored_signals, SIGQUIT);
506+ sigaddset(&officially_ignored_signals, SIGINT);
472507 }
473508
474509 /* Sets the action of SIGTSTP to ignoring the signal
@@ -483,9 +518,9 @@
483518 sigemptyset(&action.sa_mask);
484519 action.sa_flags = 0;
485520 action.sa_handler = SIG_IGN;
486- sigaction(SIGTSTP, &action, NULL);
521+ xsigaction(SIGTSTP, &action, NULL);
487522 */
488- sigaddset(&ignored_signals, SIGTSTP);
523+ sigaddset(&officially_ignored_signals, SIGTSTP);
489524 }
490525
491526 /* Sends SIGSTOP to the shell process (and the processes in the same process
@@ -859,12 +894,12 @@
859894 action.sa_handler = sig_handler;
860895
861896 if (action.sa_handler == SIG_IGN) {
862- sigaddset(&ignored_signals, signum);
897+ sigaddset(&officially_ignored_signals, signum);
863898 } else {
864- sigdelset(&ignored_signals, signum);
899+ sigdelset(&officially_ignored_signals, signum);
865900 }
866901 if (action.sa_handler == sig_handler) {
867- sigdelset(&original_sigmask, signum);
902+ sigdelset(&official_sigmask, signum);
868903 sigaddset(&trapped_signals, signum);
869904 sigdelset(&accept_sigmask, signum);
870905 } else {
@@ -906,7 +941,7 @@
906941
907942 sigemptyset(&action.sa_mask);
908943 action.sa_flags = 0;
909- if (sigaction(signum, &action, NULL) < 0) {
944+ if (xsigaction(signum, &action, NULL) < 0) {
910945 int saveerrno = errno;
911946 xerror(saveerrno, "sigaction(SIG%ls)", get_signal_name(signum));
912947 }
@@ -923,7 +958,7 @@
923958
924959 if (doing_job_control_now &&
925960 (signum == SIGTTIN || signum == SIGTTOU || signum == SIGTSTP))
926- return sigismember(&ignored_signals, signum);
961+ return sigismember(&officially_ignored_signals, signum);
927962
928963 struct sigaction action;
929964 sigemptyset(&action.sa_mask);
Show on old repository browser