pager: set PR_DEATHSIG for pager to SIGINT rather than SIGTERM
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Jun 2020 06:59:33 +0000 (08:59 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 10 Jun 2020 08:31:22 +0000 (10:31 +0200)
"less" doesn't properly reset its terminal on SIGTERM, it does so only
on SIGINT. Let's thus configure SIGINT instead of SIGTERM.

I think this is something less should fix too, and clean up things
correctly on SIGTERM, too. However, given that we explicitly enable
SIGINT behaviour by passing "K" to $LESS I figure it makes sense if we
also send SIGINT instead of SIGTERM to match it.

Fixes: #16084

src/basic/process-util.c
src/basic/process-util.h
src/shared/pager.c

index 8cb229ca09295dc9bbce641b6234f3f563b98779..f6ecc7f86f5438433e45cf693051d185f5c4eac9 100644 (file)
@@ -1301,8 +1301,8 @@ int safe_fork_full(
                                        r, "Failed to rename process, ignoring: %m");
         }
 
-        if (flags & FORK_DEATHSIG)
-                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) {
+        if (flags & (FORK_DEATHSIG|FORK_DEATHSIG_SIGINT))
+                if (prctl(PR_SET_PDEATHSIG, (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : SIGTERM) < 0) {
                         log_full_errno(prio, errno, "Failed to set death signal: %m");
                         _exit(EXIT_FAILURE);
                 }
index ca9825293c3a2eb1a678df3838301102afc69d07..e0b52246ba5d539459f6a7b397d03cc5fd7f8540 100644 (file)
@@ -150,15 +150,16 @@ int must_be_root(void);
 typedef enum ForkFlags {
         FORK_RESET_SIGNALS      = 1 <<  0, /* Reset all signal handlers and signal mask */
         FORK_CLOSE_ALL_FDS      = 1 <<  1, /* Close all open file descriptors in the child, except for 0,1,2 */
-        FORK_DEATHSIG           = 1 <<  2, /* Set PR_DEATHSIG in the child */
-        FORK_NULL_STDIO         = 1 <<  3, /* Connect 0,1,2 to /dev/null */
-        FORK_REOPEN_LOG         = 1 <<  4, /* Reopen log connection */
-        FORK_LOG                = 1 <<  5, /* Log above LOG_DEBUG log level about failures */
-        FORK_WAIT               = 1 <<  6, /* Wait until child exited */
-        FORK_NEW_MOUNTNS        = 1 <<  7, /* Run child in its own mount namespace */
-        FORK_MOUNTNS_SLAVE      = 1 <<  8, /* Make child's mount namespace MS_SLAVE */
-        FORK_RLIMIT_NOFILE_SAFE = 1 <<  9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
-        FORK_STDOUT_TO_STDERR   = 1 << 10, /* Make stdout a copy of stderr */
+        FORK_DEATHSIG           = 1 <<  2, /* Set PR_DEATHSIG in the child to SIGTERM */
+        FORK_DEATHSIG_SIGINT    = 1 <<  3, /* Set PR_DEATHSIG in the child to SIGINT */
+        FORK_NULL_STDIO         = 1 <<  4, /* Connect 0,1,2 to /dev/null */
+        FORK_REOPEN_LOG         = 1 <<  5, /* Reopen log connection */
+        FORK_LOG                = 1 <<  6, /* Log above LOG_DEBUG log level about failures */
+        FORK_WAIT               = 1 <<  7, /* Wait until child exited */
+        FORK_NEW_MOUNTNS        = 1 <<  8, /* Run child in its own mount namespace */
+        FORK_MOUNTNS_SLAVE      = 1 <<  9, /* Make child's mount namespace MS_SLAVE */
+        FORK_RLIMIT_NOFILE_SAFE = 1 << 10, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
+        FORK_STDOUT_TO_STDERR   = 1 << 11, /* Make stdout a copy of stderr */
 } ForkFlags;
 
 int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
index 1fe9db17917680f3745cbe61bd3b2102492d6b49..e03be6d23b2d7f24264412881b65f889fd607c3f 100644 (file)
@@ -131,7 +131,8 @@ int pager_open(PagerFlags flags) {
         if (flags & PAGER_JUMP_TO_END)
                 less_opts = strjoina(less_opts, " +G");
 
-        r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
+        /* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */
+        r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
         if (r < 0)
                 return r;
         if (r == 0) {