/* $Id: poll_eof.c,v 1.2 2009/07/03 11:54:30 kostik Exp kostik $ */ #include #include #include #include #include #include #include #include #include #include #include #include static int sv[2]; static pthread_barrier_t barrier; static void dopoll(int ign, const char *thr_name) { struct pollfd p[1]; int error, stop; for (;;) { pthread_barrier_wait(&barrier); bzero(p, sizeof(p)); p[0].fd = sv[0]; p[0].events = POLLIN | ign; error = poll(p, 1, INFTIM); if (error == -1) { if (errno == EINTR) continue; err(1, "poll"); } printf("%s got", thr_name); if (p[0].revents & POLLHUP) printf(" POLLHUP"); if (p[0].revents & POLLIN) { printf(" POLLIN"); } printf("\n"); } } static void * poll_thr(void *arg) { dopoll(0, "pool thread"); return (NULL); } static void * poll_igneof_thr(void *arg) { dopoll(POLLINIGNEOF, "igneof thread"); return (NULL); } #define DO_SOCKETS 1 #define DO_PIPES 2 #define DO_FIFOS 3 int main(int argc, char *argv[]) { pthread_t poll_thr_id, poll_igneof_thr_id; char a[1]; char fifo_path[] = "/tmp/poll_eof.XXXXXXX"; int error, kind; kind = DO_SOCKETS; if (argc > 1) { if (!strcmp(argv[1], "sockets")) kind = DO_SOCKETS; else if (!strcmp(argv[1], "pipes")) kind = DO_PIPES; else if (!strcmp(argv[1], "fifos")) kind = DO_FIFOS; else errx(1, "sockets, pipes or fifos"); } switch (kind) { case DO_SOCKETS: printf("Using sockets\n"); error = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); if (error == -1) err(1, "socketpair"); break; case DO_PIPES: printf("Using pipes\n"); error = pipe(sv); if (error == -1) err(1, "pipe"); break; case DO_FIFOS: printf("Using fifos\n"); if (mktemp(fifo_path) == NULL) err(1, "mktemp fifo_path"); error = mkfifo(fifo_path, S_IRUSR | S_IWUSR); if (error == -1) err(1, "mkfifo"); sv[0] = open(fifo_path, O_RDONLY | O_NONBLOCK); if (sv[0] == -1) err(1, "fifo open for read"); sv[1] = open(fifo_path, O_WRONLY); if (sv[1] == -1) err(1, "fifo open for write"); unlink(fifo_path); break; } error = pthread_barrier_init(&barrier, NULL, 3); error = pthread_create(&poll_thr_id, NULL, poll_thr, NULL); if (error != 0) errc(1, error, "pthread_create poll_thr"); error = pthread_create(&poll_igneof_thr_id, NULL, poll_igneof_thr, NULL); if (error != 0) errc(1, error, "pthread_create poll_igneof_thr"); pthread_barrier_wait(&barrier); a[0] = 'a'; write(sv[1], a, sizeof(a)); sleep(1); read(sv[0], a, sizeof(a)); pthread_barrier_wait(&barrier); a[0] = 'b'; write(sv[1], a, sizeof(a)); sleep(1); read(sv[0], a, sizeof(a)); pthread_barrier_wait(&barrier); close(sv[1]); pthread_barrier_wait(&barrier); return (0); }