Use kqueue(2) instead of select(2).

This helps to ensure we will not lose SIGINT sent by parent to child.

Reviewed by:	sbruno, ngie
Sponsored by:	DARPA, AFRL
Sponsored by:	HEIF5
Differential Revision:	https://reviews.freebsd.org/D7892
This commit is contained in:
Ruslan Bukin 2016-09-21 11:59:52 +00:00
parent bc3ad3a179
commit dab6d6fb5a

View File

@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/event.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
@ -43,8 +44,8 @@ __FBSDID("$FreeBSD$");
#include <libutil.h> #include <libutil.h>
/* /*
* We need a signal handler so kill(2) will interrupt our child's * We need a signal handler so kill(2) will interrupt the child
* select(2) instead of killing it. * instead of killing it.
*/ */
static void static void
signal_handler(int sig) signal_handler(int sig)
@ -129,7 +130,9 @@ common_test_pidfile_child(const char *fn, int parent_open)
struct pidfh *pf = NULL; struct pidfh *pf = NULL;
pid_t other = 0, pid = 0; pid_t other = 0, pid = 0;
int fd[2], serrno, status; int fd[2], serrno, status;
struct kevent event, ke;
char ch; char ch;
int kq;
unlink(fn); unlink(fn);
if (pipe(fd) != 0) if (pipe(fd) != 0)
@ -166,10 +169,20 @@ common_test_pidfile_child(const char *fn, int parent_open)
if (pf == NULL) if (pf == NULL)
_exit(1); _exit(1);
if (pidfile_write(pf) != 0) if (pidfile_write(pf) != 0)
_exit(1); _exit(2);
kq = kqueue();
if (kq == -1)
_exit(3);
EV_SET(&ke, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
/* Attach event to the kqueue. */
if (kevent(kq, &ke, 1, NULL, 0, NULL) != 0)
_exit(4);
/* Inform the parent we are ready to receive SIGINT */
if (write(fd[1], "*", 1) != 1) if (write(fd[1], "*", 1) != 1)
_exit(1); _exit(5);
select(0, 0, 0, 0, 0); /* Wait for SIGINT received */
if (kevent(kq, NULL, 0, &event, 1, NULL) != 1)
_exit(6);
_exit(0); _exit(0);
} }
// parent // parent