Changeset: 82bf5eb519ea for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=82bf5eb519ea
Modified Files:
        tools/merovingian/daemon/controlrunner.c
        tools/merovingian/daemon/handlers.c
Branch: Oct2014
Log Message:

Block SIGCHLD signals when forking for create -p.
By blocking SIGCHLD signals when forking and subsequently waiting for
the forked child when handling the create -p command, and by also
ignoring SIGCHLD signals if there is no child ready to be waited for,
we hopefully fix bug 3603.


diffs (64 lines):

diff --git a/tools/merovingian/daemon/controlrunner.c 
b/tools/merovingian/daemon/controlrunner.c
--- a/tools/merovingian/daemon/controlrunner.c
+++ b/tools/merovingian/daemon/controlrunner.c
@@ -399,6 +399,13 @@ static void ctl_handle_client(
                                } else {
                                        if (*p != '\0') {
                                                pid_t child;
+                                               sigset_t blocksig;
+                                               /* temporarily block SIGCHLD 
signals until
+                                                * we've waited for the child 
we're about to
+                                                * create. See bug 
http://bugs.monetdb.org/3603. */
+                                               sigemptyset(&blocksig);
+                                               sigaddset(&blocksig, SIGCHLD);
+                                               sigprocmask(SIG_BLOCK, 
&blocksig, (sigset_t *) 0);
                                                if ((child = fork()) == 0) {
                                                        FILE *secretf;
                                                        size_t len;
@@ -408,6 +415,10 @@ static void ctl_handle_client(
                                                        int setlen = 0;
                                                        char *sadbfarm;
 
+                                                       sigemptyset(&blocksig);
+                                                       sigaddset(&blocksig, 
SIGCHLD);
+                                                       
sigprocmask(SIG_UNBLOCK, &blocksig, (sigset_t *) 0);
+
                                                        if ((err = 
msab_getDBfarm(&sadbfarm)) != NULL) {
                                                                
Mfprintf(_mero_ctlerr, "%s: internal error: %s\n",
                                                                                
 origin, err);
@@ -456,9 +467,18 @@ static void ctl_handle_client(
                                                        }
 
                                                        exit(0); /* return to 
the parent */
-                                               } else {
+                                               } else if (child > 0) {
                                                        /* wait for the child 
to finish */
                                                        waitpid(child, NULL, 0);
+                                                       sigemptyset(&blocksig);
+                                                       sigaddset(&blocksig, 
SIGCHLD);
+                                                       
sigprocmask(SIG_UNBLOCK, &blocksig, (sigset_t *) 0);
+                                               } else {
+                                                       sigemptyset(&blocksig);
+                                                       sigaddset(&blocksig, 
SIGCHLD);
+                                                       
sigprocmask(SIG_UNBLOCK, &blocksig, (sigset_t *) 0);
+                                                       Mfprintf(_mero_ctlout, 
"%s: forking failed\n",
+                                                                        
origin);
                                                }
                                        }
 
diff --git a/tools/merovingian/daemon/handlers.c 
b/tools/merovingian/daemon/handlers.c
--- a/tools/merovingian/daemon/handlers.c
+++ b/tools/merovingian/daemon/handlers.c
@@ -169,7 +169,11 @@ childhandler(int sig, siginfo_t *si, voi
 
        /* wait for the child to get properly terminated, hopefully filling
         * in the siginfo struct on FreeBSD */
-       wait(NULL);
+       if (waitpid(-1, NULL, WNOHANG) <= 0) {
+               /* if no child has exited, we may have already waited for it
+                * in e.g. ctl_handle_client() */
+               return;
+       }
 
        if (si->si_code != CLD_EXITED &&
                        si->si_code != CLD_KILLED &&
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to