#include #include #include #include #include #include int main(int argc, char **argv) { int fd[2]; int i; char buf[2]; fd_set write_fds; struct timeval tv; ssize_t n; int status; /* initialize */ buf[0] = 'h'; buf[1] = 'i'; do { /* create pipe */ if (0 > pipe(fd)) { printf("pipe error - %s\n", strerror(errno)); break; } /* * loop four times * select for write, then write one byte * after the second write, do a read * odd selects succeed, even fail */ for (i = 0; i < 4; i++) { printf("iteration %d\n", i + 1); status = 0; /* do select */ FD_ZERO(&write_fds); FD_SET(fd[1], &write_fds); tv.tv_sec = 0; tv.tv_usec = 0; switch (select(fd[1] + 1, NULL, &write_fds, NULL, &tv)) { case -1: /* should probably check for EINTR and/or EWOULDBLOCK */ printf("select error - %s\n", strerror(errno)); break; case 0: /* no I/O */ puts("select returned 0 -- pipe not writable"); break; default: /* make sure our fd is writable */ if (FD_ISSET(fd[1], &write_fds)) { puts("select says pipe is writable"); status = 1; } else puts("select says pipe is not writable"); break; } /* do write */ n = write(fd[1], buf + (i % 2), 1); switch (n) { case -1: /* should probably check for EINTR and/or EWOULDBLOCK */ printf("write error - %s\n", strerror(errno)); break; case 0: /* no I/O */ puts("write returned 0 -- pipe closed"); break; default: printf("write succeeded - %d bytes written\n", n); if (0 == status) puts("select bug"); break; } /* do read */ if (0 == ((i + 1) % 2)) { n = read(fd[0], buf, sizeof(buf)); switch (n) { case -1: /* should probably check for EINTR and/or EWOULDBLOCK */ printf("write error - %s\n", strerror(errno)); break; case 0: /* no I/O */ puts("read returned 0 -- pipe closed"); break; default: printf("read succeeded - %d bytes read\n", n); break; } } } } while (0); exit(0); }