3 #include <sys/syslimits.h>
15 void copy_subtests(void);
16 void test_pipe_cloexec(void);
17 void test_pipe_flag_setting(void);
18 void test_pipe_nonblock(void);
19 void test_pipe_normal(void);
20 void test_pipe_nosigpipe(void);
21 void alarm_handler(int sig
);
22 void pipe_handler(int sig
);
24 static int seen_pipe_signal
= 0;
25 static int seen_alarm_signal
= 0;
28 alarm_handler(int sig
)
30 if (seen_pipe_signal
== 0)
31 seen_pipe_signal
= -1;
32 seen_alarm_signal
= 1;
44 char *subtests
[] = { "t68a", "t68b" };
45 char copy_cmd
[8 + PATH_MAX
+ 1];
48 no_tests
= sizeof(subtests
) / sizeof(char *);
50 for (i
= 0; i
< no_tests
; i
++) {
51 snprintf(copy_cmd
, 8 + PATH_MAX
, "cp ../%s .", subtests
[i
]);
59 /* Verify pipe2 creates pipes that behave like a normal pipe */
62 char buf_in
[1], buf_out
[1];
67 if (pipe2(pipes
, 0) != 0) e(1);
70 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != sizeof(buf_out
)) e(2);
71 if (read(pipes
[0], buf_in
, sizeof(buf_in
)) != sizeof(buf_in
)) e(3);
72 if (buf_out
[0] != buf_in
[0]) e(4);
74 /* When we close the write end, reading should fail */
75 if (close(pipes
[1]) != 0) e(5);
76 if (read(pipes
[0], buf_in
, sizeof(buf_in
)) != 0) e(6);
78 /* Let's retry that experiment the other way around. Install a signal
79 * handler to catch SIGPIPE. Install an alarm handler to make sure
80 * this test finishes in finite time. */
81 if (pipe2(pipes
, 0) != 0) e(7);
82 signal(SIGPIPE
, pipe_handler
);
83 signal(SIGALRM
, alarm_handler
);
85 seen_alarm_signal
= 0;
87 if (close(pipes
[0]) != 0) e(8);
88 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != -1) e(9);
89 while (seen_pipe_signal
== 0)
91 if (seen_pipe_signal
!= 1) e(10);
92 if (close(pipes
[1]) != 0) e(11);
94 /* Collect alarm signal */
95 while (seen_alarm_signal
== 0)
98 if (pipe2(pipes
, 0) != 0) e(12);
100 /* Now fork and verify we can write to the pipe */
104 /* We're the child */
107 /* Verify we can still write a byte into the pipe */
108 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != 1) e(14);
110 snprintf(fd_buf
, sizeof(fd_buf
), "%d", pipes
[1]);
111 execl("./t68a", "t68a", fd_buf
, NULL
);
113 exit(1); /* Should not be reached */
115 /* We're the parent */
118 if (waitpid(pid
, &result
, 0) == -1) e(15);
119 if (WEXITSTATUS(result
) != 0) e(16);
122 if (close(pipes
[0]) != 0) e(17);
123 if (close(pipes
[1]) != 0) e(18);
129 /* Open a pipe with O_CLOEXEC */
133 char buf_in
[1], buf_out
[1];
137 if (pipe2(pipes
, O_CLOEXEC
) != 0) e(1);
139 /* Verify O_CLOEXEC flag is set */
140 flags
= fcntl(pipes
[0], F_GETFD
);
142 if (!(flags
& FD_CLOEXEC
)) e(3);
147 /* We're the child */
150 /* Verify we can still write a byte into the pipe */
153 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != 1) e(5);
154 if (read(pipes
[0], buf_in
, sizeof(buf_in
)) != 1) e(6);
155 if (buf_out
[0] != buf_in
[0]) e(7);
157 /* Verify FD_CLOEXEC flag is still set */
158 flags
= fcntl(pipes
[0], F_GETFD
);
160 if (!(flags
& FD_CLOEXEC
)) e(9);
162 snprintf(fd_buf
, sizeof(fd_buf
), "%d", pipes
[0]);
163 execl("./t68b", "t68b", fd_buf
, NULL
);
165 exit(1); /* Should not be reached */
167 /* We're the parent */
170 if (waitpid(pid
, &result
, 0) == -1) e(10);
171 if (WEXITSTATUS(result
) != 0) e(11);
174 /* Eventhough our child's pipe should've been closed upon exec, our
175 * pipe should still be functioning.
179 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != sizeof(buf_out
)) e(12);
180 if (read(pipes
[0], buf_in
, sizeof(buf_in
)) != sizeof(buf_in
)) e(13);
181 if (buf_out
[0] != buf_in
[0]) e(14);
183 if (close(pipes
[0]) != 0) e(15);
184 if (close(pipes
[1]) != 0) e(16);
190 /* Open a pipe with O_NONBLOCK */
191 char *buf_in
, *buf_out
;
197 if (pipe2(pipes
, O_NONBLOCK
) != 0) e(1);
198 if ((pipe_size
= fpathconf(pipes
[0], _PC_PIPE_BUF
)) == -1) e(2);
199 buf_in
= calloc(2, pipe_size
); /* Allocate twice the buffer size */
200 if (buf_in
== NULL
) e(3);
201 buf_out
= calloc(2, pipe_size
); /* Idem dito for output buffer */
202 if (buf_out
== NULL
) e(4);
204 /* According to POSIX, a pipe with O_NONBLOCK set shall never block.
205 * When we attempt to write PIPE_BUF or less bytes, and there is
206 * sufficient space available, write returns nbytes. Else write will
207 * return -1 and not transfer any data.
209 if (write(pipes
[1], buf_out
, 1) != 1) e(5); /* Write 1 byte */
210 if (write(pipes
[1], buf_out
, pipe_size
) != -1) e(6); /* Can't fit */
211 if (errno
!= EAGAIN
) e(7);
213 /* When writing more than PIPE_BUF bytes and when at least 1 byte can
214 * be tranferred, return the number of bytes written. We've written 1
215 * byte, so there are PIPE_BUF - 1 bytes left. */
216 if (write(pipes
[1], buf_out
, pipe_size
+ 1) != pipe_size
- 1) e(8);
218 /* Read out all data and try again. This time we should be able to
219 * write PIPE_BUF bytes. */
220 if (read(pipes
[0], buf_in
, pipe_size
) != pipe_size
) e(9);
221 if (read(pipes
[0], buf_in
, 1) != -1) e(10); /* Empty, can't read */
222 if (errno
!= EAGAIN
) e(11);
223 if (write(pipes
[1], buf_out
, pipe_size
+ 1) != pipe_size
) e(12);
224 if (close(pipes
[0]) != 0) e(13);
225 if (close(pipes
[1]) != 0) e(14);
231 test_pipe_nosigpipe(void)
233 /* Let's retry the writing to pipe without readers experiment. This time we set
234 * the O_NOSIGPIPE flag to prevent getting a signal. */
240 if (pipe2(pipes
, O_NOSIGPIPE
) != 0) e(7);
241 signal(SIGPIPE
, pipe_handler
);
242 signal(SIGALRM
, alarm_handler
);
243 seen_pipe_signal
= 0;
244 seen_alarm_signal
= 0;
246 if (close(pipes
[0]) != 0) e(8);
247 if (write(pipes
[1], buf_out
, sizeof(buf_out
)) != -1) e(9);
249 /* Collect alarm signal */
250 while (seen_alarm_signal
== 0)
252 if (errno
!= EPIPE
) e(10);
253 if (seen_pipe_signal
!= -1) e(11); /* Alarm sig handler set it to -1 */
254 if (close(pipes
[1]) != 0) e(12);
258 test_pipe_flag_setting()
264 /* Create standard pipe with no flags and verify they're off */
265 if (pipe2(pipes
, 0) != 0) e(1);
266 if (fcntl(pipes
[0], F_GETFD
) != 0) e(2);
267 if (fcntl(pipes
[1], F_GETFD
) != 0) e(3);
268 if (fcntl(pipes
[0], F_GETFL
) & O_NONBLOCK
) e(4);
269 if (fcntl(pipes
[1], F_GETFL
) & O_NONBLOCK
) e(5);
270 if (fcntl(pipes
[0], F_GETNOSIGPIPE
) != 0) e(6);
271 if (fcntl(pipes
[1], F_GETNOSIGPIPE
) != 0) e(7);
272 if (close(pipes
[0]) != 0) e(8);
273 if (close(pipes
[1]) != 0) e(9);
275 /* Create pipe with all flags and verify they're on */
276 if (pipe2(pipes
, O_CLOEXEC
|O_NONBLOCK
|O_NOSIGPIPE
) != 0) e(10);
277 if (fcntl(pipes
[0], F_GETFD
) != FD_CLOEXEC
) e(11);
278 if (fcntl(pipes
[1], F_GETFD
) != FD_CLOEXEC
) e(12);
279 if (!(fcntl(pipes
[0], F_GETFL
) & O_NONBLOCK
)) e(13);
280 if (!(fcntl(pipes
[1], F_GETFL
) & O_NONBLOCK
)) e(14);
281 if (fcntl(pipes
[0], F_GETNOSIGPIPE
) == 0) e(15);
282 if (fcntl(pipes
[1], F_GETNOSIGPIPE
) == 0) e(16);
283 if (fcntl(pipes
[0], F_SETNOSIGPIPE
, 0) != 0) e(17);
284 if (fcntl(pipes
[0], F_GETNOSIGPIPE
) != 0) e(18);
285 if (fcntl(pipes
[0], F_SETNOSIGPIPE
, 1) != 0) e(19);
286 if (fcntl(pipes
[0], F_GETNOSIGPIPE
) == 0) e(20);
287 if (close(pipes
[0]) != 0) e(21);
288 if (close(pipes
[1]) != 0) e(22);
292 * Test the behavior of a large pipe write that achieves partial progress
293 * before the reader end is closed. The write call is expected to return EPIPE
294 * and generate a SIGPIPE signal, and otherwise leave the system in good order.
297 test_pipe_partial_write(void)
299 char buf
[PIPE_BUF
+ 2];
302 signal(SIGPIPE
, pipe_handler
);
304 if (pipe(pfd
) < 0) e(1);
310 sleep(1); /* let the parent block on the write(2) */
313 * This one-byte read raises the question whether the write
314 * should return partial progress or not, since consumption of
315 * part of its data is now clearly visible. NetBSD chooses
316 * *not* to return partial progress, and MINIX3 follows suit.
318 if (read(pfd
[0], buf
, 1) != 1) e(2);
320 sleep(1); /* let VFS retry satisfying the write(2) */
322 exit(errct
); /* close the reader side of the pipe */
333 seen_pipe_signal
= 0;
336 * The following large write should block until the child exits, as
337 * that is when the read end closes, thus making eventual completion of
338 * the write impossible.
340 if (write(pfd
[1], buf
, sizeof(buf
)) != -1) e(4);
341 if (errno
!= EPIPE
) e(5);
342 if (seen_pipe_signal
!= 1) e(6);
344 seen_pipe_signal
= 0;
346 /* A subsequent write used to cause a system crash. */
347 if (write(pfd
[1], buf
, 1) != -1) e(7);
348 if (errno
!= EPIPE
) e(8);
349 if (seen_pipe_signal
!= 1) e(9);
354 if (wait(&status
) <= 0) e(10);
355 if (!WIFEXITED(status
)) e(11);
356 errct
+= WEXITSTATUS(status
);
360 main(int argc
, char *argv
[])
364 test_pipe_flag_setting();
367 test_pipe_nonblock();
368 test_pipe_nosigpipe();
369 test_pipe_partial_write();
371 return(-1); /* Unreachable */