From d07a80dc48a3e1e7564dbef9d8b0ea7189cf9978 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 4 Jun 2007 12:35:37 -0700 Subject: [PATCH] vmsplice-touser: example --- Makefile | 2 +- vmsplice-touser.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 vmsplice-touser.c diff --git a/Makefile b/Makefile index 20255ed..e6a6d53 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -Wall -O2 -g -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -PROGS = ktee ktee-net splice-cp splice-in splice-out splice-tonet splice-fromnet splice-test4c splice-test4s vmsplice splice-bench vmsplice2 +PROGS = ktee ktee-net splice-cp splice-in splice-out splice-tonet splice-fromnet splice-test4c splice-test4s vmsplice splice-bench vmsplice2 vmsplice-touser MANS = splice.2 tee.2 vmsplice.2 all: depend $(PROGS) diff --git a/vmsplice-touser.c b/vmsplice-touser.c new file mode 100644 index 0000000..1536904 --- /dev/null +++ b/vmsplice-touser.c @@ -0,0 +1,114 @@ +/* + * Use vmsplice to splice data from a pipe to user space memory. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "splice.h" + +static int do_dump; +static int splice_flags; + +int do_vmsplice(int fd, void *buf, int len) +{ + struct pollfd pfd = { .fd = fd, .events = POLLIN, }; + struct iovec iov; + int written; + int ret; + + iov.iov_base = buf; + iov.iov_len = len; + ret = 0; + + while (len) { + /* + * in a real app you'd be more clever with poll of course, + * here we are basically just blocking on output room and + * not using the free time for anything interesting. + */ + if (poll(&pfd, 1, -1) < 0) + return error("poll"); + + written = vmsplice(fd, &iov, 1, splice_flags); + + if (written < 0) + return error("vmsplice"); + else if (!written) + break; + + len -= written; + ret += written; + if (len) { + iov.iov_len -= written; + iov.iov_base += written; + } + } + + return ret; +} + +static int usage(char *name) +{ + fprintf(stderr, "| %s [-d(ump)]\n", name); + return 1; +} + +static int parse_options(int argc, char *argv[]) +{ + int c, index = 1; + + while ((c = getopt(argc, argv, "d")) != -1) { + switch (c) { + case 'd': + do_dump = 1; + index++; + break; + default: + return -1; + } + } + + return index; +} + +static void hexdump(unsigned char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) + printf("%02x", buf[i]); + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + unsigned char *buf; + int ret; + + if (parse_options(argc, argv) < 0) + return usage(argv[0]); + + if (check_input_pipe()) + return usage(argv[0]); + + buf = malloc(4096); + + memset(buf, 0, 4096); + + ret = do_vmsplice(STDIN_FILENO, buf, 4096); + if (ret < 0) + return 1; + + printf("splice %d\n", ret); + + if (do_dump) + hexdump(buf, ret); + + return 0; +} -- 2.25.1