vmsplice-touser: example
[splice.git] / vmsplice-touser.c
1 /*
2  * Use vmsplice to splice data from a pipe to user space memory.
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <limits.h>
8 #include <string.h>
9 #include <getopt.h>
10 #include <sys/poll.h>
11 #include <sys/types.h>
12
13 #include "splice.h"
14
15 static int do_dump;
16 static int splice_flags;
17
18 int do_vmsplice(int fd, void *buf, int len)
19 {
20         struct pollfd pfd = { .fd = fd, .events = POLLIN, };
21         struct iovec iov;
22         int written;
23         int ret;
24
25         iov.iov_base = buf;
26         iov.iov_len = len;
27         ret = 0;
28
29         while (len) {
30                 /*
31                  * in a real app you'd be more clever with poll of course,
32                  * here we are basically just blocking on output room and
33                  * not using the free time for anything interesting.
34                  */
35                 if (poll(&pfd, 1, -1) < 0)
36                         return error("poll");
37
38                 written = vmsplice(fd, &iov, 1, splice_flags);
39
40                 if (written < 0)
41                         return error("vmsplice");
42                 else if (!written)
43                         break;
44
45                 len -= written;
46                 ret += written;
47                 if (len) {
48                         iov.iov_len -= written;
49                         iov.iov_base += written;
50                 }
51         }
52
53         return ret;
54 }
55
56 static int usage(char *name)
57 {
58         fprintf(stderr, "| %s [-d(ump)]\n", name);
59         return 1;
60 }
61
62 static int parse_options(int argc, char *argv[])
63 {
64         int c, index = 1;
65
66         while ((c = getopt(argc, argv, "d")) != -1) {
67                 switch (c) {
68                 case 'd':
69                         do_dump = 1;
70                         index++;
71                         break;
72                 default:
73                         return -1;
74                 }
75         }
76
77         return index;
78 }
79
80 static void hexdump(unsigned char *buf, int len)
81 {
82         int i;
83
84         for (i = 0; i < len; i++)
85                 printf("%02x", buf[i]);
86         printf("\n");
87 }
88
89 int main(int argc, char *argv[])
90 {
91         unsigned char *buf;
92         int ret;
93
94         if (parse_options(argc, argv) < 0)
95                 return usage(argv[0]);
96
97         if (check_input_pipe())
98                 return usage(argv[0]);
99
100         buf = malloc(4096);
101
102         memset(buf, 0, 4096);
103
104         ret = do_vmsplice(STDIN_FILENO, buf, 4096);
105         if (ret < 0)
106                 return 1;
107
108         printf("splice %d\n", ret);
109
110         if (do_dump)
111                 hexdump(buf, ret);
112
113         return 0;
114 }