vmsplice-touser: example
[splice.git] / vmsplice-touser.c
CommitLineData
d07a80dc
JA
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
15static int do_dump;
16static int splice_flags;
17
18int 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
56static int usage(char *name)
57{
58 fprintf(stderr, "| %s [-d(ump)]\n", name);
59 return 1;
60}
61
62static 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
80static 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
89int 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}