summaryrefslogtreecommitdiffstats
path: root/regress/sys/kern/kqueue/kqueue-process.c
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2018-08-03 15:19:44 +0000
committervisa <visa@openbsd.org>2018-08-03 15:19:44 +0000
commit1e522b7ed1a0747f70c841dcf5b973f4d8de556d (patch)
tree9387fe8223b1ab8fb072ab8aa311649920f105b1 /regress/sys/kern/kqueue/kqueue-process.c
parentMove pledge to after getopt, when the finger program becomes known (diff)
downloadwireguard-openbsd-1e522b7ed1a0747f70c841dcf5b973f4d8de556d.tar.xz
wireguard-openbsd-1e522b7ed1a0747f70c841dcf5b973f4d8de556d.zip
Improve synchronization between the parent and children. This fixes
a spurious test failure spotted by anton@ and eliminates sleeping in the test. Feedback and OK anton@
Diffstat (limited to 'regress/sys/kern/kqueue/kqueue-process.c')
-rw-r--r--regress/sys/kern/kqueue/kqueue-process.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/regress/sys/kern/kqueue/kqueue-process.c b/regress/sys/kern/kqueue/kqueue-process.c
index dd3ae9b536c..79fdfad2d77 100644
--- a/regress/sys/kern/kqueue/kqueue-process.c
+++ b/regress/sys/kern/kqueue/kqueue-process.c
@@ -1,15 +1,15 @@
-/* $OpenBSD: kqueue-process.c,v 1.12 2016/09/20 23:05:27 bluhm Exp $ */
+/* $OpenBSD: kqueue-process.c,v 1.13 2018/08/03 15:19:44 visa Exp $ */
/*
* Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain
*/
#include <sys/types.h>
#include <sys/event.h>
+#include <sys/time.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
-#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -18,21 +18,19 @@
static int process_child(void);
-static void
-usr1handler(int signum)
-{
- /* nada */
-}
+static int pfd1[2];
+static int pfd2[2];
int
do_process(void)
{
struct kevent ke;
+ struct timespec ts;
int kq, status;
pid_t pid, pid2;
int didfork, didchild;
int i;
- struct timespec ts;
+ char ch = 0;
/*
* Timeout in case something doesn't work.
@@ -43,11 +41,11 @@ do_process(void)
ASS((kq = kqueue()) >= 0,
warn("kqueue"));
- /*
- * Install a signal handler so that we can use pause() to synchronize
- * with the child with the parent.
- */
- signal(SIGUSR1, usr1handler);
+ /* Open pipes for synchronizing the children with the parent. */
+ if (pipe(pfd1) == -1)
+ err(1, "pipe 1");
+ if (pipe(pfd2) == -1)
+ err(1, "pipe 2");
switch ((pid = fork())) {
case -1:
@@ -56,8 +54,6 @@ do_process(void)
_exit(process_child());
}
- sleep(2); /* wait for child to settle down. */
-
EV_SET(&ke, pid, EVFILT_PROC, EV_ADD|EV_ENABLE|EV_CLEAR,
NOTE_EXIT|NOTE_FORK|NOTE_EXEC|NOTE_TRACK, 0, NULL);
ASS(kevent(kq, &ke, 1, NULL, 0, NULL) == 0,
@@ -71,7 +67,8 @@ do_process(void)
ASS(errno == ESRCH,
warn("register bogus pid on kqueue returned wrong error"));
- kill(pid, SIGUSR1); /* sync 1 */
+ ASS(write(pfd1[1], &ch, 1) == 1,
+ warn("write sync 1"));
didfork = didchild = 0;
@@ -107,14 +104,18 @@ do_process(void)
ASSX(didchild == 1);
ASSX(didfork == 1);
- kill(pid2, SIGUSR1); /* sync 2.1 */
- kill(pid, SIGUSR1); /* sync 2 */
+ ASS(write(pfd2[1], &ch, 1) == 1,
+ warn("write sync 2.1"));
+ ASS(write(pfd1[1], &ch, 1) == 1,
+ warn("write sync 2"));
- /* Wait for child's exit. */
+ /*
+ * Wait for child's exit. It also implies child-child has exited.
+ * This should ensure that NOTE_EXIT has been posted for both children.
+ * Child-child's events should get aggregated.
+ */
if (wait(&status) < 0)
err(1, "wait");
- /* Wait for child-child's exec/exit to receive two events at once. */
- sleep(1);
for (i = 0; i < 2; i++) {
ASS(kevent(kq, NULL, 0, &ke, 1, &ts) == 1,
@@ -145,23 +146,30 @@ do_process(void)
static int
process_child(void)
{
- signal(SIGCHLD, SIG_IGN); /* ignore our children. */
+ int status;
+ char ch;
- pause();
+ ASS(read(pfd1[0], &ch, 1) == 1,
+ warn("read sync 1"));
/* fork and see if tracking works. */
switch (fork()) {
case -1:
err(1, "fork");
case 0:
- /* sync 2.1 */
- pause();
+ ASS(read(pfd2[0], &ch, 1) == 1,
+ warn("read sync 2.1"));
execl("/usr/bin/true", "true", (char *)NULL);
err(1, "execl(true)");
}
- /* sync 2 */
- pause();
+ ASS(read(pfd1[0], &ch, 1) == 1,
+ warn("read sync 2"));
+
+ if (wait(&status) < 0)
+ err(1, "wait 2");
+ if (!WIFEXITED(status))
+ errx(1, "child-child didn't exit?");
return 0;
}