#include #include #include #include #include #include #include #include #include static void showpoll(const char *title, int events) { int n = 0; printf("%s=0x%x<", title, events); if (events & POLLIN) printf("%sPOLLIN", n++ ? "," : ""); if (events & POLLRDNORM) printf("%sPOLLRDNORM", n++ ? "," : ""); if (events & POLLRDBAND) printf("%sPOLLRDBAND", n++ ? "," : ""); if (events & POLLOUT) printf("%sPOLLOUT", n++ ? "," : ""); if (events & POLLWRNORM) printf("%sPOLLWRNORM", n++ ? "," : ""); if (events & POLLWRBAND) printf("%sPOLLWRBAND", n++ ? "," : ""); if (events & POLLHUP) printf("%sPOLLHUP", n++ ? "," : ""); if (events & POLLERR) printf("%sPOLLERR", n++ ? "," : ""); if (events & POLLNVAL) printf("%sPOLLNVAL", n++ ? "," : ""); printf(">\n"); } int main(void) { int rd0, wr, rd1; struct pollfd pfd[2]; int nfds; char ch; ssize_t nread; int bzzt = 0; (void)unlink("fifo"); if (mkfifo("fifo", 0600) == -1) err(EXIT_FAILURE, "mkfifo"); printf("1. open rd0\n"); fflush(stdout); if ((rd0 = open("fifo", O_RDONLY|O_NONBLOCK)) == -1) err(EXIT_FAILURE, "open rd0"); memset(&pfd, 0, sizeof(pfd)); pfd[0].fd = rd0; pfd[0].events = POLLIN; if ((nfds = poll(pfd, 1, 0)) == -1) err(EXIT_FAILURE, "poll"); printf("nfds=%d\n", nfds); showpoll("pfd[0].revents", pfd[0].revents); fflush(stdout); if ((nread = read(rd0, &ch, 1)) == -1) { int error = errno; warn("read rd0"); if (error == EAGAIN && (pfd[0].revents & POLLIN) != 0) { printf("*bzzt* poll said rd0 readable, why block?\n"); bzzt = 1; } } else { printf("read rd0 returned %zd bytes\n", nread); if ((pfd[0].revents & POLLIN) == 0) { printf("*bzzt* poll said rd0 nonreadable, why read?\n"); bzzt = 1; } } printf("2. open and close wr\n"); fflush(stdout); if ((wr = open("fifo", O_WRONLY)) == -1) err(EXIT_FAILURE, "open wr"); if (close(wr) == -1) err(EXIT_FAILURE, "close wr"); memset(&pfd, 0, sizeof(pfd)); pfd[0].fd = rd0; pfd[0].events = POLLIN; if ((nfds = poll(pfd, 1, 0)) == -1) err(EXIT_FAILURE, "poll"); printf("nfds=%d\n", nfds); showpoll("pfd[0].revents", pfd[0].revents); fflush(stdout); if ((nread = read(rd0, &ch, 1)) == -1) { int error = errno; warn("read rd0"); if (error == EAGAIN && (pfd[0].revents & POLLIN) != 0) { printf("*bzzt* poll said rd0 readable, why block?\n"); bzzt = 1; } } else { printf("read rd0 returned %zd bytes\n", nread); if ((pfd[0].revents & POLLIN) == 0) { printf("*bzzt* poll said rd0 nonreadable, why read?\n"); bzzt = 1; } } printf("3. open rd1\n"); fflush(stdout); if ((rd1 = open("fifo", O_RDONLY|O_NONBLOCK)) == -1) err(EXIT_FAILURE, "open rd1"); memset(&pfd, 0, sizeof(pfd)); pfd[0].fd = rd0; pfd[0].events = POLLIN; pfd[1].fd = rd1; pfd[1].events = POLLIN; if ((nfds = poll(pfd, 2, 0)) == -1) err(EXIT_FAILURE, "poll"); printf("nfds=%d\n", nfds); showpoll("pfd[0].revents", pfd[0].revents); showpoll("pfd[1].revents", pfd[1].revents); fflush(stdout); if ((nread = read(rd0, &ch, 1)) == -1) { int error = errno; warn("read rd0"); if (error == EAGAIN && (pfd[0].revents & POLLIN) != 0) { printf("*bzzt* poll said rd0 readable, why block?\n"); bzzt = 1; } } else { printf("read rd0 returned %zd bytes\n", nread); if ((pfd[0].revents & POLLIN) == 0) { printf("*bzzt* poll said rd0 nonreadable, why read?\n"); bzzt = 1; } } fflush(stdout); if ((nread = read(rd1, &ch, 1)) == -1) { int error = errno; warn("read rd1"); if (error == EAGAIN && (pfd[1].revents & POLLIN) != 0) { printf("*bzzt* poll said rd1 readable, why block?\n"); bzzt = 1; } } else { printf("read rd1 returned %zd bytes\n", nread); if ((pfd[1].revents & POLLIN) == 0) { printf("*bzzt* poll said rd1 nonreadable, why read?\n"); bzzt = 1; } } fflush(stdout); return bzzt | ferror(stdout); }