#include #include #include #include #include #include #include #include #include #ifndef F_GETPIPE_SZ # define F_GETPIPE_SZ 1032 /* The Linux number for the option */ #endif const char *this_name = "client-fifo"; static void usage(void) { const char *p = this_name; printf("usage: %s fifo-file output-file\n" "\n",p); exit(-1); } static void __vdie(const char *fmt, va_list ap, int err) { int ret = errno; const char *p = this_name; if (err && errno) perror(p); else ret = -1; fprintf(stderr, " "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); exit(ret); } void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); __vdie(fmt, ap, 0); va_end(ap); } void pdie(const char *fmt, ...) { va_list ap; va_start(ap, fmt); __vdie(fmt, ap, 1); va_end(ap); } static unsigned long long time() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000000 + tv.tv_usec; } static void print_time(unsigned long long time) { unsigned long long seconds; unsigned long long usecs; seconds = time / 1000000; usecs = time - (seconds * 1000000); printf("time: %llu.%06llu\n", seconds, usecs); } int main(int argc, char *argv[]) { unsigned long long start; unsigned long long end; char *file; char *port; int page_size; int pipe_size; int brass[2]; int ret; int cfd; int fd; if (argc < 3) usage(); port = argv[1]; file = argv[2]; fd = open(file, O_WRONLY | O_CREAT); if (fd < 0) pdie("Opening %s", file); if (pipe(brass) < 0) pdie("pipe"); page_size = getpagesize(); if (page_size <= 0) pdie("getting page size"); ret = fcntl(brass[0], F_GETPIPE_SZ, &pipe_size); if (ret < 0 || !pipe_size) pipe_size = page_size; start = time(); cfd = open(port, O_RDONLY); if (cfd < 0) pdie("Reading to %s", argv[2]); start = time(); do { ret = splice(cfd, NULL, brass[1], NULL, pipe_size, 1 /* SPLICE_F_MOVE */); if (ret < 0 && errno != EAGAIN) pdie("splice read of %s", file); ret = splice(brass[0], NULL, fd, NULL, pipe_size, 3 /* and NON_BLOCK */); if (ret < 0 && errno != EAGAIN) pdie("splice write"); if (ret < 0) { char buf[pipe_size]; ret = read(cfd, buf, pipe_size); ret = write(fd, buf, ret); } } while (ret > 0); end = time(); print_time(end - start); exit(0); }