[PATCH] splice-bench: really fix warning
[splice.git] / ktee.c
CommitLineData
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>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <errno.h>
14#include <assert.h>
15#include <limits.h>
16
17#include "splice.h"
18
19static int do_splice(int infd, int outfd, unsigned int len, char *msg)
20{
21 while (len) {
22 int written = splice(infd, NULL, outfd, NULL, len, 0);
23
24 if (written <= 0)
25 return error(msg);
26
27 len -= written;
28 }
29
30 return 0;
31}
32
33int main(int argc, char *argv[])
34{
35 struct stat sb;
36 int fd;
37
38 if (argc < 2) {
39 fprintf(stderr, "%s: outfile\n", argv[0]);
40 return 1;
41 }
42
43 if (fstat(STDIN_FILENO, &sb) < 0)
44 return error("stat");
45 if (!S_ISFIFO(sb.st_mode)) {
46 fprintf(stderr, "stdout must be a pipe\n");
47 return 1;
48 }
49
50 fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
51 if (fd < 0)
52 return error("open output");
53
54 do {
55 int tee_len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
56
57 if (tee_len < 0) {
58 if (errno == EAGAIN) {
59 usleep(1000);
60 continue;
61 }
62 return error("tee");
63 } else if (!tee_len)
64 break;
65
66 /*
67 * Send output to file, also consumes input pipe.
68 */
69 if (do_splice(STDIN_FILENO, fd, tee_len, "splice-file"))
70 break;
71 } while (1);
72
73 return 0;
74}