The attached patch unblocks SIGCHLD before executing a child process.
I believe this will fix the problem; my mistake.

Daniel

On 30 January 2012 17:00, Daniel Richman <m...@danielrichman.co.uk> wrote:
> Whoops. The sig mask blocking  SIGCHLD will be inherited. I can modify the
> patch to fix this later today.
>
> Daniel
>
> On Jan 30, 2012 3:54 PM, "Clint Adams" <cl...@debian.org> wrote:
>>
>> Daniel,
>>
>> On Mon, Jan 30, 2012 at 02:45:08PM +0900, Puzzlet Chung wrote:
>> > Some of my scripts for the cron job, they spawn multiple processes at
>> > once in background and wait till all of them end. But the new patch
>> > from debianutils 4.2 somehow makes the children defunct.
>> > Here's how I reproduced it:
>> >
>> > mkdir -p /tmp/run-parts-test
>> > cd /tmp/run-parts-test
>> > echo $'#!/bin/sh\nls /tmp > /dev/null &\nwait' > test
>> > chmod +x test
>> > run-parts /tmp/run-parts-test
>> >
>> > And the output of ps uf:
>> >
>> > puzzlet  16206  0.0  0.0  22624  4112 pts/9    Ss   13:41   0:00
>> > /bin/bash
>> > puzzlet   6909  0.0  0.0   4052   588 pts/9    S+   14:34   0:00  \_
>> > run-parts /tmp/run-parts-test
>> > puzzlet   6910  0.0  0.0   4148   580 pts/9    S+   14:34   0:00
>> > \_ /bin/sh /tmp/run-parts-test/test
>> > puzzlet   6911  0.0  0.0      0     0 pts/9    Z+   14:34   0:00
>> >    \_ [ls] <defunct>
>> >
>>
>> Thoughts?
--- a/run-parts.c
+++ b/run-parts.c
@@ -51,6 +51,9 @@
 char *custom_ere;
 regex_t hierre, tradre, excsre, classicalre, customre;
 
+static void catch_signals();
+static void restore_signals();
+
 static char* regex_get_error(int errcode, regex_t *compiled);
 static void  regex_compile_pattern(void);
 static void  regex_clean(void);
@@ -178,6 +181,7 @@
     exit(1);
   }
   else if (!pid) {
+    restore_signals();
     if (new_session_mode)
       setsid();
     if (report_mode) {
@@ -347,6 +351,15 @@
     sigprocmask(SIG_BLOCK, &set, NULL);
 }
 
+/* Unblock signals before execing a child */
+static void restore_signals()
+{
+    sigset_t set;
+    sigemptyset(&set);
+    sigaddset(&set, SIGCHLD);
+    sigprocmask(SIG_UNBLOCK, &set, NULL);
+}
+
 /* Find the parts to run & call run_part() */
 void run_parts(char *dirname)
 {

Reply via email to