From ca05cace316acdb0ea7677a6ddc83610697f2b24 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Tue, 18 Apr 1995 21:51:11 +0000 Subject: [PATCH] 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. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5368 dc483132-0cff-0310-8789-dd5450dbe970 --- src/slave/ChangeLog | 24 ++++++++++++++++++++++++ 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 + + * 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; /* 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); -- 2.26.2