Fix various compile warnings
[splice.git] / ktee.c
1 /*
2  * A tee implementation using sys_tee. Stores stdin input in the given file
3  * and duplicates that to stdout.
4  */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include <fcntl.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <errno.h>
13 #include <assert.h>
14 #include <limits.h>
15
16 #include "splice.h"
17
18 static int splice_flags;
19
20 static int do_splice(int infd, int outfd, unsigned int len, char *msg)
21 {
22         while (len) {
23                 int written = ssplice(infd, NULL, outfd, NULL, len, splice_flags);
24
25                 if (written <= 0)
26                         return error(msg);
27
28                 len -= written;
29         }
30
31         return 0;
32 }
33
34 static int usage(char *name)
35 {
36         fprintf(stderr, "... | %s: [-m(ove)] outfile\n", name);
37         return 1;
38 }
39
40 static int parse_options(int argc, char *argv[])
41 {
42         int c, index = 1;
43
44         while ((c = getopt(argc, argv, "m")) != -1) {
45                 switch (c) {
46                 case 'm':
47                         splice_flags = SPLICE_F_MOVE;
48                         index++;
49                         break;
50                 default:
51                         return -1;
52                 }
53         }
54
55         return index;
56 }
57
58 int main(int argc, char *argv[])
59 {
60         int fd, index;
61
62         if (argc < 2)
63                 return usage(argv[0]);
64
65         if (check_input_pipe())
66                 return usage(argv[0]);
67
68         index = parse_options(argc, argv);
69         if (index == -1 || index + 1 > argc)
70                 return usage(argv[0]);
71
72         fd = open(argv[index], O_WRONLY | O_CREAT | O_TRUNC, 0644);
73         if (fd < 0)
74                 return error("open output");
75
76         do {
77                 int tee_len = stee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, 0);
78
79                 if (tee_len < 0) {
80                         if (errno == EAGAIN) {
81                                 usleep(1000);
82                                 continue;
83                         }
84                         return error("tee");
85                 } else if (!tee_len)
86                         break;
87
88                 /*
89                  * Send output to file, also consumes input pipe.
90                  */
91                 if (do_splice(STDIN_FILENO, fd, tee_len, "splice-file"))
92                         break;
93         } while (1);
94
95         return 0;
96 }