diff options
Diffstat (limited to 'src/slave')
| -rw-r--r-- | src/slave/ChangeLog | 24 | ||||
| -rw-r--r-- | src/slave/kpropd.c | 45 |
2 files changed, 59 insertions, 10 deletions
diff --git a/src/slave/ChangeLog b/src/slave/ChangeLog index 5b1285eaf..617728b0f 100644 --- a/src/slave/ChangeLog +++ b/src/slave/ChangeLog @@ -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(), diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c index d0872df29..174024d5c 100644 --- a/src/slave/kpropd.c +++ b/src/slave/kpropd.c @@ -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); |
