Postfix3.3.1
select_bug.c
[詳解]
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 
41 static 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 
70 int 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");
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 }
#define VSTREAM_OUT
Definition: vstream.h:67
#define DELAY
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
int main(int argc, char **argv)
Definition: select_bug.c:70
void msg_vstream_init(const char *name, VSTREAM *vp)
Definition: msg_vstream.c:77
#define VSTREAM_ERR
Definition: vstream.h:68
void msg_info(const char *fmt,...)
Definition: msg.c:199