tee(2) System Calls Manual tee(2) tee - Standard C library (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() duplicates up to size bytes of data from the pipe referred to by the file descriptor fd_in to the pipe referred to by the file descriptor fd_out. It does not consume the data that is duplicated from fd_in; therefore, that data can be copied by a subsequent 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 flags SPLICE_F_NONBLOCK (O_NONBLOCK), . EINVAL fd_in fd_out ; fd_in fd_out . ENOMEM . Linux. Linux 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) () Azamat Hackimov , Dmitry Bolkhovskikh , Yuri Kozlov , Kirill Rekhov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux man-pages 6.12 17 2024 . tee(2)