diff options
Diffstat (limited to 'src/util/select_bug.c')
-rw-r--r-- | src/util/select_bug.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/util/select_bug.c b/src/util/select_bug.c new file mode 100644 index 0000000..9b479ca --- /dev/null +++ b/src/util/select_bug.c @@ -0,0 +1,95 @@ +/*++ +/* NAME +/* select_bug 1 +/* SUMMARY +/* select test program +/* SYNOPSIS +/* select_bug +/* DESCRIPTION +/* select_bug forks child processes that perform select() +/* on a shared socket, and sees if a wakeup affects other +/* processes selecting on a different socket or stdin. +/* DIAGNOSTICS +/* Problems are reported to the standard error stream. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> /* bzero() prototype for 44BSD */ + +/* Utility library. */ + +#include <msg.h> +#include <vstream.h> +#include <msg_vstream.h> + +static pid_t fork_and_read_select(const char *what, int delay, int fd) +{ + struct timeval tv; + pid_t pid; + fd_set readfds; + + switch (pid = fork()) { + case -1: + msg_fatal("fork: %m"); + case 0: + tv.tv_sec = delay; + tv.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + switch (select(fd + 1, &readfds, (fd_set *) 0, &readfds, &tv)) { + case -1: + msg_fatal("select: %m"); + case 0: + msg_info("%s select timed out", what); + exit(0); + default: + msg_info("%s select wakeup", what); + exit(0); + } + default: + return (pid); + } +} + +int main(int argc, char **argv) +{ + int pair1[2]; + int pair2[2]; + + msg_vstream_init(argv[0], VSTREAM_ERR); + +#define DELAY 1 + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair1) < 0) + msg_fatal("socketpair: %m"); + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair2) < 0) + msg_fatal("socketpair: %m"); + + vstream_printf("Doing multiple select on socket1, then write to it...\n"); + vstream_fflush(VSTREAM_OUT); + fork_and_read_select("socket1", DELAY, pair1[0]); /* one */ + fork_and_read_select("socket1", DELAY, pair1[0]); /* two */ + fork_and_read_select("socket2", DELAY, pair2[0]); + fork_and_read_select("stdin", DELAY, 0); + if (write(pair1[1], "", 1) != 1) + msg_fatal("write: %m"); + while (wait((int *) 0) >= 0) + /* void */ ; + return (0); +} |