No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / fifo_rdonly_bug.c
blobc13d781a8b9351a6d2922d9f0c0f250263490168
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* fifo_rdonly_bug 1
6 /* SUMMARY
7 /* fifo server test program
8 /* SYNOPSIS
9 /* fifo_rdonly_bug
10 /* DESCRIPTION
11 /* fifo_rdonly_bug creates a FIFO and opens it read only. It
12 /* then opens the FIFO for writing, writes one byte, and closes
13 /* the writing end. On Linux Redhat 4.2 and 5.0, and HP-UX 9.05
14 /* and 10.20, select() will report that the FIFO remains readable
15 /* even after multiple read operations.
16 /* DIAGNOSTICS
17 /* Problems are reported to the standard error stream.
18 /* LICENSE
19 /* .ad
20 /* .fi
21 /* The Secure Mailer license must be distributed with this software.
22 /* AUTHOR(S)
23 /* Wietse Venema
24 /* IBM T.J. Watson Research
25 /* P.O. Box 704
26 /* Yorktown Heights, NY 10598, USA
27 /*--*/
29 #include <sys_defs.h>
30 #include <sys/stat.h>
31 #include <sys/time.h>
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <string.h>
38 #define FIFO_PATH "test-fifo"
39 #define TRIGGER_DELAY 5
41 #define perrorexit(s) { perror(s); exit(1); }
43 static void cleanup(void)
45 printf("Removing fifo %s...\n", FIFO_PATH);
46 if (unlink(FIFO_PATH))
47 perrorexit("unlink");
48 printf("Done.\n");
51 static void perrorcleanup(char *str)
53 perror(str);
54 cleanup();
55 exit(0);
58 static void readable_event(int fd)
60 char ch;
61 static int count = 0;
63 if (read(fd, &ch, 1) < 0) {
64 perror("read");
65 sleep(1);
67 if (count++ > 5) {
68 printf("FIFO remains readable after multiple reads.\n");
69 cleanup();
70 exit(1);
74 int main(int unused_argc, char **unused_argv)
76 struct timeval tv;
77 fd_set read_fds;
78 fd_set except_fds;
79 int fd;
80 int fd2;
82 (void) unlink(FIFO_PATH);
84 printf("Create fifo %s...\n", FIFO_PATH);
85 if (mkfifo(FIFO_PATH, 0600) < 0)
86 perrorexit("mkfifo");
88 printf("Open fifo %s, read-only mode...\n", FIFO_PATH);
89 if ((fd = open(FIFO_PATH, O_RDONLY | O_NONBLOCK, 0)) < 0)
90 perrorcleanup("open");
92 printf("Write one byte to the fifo, then close it...\n");
93 if ((fd2 = open(FIFO_PATH, O_WRONLY, 0)) < 0)
94 perrorcleanup("open fifo O_WRONLY");
95 if (write(fd2, "", 1) < 1)
96 perrorcleanup("write one byte to fifo");
97 if (close(fd2) < 0)
98 perrorcleanup("close fifo");
100 printf("Selecting the fifo for readability...\n");
102 for (;;) {
103 FD_ZERO(&read_fds);
104 FD_SET(fd, &read_fds);
105 FD_ZERO(&except_fds);
106 FD_SET(fd, &except_fds);
107 tv.tv_sec = 1;
108 tv.tv_usec = 0;
110 switch (select(fd + 1, &read_fds, (fd_set *) 0, &except_fds, &tv)) {
111 case -1:
112 perrorexit("select");
113 default:
114 if (FD_ISSET(fd, &except_fds)) {
115 printf("Exceptional fifo condition! You are not normal!\n");
116 readable_event(fd);
117 } else if (FD_ISSET(fd, &read_fds)) {
118 printf("Readable fifo condition\n");
119 readable_event(fd);
121 break;
122 case 0:
123 printf("The fifo is not readable. You're normal.\n");
124 cleanup();
125 exit(0);
126 break;