[PATCH] vmsplice2: add switch for stack allocation
[splice.git] / vmsplice2.c
CommitLineData
648a7fef
JA
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
9649cd9b
JA
16static int alloc_stack;
17
648a7fef
JA
18int do_vmsplice(int fd, struct iovec *iov, unsigned long nr_vecs)
19{
20 struct pollfd pfd = { .fd = fd, .events = POLLOUT, };
21 long written;
22
23 while (nr_vecs) {
24 /*
25 * in a real app you'd be more clever with poll of course,
26 * here we are basically just blocking on output room and
27 * not using the free time for anything interesting.
28 */
29 if (poll(&pfd, 1, -1) < 0)
30 return error("poll");
31
32 written = vmsplice(fd, iov, nr_vecs, 0);
33
34 if (written <= 0)
35 return error("vmsplice");
36
37 while (written) {
38 int this_len = iov->iov_len;
39
40 if (this_len > written)
41 this_len = written;
42
43 iov->iov_len -= this_len;
44 if (!iov->iov_len) {
45 nr_vecs--;
46 iov++;
47 }
48
49 written -= this_len;
50 }
51 }
52
53 return 0;
54}
55
56static int usage(char *name)
57{
9649cd9b 58 fprintf(stderr, "%s [-s(tack)] | ...\n", name);
648a7fef
JA
59 return 1;
60}
61
9649cd9b
JA
62static int parse_options(int argc, char *argv[])
63{
64 int c, index = 1;
65
66 while ((c = getopt(argc, argv, "s")) != -1) {
67 switch (c) {
68 case 's':
69 alloc_stack = 1;
70 index++;
71 break;
72 default:
73 return -1;
74 }
75 }
76
77 return index;
78}
79
e346936e
JA
80#define S1 "header header header header header header header header"
81#define S2 "body body body body body body body body body body body"
82#define S3 "footer footer footer footer footer footer footer footer"
83
648a7fef
JA
84int main(int argc, char *argv[])
85{
648a7fef 86 struct iovec vecs[3];
9649cd9b
JA
87 char *h, *b, *f;
88
89 if (parse_options(argc, argv) < 0)
90 return usage(argv[0]);
91
92 if (alloc_stack) {
93 /* Dangerous on-stack usage! */
94 h = S1;
95 b = S2;
96 f = S3;
97 } else {
98 h = strdup(S1);
99 b = strdup(S2);
100 f = strdup(S3);
101 }
648a7fef
JA
102
103 vecs[0].iov_base = h;
648a7fef 104 vecs[1].iov_base = b;
648a7fef 105 vecs[2].iov_base = f;
e346936e
JA
106 vecs[0].iov_len = strlen(vecs[0].iov_base);
107 vecs[1].iov_len = strlen(vecs[1].iov_base);
108 vecs[2].iov_len = strlen(vecs[2].iov_base);
648a7fef
JA
109
110 if (check_output_pipe())
111 return usage(argv[0]);
112
113 return do_vmsplice(STDOUT_FILENO, vecs, 3);
114}