diff options
author | wpaul <wpaul@FreeBSD.org> | 1997-01-11 17:16:18 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1997-01-11 17:16:18 +0000 |
commit | c5b15215e52f7aa9e2eb74570d6714d0257f9303 (patch) | |
tree | 087ef55667cf5637332b27912040a2d40f8cb481 /usr.sbin/ypbind | |
parent | aad3e50634d653ff32edb34a6dc3f896e1a8315a (diff) | |
download | FreeBSD-src-c5b15215e52f7aa9e2eb74570d6714d0257f9303.zip FreeBSD-src-c5b15215e52f7aa9e2eb74570d6714d0257f9303.tar.gz |
Correct two bugs:
- If a child receives a SIGTERM, it will call the terminate() function
and end up doing the shutdown procedurs that should really only be
done by the parent. Set the SIGTERM behavior back to SIG_DLT in the
child after fork()ing.
- If the parent fails to read data back from the child because the
child has exited, it will call rpc_received() with bogus tdata that
can cause the parent to SEGV. Make handle_children() detect this
condition correctly and handle it sanely.
*sigh* Another 2.2 candidate.
Diffstat (limited to 'usr.sbin/ypbind')
-rw-r--r-- | usr.sbin/ypbind/ypbind.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/usr.sbin/ypbind/ypbind.c b/usr.sbin/ypbind/ypbind.c index a4e7ef1..ded22fb 100644 --- a/usr.sbin/ypbind/ypbind.c +++ b/usr.sbin/ypbind/ypbind.c @@ -28,7 +28,7 @@ */ #ifndef LINT -static char rcsid[] = "$Id: ypbind.c,v 1.18 1995/12/15 03:39:25 wpaul Exp $"; +static char rcsid[] = "$Id: ypbind.c,v 1.19 1996/12/30 15:31:26 peter Exp $"; #endif #include <sys/param.h> @@ -132,7 +132,7 @@ struct in_addr restricted_addrs[RESTRICTED_SERVERS]; #endif /* RPC timeout value */ #ifndef FAIL_THRESHOLD -#define FAIL_THRESHOLD 10 +#define FAIL_THRESHOLD 20 #endif /* Number of times to fish for a response froma particular set of hosts */ @@ -193,7 +193,7 @@ CLIENT *clnt; } ypdb = (struct _dom_binding *)malloc(sizeof *ypdb); if (ypdb == NULL) { - syslog(LOG_WARNING, "malloc: %s", strerror(errno)); + syslog(LOG_WARNING, "malloc: %m"); res.ypbind_resp_u.ypbind_error = YPBIND_ERR_RESC; return &res; } @@ -483,7 +483,7 @@ char **argv; break; case -1: if (errno != EINTR) - syslog(LOG_WARNING, "select: %s", strerror(errno)); + syslog(LOG_WARNING, "select: %m"); break; default: for(ypdb=ypbindlist; ypdb; ypdb=ypdb->dom_pnext) { @@ -525,17 +525,52 @@ struct _dom_binding *ypdb; { char buf[YPMAXDOMAIN + 1]; struct sockaddr_in addr; + int d = 0, a = 0; + struct _dom_binding *y, *prev = NULL; + char path[MAXPATHLEN]; + + if ((d = read(READFD, &buf, sizeof(buf))) <= 0) + syslog(LOG_WARNING, "could not read from child: %m"); - if (read(READFD, &buf, sizeof(buf)) < 0) - syslog(LOG_WARNING, "could not read from child: %s", strerror(errno)); - if (read(READFD, &addr, sizeof(struct sockaddr_in)) < 0) - syslog(LOG_WARNING, "could not read from child: %s", strerror(errno)); + if ((a = read(READFD, &addr, sizeof(struct sockaddr_in))) < 0) + syslog(LOG_WARNING, "could not read from child: %m"); close(READFD); FD_CLR(READFD, &fdsr); FD_CLR(READFD, &svc_fdset); READFD = WRITEFD = -1; - rpc_received((char *)&buf, &addr, 0); + if (d > 0 && a > 0) + rpc_received((char *)&buf, &addr, 0); + else { + for(y=ypbindlist; y; y=y->dom_pnext) { + if (y == ypdb) + break; + prev = y; + } + switch(ypdb->dom_default) { + case 0: + if (prev == NULL) + ypbindlist = y->dom_pnext; + else + prev->dom_pnext = y->dom_pnext; + sprintf(path, "%s/%s.%ld", BINDINGDIR, + ypdb->dom_domain, YPVERS); + close(ypdb->dom_lockfd); + unlink(path); + free(ypdb); + domains--; + return; + case 1: + ypdb->dom_broadcast_pid = 0; + ypdb->dom_alive = 0; + broadcast(ypdb); + return; + default: + break; + } + } + + return; } /* @@ -620,7 +655,7 @@ struct _dom_binding *ypdb; return; if (pipe(ypdb->dom_pipe_fds) < 0) { - syslog(LOG_WARNING, "pipe: %s",strerror(errno)); + syslog(LOG_WARNING, "pipe: %m"); return; } @@ -634,9 +669,11 @@ struct _dom_binding *ypdb; switch((ypdb->dom_broadcast_pid = fork())) { case 0: close(READFD); + signal(SIGCHLD, SIG_DFL); + signal(SIGTERM, SIG_DFL); break; case -1: - syslog(LOG_WARNING, "fork: %s", strerror(errno)); + syslog(LOG_WARNING, "fork: %m"); close(READFD); close(WRITEFD); return; @@ -810,7 +847,7 @@ int force; return; ypdb = (struct _dom_binding *)malloc(sizeof *ypdb); if (ypdb == NULL) { - syslog(LOG_WARNING, "malloc: %s", strerror(errno)); + syslog(LOG_WARNING, "malloc: %m"); return; } bzero((char *)ypdb, sizeof *ypdb); @@ -870,7 +907,7 @@ int force; *(u_short *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port = raddrp->sin_port; if( writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) { - syslog(LOG_WARNING, "write: %s", strerror(errno)); + syslog(LOG_WARNING, "write: %m"); close(ypdb->dom_lockfd); ypdb->dom_lockfd = -1; return; |