Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2
uname output: Linux zinc 6.6.1-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 08 Nov 2023 16:05:38 +0000 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.2 Patch
Level: 21
Release Status: release

Description:
Hi,

I would like to suggest a new shell option to ensure child processes are automatically killed when the parent dies.

Right now, it's already possible to emulate this feature by setting a trap to kill all child processes on exit (trap "kill 0" EXIT), but obviously it doesn't work if the process is terminated by a signal that cannot be caught (like SIGKILL).

On Linux, it can be done by setting the PR_SET_PDEATHSIG flag to propagate the parent termination signal to the child, regardless of whether the signal can be caught or not.

The rationale for this feature is that scripts spawning background processes to listen to various events (udev events, window manager events, etc) often leave orphan processes behind when terminated forcefully.

I've attached a proof-of-concept patch.
diff --git a/builtins/shopt.def b/builtins/shopt.def
index ba97e702..5ecabde4 100644
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -83,6 +83,7 @@ extern int extended_quote;
 extern int check_window_size;
 extern int glob_ignore_case, match_ignore_case;
 extern int hup_on_exit;
+extern int no_reparent;
 extern int xpg_echo;
 extern int gnu_error_format;
 extern int check_jobs_at_exit;
@@ -247,6 +248,7 @@ static struct {
   { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
   { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
   { "noexpand_translation", &singlequote_translations, (shopt_set_func_t *)NULL },
+  { "noreparent", &no_reparent, (shopt_set_func_t *)NULL },
   { "nullglob",	&allow_null_glob_expansion, (shopt_set_func_t *)NULL },
   { "patsub_replacement", &patsub_replacement, (shopt_set_func_t *)NULL },
 #if defined (PROGRAMMABLE_COMPLETION)
@@ -365,6 +367,7 @@ reset_shopt_options ()
   glob_star = 0;
   gnu_error_format = 0;
   hup_on_exit = 0;
+  no_reparent = 0;
   inherit_errexit = 0;
   interactive_comments = 1;
   lastpipe_opt = 0;
diff --git a/jobs.c b/jobs.c
index b96230fa..572e599c 100644
--- a/jobs.c
+++ b/jobs.c
@@ -65,6 +65,8 @@
 #  include <bsdtty.h>
 #endif /* hpux && !TERMIOS_TTY_DRIVER */
 
+#include <linux/prctl.h>
+
 #include "bashansi.h"
 #include "bashintl.h"
 #include "shell.h"
@@ -221,6 +223,8 @@ PROCESS *the_pipeline = (PROCESS *)NULL;
 /* If this is non-zero, do job control. */
 int job_control = 1;
 
+int no_reparent = 0;
+
 /* Are we running in background? (terminal_pgrp != shell_pgrp) */
 int running_in_background = 0;
 
@@ -2223,6 +2227,9 @@ make_child (command, flags)
 
       /* Restore top-level signal mask, including unblocking SIGTERM */
       restore_sigmask ();
+
+	  if (no_reparent && prctl(PR_SET_PDEATHSIG, SIGTERM))
+		sys_error("prctl");
   
       if (job_control)
 	{
  • FEATURE REQUEST ... Corto Beau
    • Re: FEATURE... Saint Michael
    • Re: FEATURE... Oğuz
      • Re: FEA... Corto Beau via Bug reports for the GNU Bourne Again SHell
        • Re:... Corto Beau via Bug reports for the GNU Bourne Again SHell
          • ... Corto Beau via Bug reports for the GNU Bourne Again SHell
        • Re:... Oğuz
          • ... Corto Beau via Bug reports for the GNU Bourne Again SHell
            • ... Chet Ramey

Reply via email to