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