]> err.no Git - util-linux/commitdiff
flock: fix hang when parent ignores SIGCHLD
authorMike Frysinger <vapier@gentoo.org>
Mon, 7 Dec 2009 14:18:17 +0000 (15:18 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 7 Dec 2009 14:23:40 +0000 (15:23 +0100)
If flock is executed from a process which has set SIGCHLD to SIG_IGN, then
flock will eat cpu and hang indefinitely if given a command to execute.
So before we fork(), make sure to set SIGCHLD handling back to the default
so that the later waitpid() doesn't freak out on us.

[kzak@redhat.com: - add a check for waitpid() return value]

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/flock.c

index a53f6d317b44ad5457ca1fb95aea3c21c613d765..75c007c731a41ae1156767fb9439344ca1bf055e 100644 (file)
@@ -287,6 +287,8 @@ int main(int argc, char *argv[])
   if ( cmd_argv ) {
     pid_t w, f;
 
+    /* Clear any inherited settings */
+    signal(SIGCHLD, SIG_DFL);
     f = fork();
 
     if ( f < 0 ) {
@@ -304,9 +306,15 @@ int main(int argc, char *argv[])
     } else {
       do {
        w = waitpid(f, &status, 0);
+       if (w == -1 && errno != EINTR)
+         break;
       } while ( w != f );
 
-      if ( WIFEXITED(status) )
+      if (w == -1) {
+       err = errno;
+       status = EXIT_FAILURE;
+       fprintf(stderr, "%s: waitpid failed: %s\n", program, strerror(err));
+      } else if ( WIFEXITED(status) )
        status = WEXITSTATUS(status);
       else if ( WIFSIGNALED(status) )
        status = WTERMSIG(status) + 128;