mirror of https://github.com/mkerrisk/man-pages
196 lines
4.6 KiB
Groff
196 lines
4.6 KiB
Groff
.\" Hey Emacs! This file is -*- nroff -*- source.
|
|
.\"
|
|
.\" This manpage is Copyright (C) 2006 Jens Axboe
|
|
.\" and Copyright (C) 2006 Michael Kerrisk <mtk-manpages@gmx.net>
|
|
.\"
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
.\" preserved on all copies.
|
|
.\"
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
.\" permission notice identical to this one.
|
|
.\"
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
.\" have taken the same level of care in the production of this manual,
|
|
.\" which is licensed free of charge, as they might when working
|
|
.\" professionally.
|
|
.\"
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
.\"
|
|
.TH tee 2 2006-04-28 "Linux 2.6.17" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
tee \- duplicating pipe content
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.B #define _GNU_SOURCE
|
|
.B #include <fcntl.h>
|
|
|
|
.BI "long tee(int " fd_in ", int " fd_out ", size_t " len \
|
|
", unsigned int " flags );
|
|
.fi
|
|
.SH DESCRIPTION
|
|
.\" Example programs http://brick.kernel.dk/snaps
|
|
.\"
|
|
.\"
|
|
.\" add a "tee(in, out1, out2)" system call that duplicates the pages
|
|
.\" (again, incrementing their reference count, not copying the data) from
|
|
.\" one pipe to two other pipes.
|
|
.BR tee ()
|
|
duplicates up to
|
|
.I len
|
|
bytes of data from the pipe referred to by the file descriptor
|
|
.I fd_in
|
|
to the pipe referred to by the file descriptor
|
|
.IR fd_out .
|
|
It does not consume the data that is duplicated from
|
|
.IR fd_in ;
|
|
therefore, that data can be copied by a subsequent
|
|
.BR splice (2).
|
|
|
|
.I flags
|
|
is a series of modifier flags, which share the name space with
|
|
.BR splice (2)
|
|
and
|
|
.BR vmsplice (2):
|
|
.TP 1.9i
|
|
.B SPLICE_F_MOVE
|
|
Currently has no effect for
|
|
.BR tee ();
|
|
see
|
|
.BR splice (2).
|
|
.TP
|
|
.B SPLICE_F_NONBLOCK
|
|
Do not block on I/O; see
|
|
.BR splice (2)
|
|
for further details.
|
|
.TP
|
|
.B SPLICE_F_MORE
|
|
Currently has no effect for
|
|
.BR tee (),
|
|
but may be implemented in the future; see
|
|
.BR splice (2).
|
|
.TP
|
|
.B SPLICE_F_GIFT
|
|
Unused for
|
|
.BR tee ();
|
|
see
|
|
.BR vmsplice (2).
|
|
.SH RETURN VALUE
|
|
Upon successful completion,
|
|
.BR tee ()
|
|
returns the number of bytes that were duplicated between the input
|
|
and output.
|
|
A return value of 0 means that there was no data to transfer,
|
|
and it would not make sense to block, because there are no
|
|
writers connected to the write end of the pipe referred to by
|
|
.IR fd_in .
|
|
|
|
On error,
|
|
.BR tee ()
|
|
returns \-1 and
|
|
.I errno
|
|
is set to indicate the error.
|
|
.SH ERRORS
|
|
.TP
|
|
.B EINVAL
|
|
.I fd_in
|
|
or
|
|
.I fd_out
|
|
does not refer to a pipe; or
|
|
.I fd_in
|
|
and
|
|
.I fd_out
|
|
refer to the same pipe.
|
|
.TP
|
|
.B ENOMEM
|
|
Out of memory.
|
|
.SH NOTES
|
|
Conceptually,
|
|
.BR tee ()
|
|
copies the data between the two pipes.
|
|
In reality no real data copying takes place though:
|
|
under the covers,
|
|
.BR tee ()
|
|
assigns data in the output by merely grabbing
|
|
a reference to the input.
|
|
.SH EXAMPLE
|
|
The following example implements a basic
|
|
.BR tee (1)
|
|
program using the
|
|
.BR tee (2)
|
|
system call.
|
|
.nf
|
|
|
|
#define _GNU_SOURCE
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int fd;
|
|
int len, slen;
|
|
|
|
assert(argc == 2);
|
|
|
|
fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
if (fd == -1) {
|
|
perror("open");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
do {
|
|
/*
|
|
* tee stdin to stdout.
|
|
*/
|
|
len = tee(STDIN_FILENO, STDOUT_FILENO,
|
|
INT_MAX, SPLICE_F_NONBLOCK);
|
|
|
|
if (len < 0) {
|
|
if (errno == EAGAIN)
|
|
continue;
|
|
perror("tee");
|
|
exit(EXIT_FAILURE);
|
|
} else
|
|
if (len == 0)
|
|
break;
|
|
|
|
/*
|
|
* Consume stdin by splicing it to a file.
|
|
*/
|
|
while (len > 0) {
|
|
slen = splice(STDIN_FILENO, NULL, fd, NULL,
|
|
len, SPLICE_F_MOVE);
|
|
if (slen < 0) {
|
|
perror("splice");
|
|
break;
|
|
}
|
|
len -= slen;
|
|
}
|
|
} while (1);
|
|
|
|
close(fd);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
.fi
|
|
.SH HISTORY
|
|
The
|
|
.BR tee (2)
|
|
system call first appeared in Linux-2.6.17.
|
|
.SH "CONFORMING TO"
|
|
This system call is Linux specific.
|
|
.SH SEE ALSO
|
|
.BR splice (2),
|
|
.BR vmsplice (2)
|