summaryrefslogtreecommitdiff
path: root/usr.sbin/rpcbind
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2018-01-02 17:25:13 +0000
committerConrad Meyer <cem@FreeBSD.org>2018-01-02 17:25:13 +0000
commit35f85edc809e9df9da1327b4f74d8271b03abeb8 (patch)
treeae788a60d15c711f8cbd8be346a28df453390d93 /usr.sbin/rpcbind
parent8b081eaa55b1eb7a457f7bf43be5997a1fef3ac0 (diff)
downloadsrc-test2-35f85edc809e9df9da1327b4f74d8271b03abeb8.tar.gz
src-test2-35f85edc809e9df9da1327b4f74d8271b03abeb8.zip
Notes
Diffstat (limited to 'usr.sbin/rpcbind')
-rw-r--r--usr.sbin/rpcbind/rpcb_svc_com.c30
-rw-r--r--usr.sbin/rpcbind/rpcbind.c18
-rw-r--r--usr.sbin/rpcbind/rpcbind.h1
3 files changed, 37 insertions, 12 deletions
diff --git a/usr.sbin/rpcbind/rpcb_svc_com.c b/usr.sbin/rpcbind/rpcb_svc_com.c
index 973e7a542ca3..8dc68ee3f7e1 100644
--- a/usr.sbin/rpcbind/rpcb_svc_com.c
+++ b/usr.sbin/rpcbind/rpcb_svc_com.c
@@ -1101,7 +1101,7 @@ void
my_svc_run(void)
{
size_t nfds;
- struct pollfd pollfds[FD_SETSIZE];
+ struct pollfd pollfds[FD_SETSIZE + 1];
int poll_ret, check_ret;
int n;
#ifdef SVC_RUN_DEBUG
@@ -1112,6 +1112,9 @@ my_svc_run(void)
for (;;) {
p = pollfds;
+ p->fd = terminate_rfd;
+ p->events = MASKVAL;
+ p++;
for (n = 0; n <= svc_maxfd; n++) {
if (FD_ISSET(n, &svc_fdset)) {
p->fd = n;
@@ -1130,23 +1133,26 @@ my_svc_run(void)
fprintf(stderr, ">\n");
}
#endif
- switch (poll_ret = poll(pollfds, nfds, 30 * 1000)) {
+ poll_ret = poll(pollfds, nfds, 30 * 1000);
+
+ if (doterminate != 0) {
+ close(rpcbindlockfd);
+#ifdef WARMSTART
+ syslog(LOG_ERR,
+ "rpcbind terminating on signal %d. Restart with \"rpcbind -w\"",
+ (int)doterminate);
+ write_warmstart(); /* Dump yourself */
+#endif
+ exit(2);
+ }
+
+ switch (poll_ret) {
case -1:
/*
* We ignore all errors, continuing with the assumption
* that it was set by the signal handlers (or any
* other outside event) and not caused by poll().
*/
- if (doterminate != 0) {
- close(rpcbindlockfd);
-#ifdef WARMSTART
- syslog(LOG_ERR,
- "rpcbind terminating on signal %d. Restart with \"rpcbind -w\"",
- (int)doterminate);
- write_warmstart(); /* Dump yourself */
-#endif
- exit(2);
- }
case 0:
cleanfds = svc_fdset;
__svc_clean_idle(&cleanfds, 30, FALSE);
diff --git a/usr.sbin/rpcbind/rpcbind.c b/usr.sbin/rpcbind/rpcbind.c
index 71f1e66c925c..c9779fa9f34c 100644
--- a/usr.sbin/rpcbind/rpcbind.c
+++ b/usr.sbin/rpcbind/rpcbind.c
@@ -79,6 +79,7 @@ static char sccsid[] = "@(#)rpcbind.c 1.35 89/04/21 Copyr 1984 Sun Micro";
/* Global variables */
int debugging = 0; /* Tell me what's going on */
int doabort = 0; /* When debugging, do an abort on errors */
+int terminate_rfd; /* Pipefd to wake on signal */
volatile sig_atomic_t doterminate = 0; /* Terminal signal received */
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
int rpcbindlockfd;
@@ -101,6 +102,7 @@ static struct sockaddr **bound_sa;
static int ipv6_only = 0;
static int nhosts = 0;
static int on = 1;
+static int terminate_wfd;
#ifdef WARMSTART
/* Local Variable */
@@ -133,6 +135,7 @@ main(int argc, char *argv[])
void *nc_handle; /* Net config handle */
struct rlimit rl;
int maxrec = RPC_MAXDATASIZE;
+ int error, fds[2];
parseargs(argc, argv);
@@ -192,6 +195,16 @@ main(int argc, char *argv[])
}
endnetconfig(nc_handle);
+ /*
+ * Allocate pipe fd to wake main thread from signal handler in non-racy
+ * way.
+ */
+ error = pipe(fds);
+ if (error != 0)
+ err(1, "pipe failed");
+ terminate_rfd = fds[0];
+ terminate_wfd = fds[1];
+
/* catch the usual termination signals for graceful exit */
(void) signal(SIGCHLD, reap);
(void) signal(SIGINT, terminate);
@@ -761,8 +774,13 @@ rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
static void
terminate(int signum)
{
+ char c = '\0';
+ ssize_t wr;
doterminate = signum;
+ wr = write(terminate_wfd, &c, 1);
+ if (wr < 1)
+ _exit(2);
}
void
diff --git a/usr.sbin/rpcbind/rpcbind.h b/usr.sbin/rpcbind/rpcbind.h
index 695b24455b16..a4bb3d274066 100644
--- a/usr.sbin/rpcbind/rpcbind.h
+++ b/usr.sbin/rpcbind/rpcbind.h
@@ -70,6 +70,7 @@ struct r_rmtcall_args {
extern int debugging;
extern int doabort;
+extern int terminate_rfd;
extern volatile sig_atomic_t doterminate;
#ifdef LIBWRAP
extern int libwrap;