tee(2) System Calls Manual tee(2) tee - (libc -lc) #define _GNU_SOURCE /* feature_test_macros(7) */ #include ssize_t tee(int fd_in, int fd_out, size_t size, unsigned int flags); tee() size fd_in fd_out. fd_in splice(2) . flags (OR) : SPLICE_F_MOVE tee() splice(2). SPLICE_F_NONBLOCK / splice(2) . SPLICE_F_MORE tee() splice(2). SPLICE_F_GIFT tee() vmsplice(2). tee() . 0 fd_in. tee() -1 errno . EAGAIN SPLICE_F_NONBLOCK flags (O_NONBLOCK) . EINVAL fd_in fd_out fd_in fd_out . ENOMEM . . 2.6.17 glibc 2.5. tee() . : tee() . tee(1) tee(). : $ date | ./a.out out.log | cat; Tue Oct 28 10:06:00 CET 2014 $ cat out.log; Tue Oct 28 10:06:00 CET 2014 #define _GNU_SOURCE #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd; ssize_t size, ssize; if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } for (;;) { /* * tee stdin to stdout. */ size = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); if (size < 0) { if (errno == EAGAIN) continue; perror("tee"); exit(EXIT_FAILURE); } if (size == 0) break; /* * Consume stdin by splicing it to a file. */ while (size > 0) { ssize = splice(STDIN_FILENO, NULL, fd, NULL, size, SPLICE_F_MOVE); if (ssize < 0) { perror("splice"); exit(EXIT_FAILURE); } size -= ssize; } } close(fd); exit(EXIT_SUCCESS); } splice(2), vmsplice(2), pipe(7) 3 . . : . 6.18 8 2026 tee(2)