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