@@ -50,17 +50,51 @@ typedef struct {
5050 struct sigaction * const sigttou_action_ptr ;
5151} signal_configuration_t ;
5252
53+ static const struct {
54+ char * const name ;
55+ int number ;
56+ } signal_names [] = {
57+ { "SIGHUP" , SIGHUP },
58+ { "SIGINT" , SIGINT },
59+ { "SIGQUIT" , SIGQUIT },
60+ { "SIGILL" , SIGILL },
61+ { "SIGTRAP" , SIGTRAP },
62+ { "SIGABRT" , SIGABRT },
63+ { "SIGBUS" , SIGBUS },
64+ { "SIGFPE" , SIGFPE },
65+ { "SIGKILL" , SIGKILL },
66+ { "SIGUSR1" , SIGUSR1 },
67+ { "SIGSEGV" , SIGSEGV },
68+ { "SIGUSR2" , SIGUSR2 },
69+ { "SIGPIPE" , SIGPIPE },
70+ { "SIGALRM" , SIGALRM },
71+ { "SIGTERM" , SIGTERM },
72+ { "SIGCHLD" , SIGCHLD },
73+ { "SIGCONT" , SIGCONT },
74+ { "SIGSTOP" , SIGSTOP },
75+ { "SIGTSTP" , SIGTSTP },
76+ { "SIGTTIN" , SIGTTIN },
77+ { "SIGTTOU" , SIGTTOU },
78+ { "SIGURG" , SIGURG },
79+ { "SIGXCPU" , SIGXCPU },
80+ { "SIGXFSZ" , SIGXFSZ },
81+ { "SIGVTALRM" , SIGVTALRM },
82+ { "SIGPROF" , SIGPROF },
83+ { "SIGWINCH" , SIGWINCH },
84+ { "SIGSYS" , SIGSYS },
85+ };
86+
5387static unsigned int verbosity = DEFAULT_VERBOSITY ;
5488
5589static int32_t expect_status [(STATUS_MAX - STATUS_MIN + 1 ) / 32 ];
5690
5791#ifdef PR_SET_CHILD_SUBREAPER
5892#define HAS_SUBREAPER 1
59- #define OPT_STRING "hvwgle:s"
93+ #define OPT_STRING "p: hvwgle:s"
6094#define SUBREAPER_ENV_VAR "TINI_SUBREAPER"
6195#else
6296#define HAS_SUBREAPER 0
63- #define OPT_STRING "hvwgle:"
97+ #define OPT_STRING "p: hvwgle:"
6498#endif
6599
66100#define VERBOSITY_ENV_VAR "TINI_VERBOSITY"
@@ -71,6 +105,7 @@ static int32_t expect_status[(STATUS_MAX - STATUS_MIN + 1) / 32];
71105#if HAS_SUBREAPER
72106static unsigned int subreaper = 0 ;
73107#endif
108+ static unsigned int parent_death_signal = 0 ;
74109static unsigned int kill_process_group = 0 ;
75110
76111static unsigned int warn_on_reap = 0 ;
@@ -207,6 +242,7 @@ void print_usage(char* const name, FILE* const file) {
207242#if HAS_SUBREAPER
208243 fprintf (file , " -s: Register as a process subreaper (requires Linux >= 3.4).\n" );
209244#endif
245+ fprintf (file , " -p SIGNAL: Trigger SIGNAL when parent dies, e.g. \"-p SIGKILL\".\n" );
210246 fprintf (file , " -v: Generate more verbose output. Repeat up to 3 times.\n" );
211247 fprintf (file , " -w: Print a warning when processes are getting reaped.\n" );
212248 fprintf (file , " -g: Send signals to the child's process group.\n" );
@@ -235,6 +271,20 @@ void print_license(FILE* const file) {
235271 }
236272}
237273
274+ int set_pdeathsig (char * const arg ) {
275+ size_t i ;
276+
277+ for (i = 0 ; i < ARRAY_LEN (signal_names ); i ++ ) {
278+ if (strcmp (signal_names [i ].name , arg ) == 0 ) {
279+ /* Signals start at value "1" */
280+ parent_death_signal = signal_names [i ].number ;
281+ return 0 ;
282+ }
283+ }
284+
285+ return 1 ;
286+ }
287+
238288int add_expect_status (char * arg ) {
239289 long status = 0 ;
240290 char * endptr = NULL ;
@@ -276,6 +326,14 @@ int parse_args(const int argc, char* const argv[], char* (**child_args_ptr_ptr)[
276326 subreaper ++ ;
277327 break ;
278328#endif
329+ case 'p' :
330+ if (set_pdeathsig (optarg )) {
331+ PRINT_FATAL ("Not a valid option for -p: %s" , optarg );
332+ * parse_fail_exitcode_ptr = 1 ;
333+ return 1 ;
334+ }
335+ break ;
336+
279337 case 'v' :
280338 verbosity ++ ;
281339 break ;
@@ -575,6 +633,12 @@ int main(int argc, char *argv[]) {
575633 return 1 ;
576634 }
577635
636+ /* Trigger signal on this process when the parent process exits. */
637+ if (parent_death_signal && prctl (PR_SET_PDEATHSIG , parent_death_signal )) {
638+ PRINT_FATAL ("Failed to set up parent death signal" );
639+ return 1 ;
640+ }
641+
578642#if HAS_SUBREAPER
579643 /* If available and requested, register as a subreaper */
580644 if (register_subreaper ()) {
0 commit comments