kpropd uses fork instead of vfork, because it's closing file
authorTheodore Tso <tytso@mit.edu>
Tue, 18 Apr 1995 21:51:11 +0000 (21:51 +0000)
committerTheodore Tso <tytso@mit.edu>
Tue, 18 Apr 1995 21:51:11 +0000 (21:51 +0000)
descriptors in the child.

Print out the pid of the child process if debugging is enabled.

Use _exit() instead exit() after a fork(), so that child process
doesn't cause the stdio buffers don't get flushed twice.

When debugging is enabled and kpropd can't bind to the port, it should
try binding again after setting SO_REUSEADDR on the socket.  This
avoids problems when debugging modifications to kprop/kpropd or its
setup, when kpropd is run twice quickly in succession.

kpropd shouldn't signal(SIGCHLD, SIG_IGN) in the parent.  Instead, it
should wait() until the child exits.  This was causing problems
because setting SIGCHLD to SIG_IGN under SYSV causes child processes
to get reaped automatically, so the wait() for kdb5_edit was failing.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5368 dc483132-0cff-0310-8789-dd5450dbe970

src/slave/ChangeLog
src/slave/kpropd.c

index 5b1285eaf9d08aa018f71c83076c98743d4764bb..617728b0ff66e0dd728bcf64743124bc3445ce30 100644 (file)
@@ -1,3 +1,27 @@
+Fri Apr 14 15:23:29 1995    <tytso@rsx-11.mit.edu>
+
+       * kpropd.c (load_database): kpropd uses fork instead of vfork,
+               because it's closing file descriptors in the child.
+
+               Print out the pid of the child process if debugging is
+               enabled. 
+
+               Use _exit() instead exit() after a fork(), so that child
+               process doesn't cause the stdio buffers don't get flushed
+               twice.
+
+               When debugging is enabled and kpropd can't bind to the
+               port, it should try binding again after setting
+               SO_REUSEADDR on the socket.  This avoids problems when
+               debugging modifications to kprop/kpropd or its setup, when
+               kpropd is run twice quickly in succession. 
+
+               kpropd shouldn't signal(SIGCHLD, SIG_IGN) in the parent.
+               Instead, it should wait() until the child exits.  This was
+               causing problems because setting SIGCHLD to SIG_IGN under
+               SYSV causes child processes to get reaped automatically,
+               so the wait() for kdb5_edit was failing.
+
 Mon Mar 27 07:56:26 1995 Chris Provenzano (proven@mit.edu)
 
         * kprop.c : Use new calling conventions for krb5_sendauth(),
index d0872df29afa3c65dad89500eda81eb7bd9baf33..174024d5c48e29426edadc33288d752af018aa85 100644 (file)
@@ -138,6 +138,7 @@ void do_standalone()
        struct  sockaddr_in     sin, frominet;
        struct servent *sp;
        int     finet, fromlen, s;
+       int     ret;
        
        finet = socket(AF_INET, SOCK_STREAM, 0);
        if (finet < 0) {
@@ -152,10 +153,22 @@ void do_standalone()
        memset((char *) &sin,0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_port = sp->s_port;
-       if (bind(finet, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+       if ((ret = bind(finet, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
+           if (debug) {
+               int on = 1;
+               fprintf(stderr,
+                       "%s: attempting to rebind socket with SO_REUSEADDR\n",
+                       progname);
+               if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
+                              (char *)&on, sizeof(on)) < 0)
+                   com_err(progname, errno, "in setsockopt(SO_REUSEADDR)");
+               ret = bind(finet, (struct sockaddr *) &sin, sizeof(sin));
+           }
+           if (ret < 0) {
                perror("bind");
                com_err(progname, errno, "while binding listener socket");
                exit(1);
+           }
        }
        if (!debug)
                daemon(1, 0);       
@@ -172,6 +185,8 @@ void do_standalone()
                exit(1);
        }
        while (1) {
+               int child_pid;
+           
                memset((char *)&frominet, 0, sizeof(frominet));
                fromlen = sizeof(frominet);
                s = accept(finet, (struct sockaddr *) &frominet, &fromlen);
@@ -182,15 +197,25 @@ void do_standalone()
                                        "from accept system call");
                        continue;
                }
-               if (debug || fork() == 0) {
-                       (void) signal(SIGCHLD, SIG_IGN);
+               if (debug)
+                       child_pid = 0;
+               else
+                       child_pid = fork();
+               switch (child_pid) {
+               case -1:
+                       com_err(progname, errno, "while forking");
+                       exit(1);
+               case 0:
                        (void) close(finet);
 
                        doit(s);
                        close(s);
-                       exit(0);
+                       _exit(0);
+               default:
+                       wait(0);
+                       close(s);
+                       
                }
-               close(s);
        }
 }
 
@@ -749,6 +774,7 @@ load_database(context, kdb5_edit, database_file_name)
 {
        static char     *edit_av[4];
        int     error_ret, save_stderr;
+       int     child_pid;
 
        /* <sys/param.h> has been included, so BSD will be defined on
           BSD systems */
@@ -773,10 +799,7 @@ load_database(context, kdb5_edit, database_file_name)
        edit_av[2] = request;
        edit_av[3] = NULL;
 
-#ifndef BSD
-#define        vfork fork
-#endif
-       switch(vfork()) {
+       switch(child_pid = fork()) {
        case -1:
                com_err(progname, errno, "while trying to fork %s",
                        kdb5_edit);
@@ -798,9 +821,11 @@ load_database(context, kdb5_edit, database_file_name)
                        dup2(save_stderr, 2);
                com_err(progname, retval, "while trying to exec %s",
                        kdb5_edit);
-               exit(1);
+               _exit(1);
                /*NOTREACHED*/
        default:
+               if (debug)
+                   printf("Child PID is %d\n", child_pid);
                if (wait(&waitb) < 0) {
                        com_err(progname, errno, "while waiting for %s",
                                kdb5_edit);