#define _GNU_SOURCE #include #include #include #include #include #include /* pipe file descriptors */ static int fd[2]; /* send/write size */ static size_t size; /* options */ static struct option long_opts[] = { { "size", required_argument, NULL, 's' }, { NULL, 0, NULL, 0 }, }; static void *reader(void *arg) { unsigned char buf[size]; ssize_t read_ = 0; while (read_ < size) { ssize_t ret; ret = read(fd[0], buf + read_, size - read_); if (ret < 0) { perror("read() failed"); exit(EXIT_FAILURE); } read_ += ret; } printf("Reader: got data\n"); return NULL; } static void *writer(void *arg) { unsigned char buf[size]; ssize_t written = 0; sleep(1); while (written < size) { ssize_t ret; ret = write(fd[1], buf + written, size - written); if (ret < 0) { perror("write() failed"); exit(EXIT_FAILURE); } written += ret; } printf("Writer: sent data\n"); sleep(1); return NULL; } static inline void print_usage_and_die(void) { fprintf(stderr, "usage: pipedemo [-s ]\n"); exit(EXIT_FAILURE); } int main(int argc, char **argv) { pthread_t tid1, tid2; char *end; int c; size = 4 << 10; while ((c = getopt_long(argc, argv, "s:", long_opts, NULL)) != -1) { switch (c) { case 's': size = strtoull(optarg, &end, 10); if (end == optarg || *end != '\0' || errno == ERANGE) { fprintf(stderr, "given size is not valid\n"); return EXIT_FAILURE; } break; default: print_usage_and_die(); } } if (pipe(fd) < 0) { perror("pipe() failed"); return EXIT_FAILURE; } if (pthread_create(&tid1, NULL, reader, NULL) || pthread_create(&tid2, NULL, writer, NULL)) { fprintf(stderr, "pthread_create() failed\n"); return EXIT_FAILURE; } if (pthread_setname_np(tid1, "pipedemo-reader") || pthread_setname_np(tid2, "pipedemo-writer")) { fprintf(stderr, "pthread_create() failed\n"); return EXIT_FAILURE; } pthread_join(tid1, NULL); pthread_join(tid2, NULL); return EXIT_SUCCESS; }