1 #include <errno.h>
2 #include <stdio.h>
3 #include <poll.h>
4
main()5 int main() {
6 /* Test for #7859.
7 * Start a process with popen and watch the pipe using poll().
8 * We should get these events (preferrably in this exact order):
9 * - 3 reads of the values 1, 2 and 3 from the bash script
10 * - 1 end of file event (that should make the pipe readable)
11 * - 1 EINTR return from poll because of the SIGCHLD signal when the child process terminates
12 *
13 * Currently, the EINTR return happens before the end of file event notification.
14 */
15 FILE* f = popen("/bin/bash -c 'for i in 1 2 3; do { echo $i; sleep 1; }; done'", "r");
16 printf("f=%p\n", f);
17 int fd = fileno(f);
18 printf("fd=%d\n", fd);
19
20 struct pollfd pfd;
21 pfd.fd = fd;
22 pfd.events = POLLIN | POLLRDBAND;
23
24 char buffer[80];
25
26 while (1) {
27 int rv = poll(&pfd, 1, 500);
28 printf("rv=%d\n", rv);
29 if (rv == 0)
30 continue;
31 if (rv < 0) {
32 if (errno == EINTR) {
33 puts("warning: received SIGCHLD before stream close event");
34 continue;
35 } else {
36 printf("poll returns with error %s\n", strerror(errno));
37 break;
38 }
39 }
40 printf("events=%08x revents=%08x\n", pfd.events, pfd.revents);
41 if ((pfd.events & pfd.revents) == 0)
42 break;
43
44 fgets(buffer, 79, f);
45 printf("output: %s", buffer);
46 }
47
48 return 0;
49 }
50