pager: set PR_DEATHSIG for pager to SIGINT rather than SIGTERM

"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
This commit is contained in:
Lennart Poettering 2020-06-09 08:59:33 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent c85b6ff1b2
commit 97033ba455
3 changed files with 14 additions and 12 deletions

View 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);
}

View 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);

View 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) {