xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/select_bug.c (revision 41fbaed053f8fbfdf9d2a4ee0a7386a3c83f8505)
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 
fork_and_read_select(const char * what,int delay,int fd)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 
main(int argc,char ** argv)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