]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/tee.2
3c35a05aad093810df7bd0b0b86c488331efe395
[thirdparty/man-pages.git] / man2 / tee.2
1 .\" This manpage is Copyright (C) 2006 Jens Axboe
2 .\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH TEE 2 2020-06-09 "Linux" "Linux Programmer's Manual"
7 .SH NAME
8 tee \- duplicating pipe content
9 .SH LIBRARY
10 Standard C library
11 .RI ( libc ", " \-lc )
12 .SH SYNOPSIS
13 .nf
14 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
15 .B #include <fcntl.h>
16 .PP
17 .BI "ssize_t tee(int " fd_in ", int " fd_out ", size_t " len \
18 ", unsigned int " flags );
19 .fi
20 .\" Return type was long before glibc 2.7
21 .SH DESCRIPTION
22 .\" Example programs http://brick.kernel.dk/snaps
23 .\"
24 .\"
25 .\" add a "tee(in, out1, out2)" system call that duplicates the pages
26 .\" (again, incrementing their reference count, not copying the data) from
27 .\" one pipe to two other pipes.
28 .BR tee ()
29 duplicates up to
30 .I len
31 bytes of data from the pipe referred to by the file descriptor
32 .I fd_in
33 to the pipe referred to by the file descriptor
34 .IR fd_out .
35 It does not consume the data that is duplicated from
36 .IR fd_in ;
37 therefore, that data can be copied by a subsequent
38 .BR splice (2).
39 .PP
40 .I flags
41 is a bit mask that is composed by ORing together
42 zero or more of the following values:
43 .TP 1.9i
44 .B SPLICE_F_MOVE
45 Currently has no effect for
46 .BR tee ();
47 see
48 .BR splice (2).
49 .TP
50 .B SPLICE_F_NONBLOCK
51 Do not block on I/O; see
52 .BR splice (2)
53 for further details.
54 .TP
55 .B SPLICE_F_MORE
56 Currently has no effect for
57 .BR tee (),
58 but may be implemented in the future; see
59 .BR splice (2).
60 .TP
61 .B SPLICE_F_GIFT
62 Unused for
63 .BR tee ();
64 see
65 .BR vmsplice (2).
66 .SH RETURN VALUE
67 Upon successful completion,
68 .BR tee ()
69 returns the number of bytes that were duplicated between the input
70 and output.
71 A return value of 0 means that there was no data to transfer,
72 and it would not make sense to block, because there are no
73 writers connected to the write end of the pipe referred to by
74 .IR fd_in .
75 .PP
76 On error,
77 .BR tee ()
78 returns \-1 and
79 .I errno
80 is set to indicate the error.
81 .SH ERRORS
82 .TP
83 .B EAGAIN
84 .B SPLICE_F_NONBLOCK
85 was specified in
86 .IR flags
87 or one of the file descriptors had been marked as nonblocking
88 .RB ( O_NONBLOCK ) ,
89 and the operation would block.
90 .TP
91 .B EINVAL
92 .I fd_in
93 or
94 .I fd_out
95 does not refer to a pipe; or
96 .I fd_in
97 and
98 .I fd_out
99 refer to the same pipe.
100 .TP
101 .B ENOMEM
102 Out of memory.
103 .SH VERSIONS
104 The
105 .BR tee ()
106 system call first appeared in Linux 2.6.17;
107 library support was added to glibc in version 2.5.
108 .SH CONFORMING TO
109 This system call is Linux-specific.
110 .SH NOTES
111 Conceptually,
112 .BR tee ()
113 copies the data between the two pipes.
114 In reality no real data copying takes place though:
115 under the covers,
116 .BR tee ()
117 assigns data to the output by merely grabbing
118 a reference to the input.
119 .SH EXAMPLES
120 The example below implements a basic
121 .BR tee (1)
122 program using the
123 .BR tee ()
124 system call.
125 Here is an example of its use:
126 .PP
127 .in +4n
128 .EX
129 $ \fBdate | ./a.out out.log | cat\fP
130 Tue Oct 28 10:06:00 CET 2014
131 $ \fBcat out.log\fP
132 Tue Oct 28 10:06:00 CET 2014
133 .EE
134 .in
135 .SS Program source
136 \&
137 .EX
138 #define _GNU_SOURCE
139 #include <fcntl.h>
140 #include <stdio.h>
141 #include <stdlib.h>
142 #include <unistd.h>
143 #include <errno.h>
144 #include <limits.h>
145
146 int
147 main(int argc, char *argv[])
148 {
149 int fd;
150 ssize_t len, slen;
151
152 if (argc != 2) {
153 fprintf(stderr, "Usage: %s <file>\en", argv[0]);
154 exit(EXIT_FAILURE);
155 }
156
157 fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
158 if (fd == \-1) {
159 perror("open");
160 exit(EXIT_FAILURE);
161 }
162
163 for (;;) {
164 /*
165 * tee stdin to stdout.
166 */
167 len = tee(STDIN_FILENO, STDOUT_FILENO,
168 INT_MAX, SPLICE_F_NONBLOCK);
169 if (len < 0) {
170 if (errno == EAGAIN)
171 continue;
172 perror("tee");
173 exit(EXIT_FAILURE);
174 }
175 if (len == 0)
176 break;
177
178 /*
179 * Consume stdin by splicing it to a file.
180 */
181 while (len > 0) {
182 slen = splice(STDIN_FILENO, NULL, fd, NULL,
183 len, SPLICE_F_MOVE);
184 if (slen < 0) {
185 perror("splice");
186 exit(EXIT_FAILURE);
187 }
188 len \-= slen;
189 }
190 }
191
192 close(fd);
193 exit(EXIT_SUCCESS);
194 }
195 .EE
196 .SH SEE ALSO
197 .BR splice (2),
198 .BR vmsplice (2),
199 .BR pipe (7)