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