+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(),
struct sockaddr_in sin, frominet;
struct servent *sp;
int finet, fromlen, s;
+ int ret;
finet = socket(AF_INET, SOCK_STREAM, 0);
if (finet < 0) {
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);
exit(1);
}
while (1) {
+ int child_pid;
+
memset((char *)&frominet, 0, sizeof(frominet));
fromlen = sizeof(frominet);
s = accept(finet, (struct sockaddr *) &frominet, &fromlen);
"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);
}
}
{
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 */
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);
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);