Commit | Line | Data |
---|---|---|
d8525fbd | 1 | /* |
d633e577 JA |
2 | * A tee implementation using sys_tee. Stores stdin input in the given file |
3 | * and duplicates that to stdout. | |
d8525fbd JA |
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> | |
d8525fbd JA |
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 do_splice(int infd, int outfd, unsigned int len, char *msg) | |
19 | { | |
20 | while (len) { | |
21 | int written = splice(infd, NULL, outfd, NULL, len, 0); | |
22 | ||
23 | if (written <= 0) | |
24 | return error(msg); | |
25 | ||
26 | len -= written; | |
27 | } | |
28 | ||
29 | return 0; | |
30 | } | |
31 | ||
f91353a3 JA |
32 | static int usage(char *name) |
33 | { | |
34 | fprintf(stderr, "... | %s: outfile\n", name); | |
35 | return 1; | |
36 | } | |
37 | ||
d8525fbd JA |
38 | int main(int argc, char *argv[]) |
39 | { | |
d8525fbd JA |
40 | int fd; |
41 | ||
f91353a3 JA |
42 | if (argc < 2) |
43 | return usage(argv[0]); | |
d8525fbd | 44 | |
76797253 | 45 | if (check_input_pipe()) |
f91353a3 | 46 | return usage(argv[0]); |
d8525fbd JA |
47 | |
48 | fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); | |
49 | if (fd < 0) | |
50 | return error("open output"); | |
51 | ||
52 | do { | |
53 | int tee_len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); | |
54 | ||
55 | if (tee_len < 0) { | |
56 | if (errno == EAGAIN) { | |
57 | usleep(1000); | |
58 | continue; | |
59 | } | |
60 | return error("tee"); | |
61 | } else if (!tee_len) | |
62 | break; | |
63 | ||
64 | /* | |
65 | * Send output to file, also consumes input pipe. | |
66 | */ | |
67 | if (do_splice(STDIN_FILENO, fd, tee_len, "splice-file")) | |
68 | break; | |
69 | } while (1); | |
70 | ||
71 | return 0; | |
72 | } |