1 #include <errno.h> 2 #include <stdio.h> 3 #include <poll.h> 4 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