vmsplice-touser: example
authorJens Axboe <jens.axboe@oracle.com>
Mon, 4 Jun 2007 19:35:37 +0000 (12:35 -0700)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 4 Jun 2007 19:35:37 +0000 (12:35 -0700)
Makefile
vmsplice-touser.c [new file with mode: 0644]

index 20255ed110a9595104e2f7459a26abf75e89f7f2..e6a6d53bc26737f25f03bfc97eb422ef8ae3ab4f 100644 (file)
--- 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 (file)
index 0000000..1536904
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Use vmsplice to splice data from a pipe to user space memory.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+
+#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;
+}