189846eb7737899f3822f78c55206425c1685ea6
[splice.git] / vmsplice2.c
1 /*
2  * Use vmsplice to fill some user memory into a pipe. vmsplice writes
3  * to stdout, so that must be a pipe.
4  */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <limits.h>
9 #include <string.h>
10 #include <getopt.h>
11 #include <sys/poll.h>
12 #include <sys/types.h>
13
14 #include "splice.h"
15
16 int do_vmsplice(int fd, struct iovec *iov, unsigned long nr_vecs)
17 {
18         struct pollfd pfd = { .fd = fd, .events = POLLOUT, };
19         long written;
20
21         while (nr_vecs) {
22                 /*
23                  * in a real app you'd be more clever with poll of course,
24                  * here we are basically just blocking on output room and
25                  * not using the free time for anything interesting.
26                  */
27                 if (poll(&pfd, 1, -1) < 0)
28                         return error("poll");
29
30                 written = vmsplice(fd, iov, nr_vecs, 0);
31
32                 if (written <= 0)
33                         return error("vmsplice");
34
35                 while (written) {
36                         int this_len = iov->iov_len;
37
38                         if (this_len > written)
39                                 this_len = written;
40
41                         iov->iov_len -= this_len;
42                         if (!iov->iov_len) {
43                                 nr_vecs--;
44                                 iov++;
45                         }
46
47                         written -= this_len;
48                 }
49         }
50
51         return 0;
52 }
53
54 static int usage(char *name)
55 {
56         fprintf(stderr, "%s | ...\n", name);
57         return 1;
58 }
59
60 int main(int argc, char *argv[])
61 {
62         char h[] = "header header header header header header header header";
63         char b[] = "body body body body body body body body body body body";
64         char f[] = "footer footer footer footer footer footer footer footer";
65         struct iovec vecs[3];
66
67         vecs[0].iov_base = h;
68         vecs[0].iov_len = strlen(h);
69         vecs[1].iov_base = b;
70         vecs[1].iov_len = strlen(b);
71         vecs[2].iov_base = f;
72         vecs[2].iov_len = strlen(f);
73                 
74         if (check_output_pipe())
75                 return usage(argv[0]);
76
77         return do_vmsplice(STDOUT_FILENO, vecs, 3);
78 }