1/*++ 2/* NAME 3/* select_bug 1 4/* SUMMARY 5/* select test program 6/* SYNOPSIS 7/* select_bug 8/* DESCRIPTION 9/* select_bug forks child processes that perform select() 10/* on a shared socket, and sees if a wakeup affects other 11/* processes selecting on a different socket or stdin. 12/* DIAGNOSTICS 13/* Problems are reported to the standard error stream. 14/* LICENSE 15/* .ad 16/* .fi 17/* The Secure Mailer license must be distributed with this software. 18/* AUTHOR(S) 19/* Wietse Venema 20/* IBM T.J. Watson Research 21/* P.O. Box 704 22/* Yorktown Heights, NY 10598, USA 23/*--*/ 24 25/* System library. */ 26 27#include <sys_defs.h> 28#include <sys/time.h> 29#include <sys/socket.h> 30#include <sys/wait.h> 31#include <unistd.h> 32#include <stdlib.h> 33#include <string.h> /* bzero() prototype for 44BSD */ 34 35/* Utility library. */ 36 37#include <msg.h> 38#include <vstream.h> 39#include <msg_vstream.h> 40 41static pid_t fork_and_read_select(const char *what, int delay, int fd) 42{ 43 struct timeval tv; 44 pid_t pid; 45 fd_set readfds; 46 47 switch (pid = fork()) { 48 case -1: 49 msg_fatal("fork: %m"); 50 case 0: 51 tv.tv_sec = delay; 52 tv.tv_usec = 0; 53 FD_ZERO(&readfds); 54 FD_SET(fd, &readfds); 55 switch (select(fd + 1, &readfds, (fd_set *) 0, &readfds, &tv)) { 56 case -1: 57 msg_fatal("select: %m"); 58 case 0: 59 msg_info("%s select timed out", what); 60 exit(0); 61 default: 62 msg_info("%s select wakeup", what); 63 exit(0); 64 } 65 default: 66 return (pid); 67 } 68} 69 70int main(int argc, char **argv) 71{ 72 int pair1[2]; 73 int pair2[2]; 74 75 msg_vstream_init(argv[0], VSTREAM_ERR); 76 77#define DELAY 1 78 79 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair1) < 0) 80 msg_fatal("socketpair: %m"); 81 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair2) < 0) 82 msg_fatal("socketpair: %m"); 83 84 vstream_printf("Doing multiple select on socket1, then write to it...\n"); 85 vstream_fflush(VSTREAM_OUT); 86 fork_and_read_select("socket1", DELAY, pair1[0]); /* one */ 87 fork_and_read_select("socket1", DELAY, pair1[0]); /* two */ 88 fork_and_read_select("socket2", DELAY, pair2[0]); 89 fork_and_read_select("stdin", DELAY, 0); 90 if (write(pair1[1], "", 1) != 1) 91 msg_fatal("write: %m"); 92 while (wait((int *) 0) >= 0) 93 /* void */ ; 94 return (0); 95} 96