Blame man2/splice.2

Packit 7cfc04
.\" This manpage is Copyright (C) 2006 Jens Axboe
Packit 7cfc04
.\" and Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
Packit 7cfc04
.\"
Packit 7cfc04
.\" %%%LICENSE_START(VERBATIM)
Packit 7cfc04
.\" Permission is granted to make and distribute verbatim copies of this
Packit 7cfc04
.\" manual provided the copyright notice and this permission notice are
Packit 7cfc04
.\" preserved on all copies.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Permission is granted to copy and distribute modified versions of this
Packit 7cfc04
.\" manual under the conditions for verbatim copying, provided that the
Packit 7cfc04
.\" entire resulting derived work is distributed under the terms of a
Packit 7cfc04
.\" permission notice identical to this one.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Since the Linux kernel and libraries are constantly changing, this
Packit 7cfc04
.\" manual page may be incorrect or out-of-date.  The author(s) assume no
Packit 7cfc04
.\" responsibility for errors or omissions, or for damages resulting from
Packit 7cfc04
.\" the use of the information contained herein.  The author(s) may not
Packit 7cfc04
.\" have taken the same level of care in the production of this manual,
Packit 7cfc04
.\" which is licensed free of charge, as they might when working
Packit 7cfc04
.\" professionally.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Formatted or processed versions of this manual, if unaccompanied by
Packit 7cfc04
.\" the source, must acknowledge the copyright and authors of this work.
Packit 7cfc04
.\" %%%LICENSE_END
Packit 7cfc04
.\"
Packit 7cfc04
.TH SPLICE 2 2017-09-15 "Linux" "Linux Programmer's Manual"
Packit 7cfc04
.SH NAME
Packit 7cfc04
splice \- splice data to/from a pipe
Packit 7cfc04
.SH SYNOPSIS
Packit 7cfc04
.nf
Packit 7cfc04
.BR "#define _GNU_SOURCE" "         /* See feature_test_macros(7) */"
Packit 7cfc04
.B #include <fcntl.h>
Packit 7cfc04
.PP
Packit 7cfc04
.BI "ssize_t splice(int " fd_in ", loff_t *" off_in ", int " fd_out ,
Packit 7cfc04
.BI "               loff_t *" off_out ", size_t " len \
Packit 7cfc04
", unsigned int " flags );
Packit 7cfc04
.\" Return type was long before glibc 2.7
Packit 7cfc04
.fi
Packit 7cfc04
.SH DESCRIPTION
Packit 7cfc04
.BR splice ()
Packit 7cfc04
moves data between two file descriptors
Packit 7cfc04
without copying between kernel address space and user address space.
Packit 7cfc04
It transfers up to
Packit 7cfc04
.I len
Packit 7cfc04
bytes of data from the file descriptor
Packit 7cfc04
.I fd_in
Packit 7cfc04
to the file descriptor
Packit 7cfc04
.IR fd_out ,
Packit 7cfc04
where one of the file descriptors must refer to a pipe.
Packit 7cfc04
.PP
Packit 7cfc04
The following semantics apply for
Packit 7cfc04
.I fd_in
Packit 7cfc04
and
Packit 7cfc04
.IR off_in :
Packit 7cfc04
.IP * 3
Packit 7cfc04
If
Packit 7cfc04
.I fd_in
Packit 7cfc04
refers to a pipe, then
Packit 7cfc04
.I off_in
Packit 7cfc04
must be NULL.
Packit 7cfc04
.IP *
Packit 7cfc04
If
Packit 7cfc04
.I fd_in
Packit 7cfc04
does not refer to a pipe and
Packit 7cfc04
.I off_in
Packit 7cfc04
is NULL, then bytes are read from
Packit 7cfc04
.I fd_in
Packit 7cfc04
starting from the file offset,
Packit 7cfc04
and the file offset is adjusted appropriately.
Packit 7cfc04
.IP *
Packit 7cfc04
If
Packit 7cfc04
.I fd_in
Packit 7cfc04
does not refer to a pipe and
Packit 7cfc04
.I off_in
Packit 7cfc04
is not NULL, then
Packit 7cfc04
.I off_in
Packit 7cfc04
must point to a buffer which specifies the starting
Packit 7cfc04
offset from which bytes will be read from
Packit 7cfc04
.IR fd_in ;
Packit 7cfc04
in this case, the file offset of
Packit 7cfc04
.I fd_in
Packit 7cfc04
is not changed.
Packit 7cfc04
.PP
Packit 7cfc04
Analogous statements apply for
Packit 7cfc04
.I fd_out
Packit 7cfc04
and
Packit 7cfc04
.IR off_out .
Packit 7cfc04
.PP
Packit 7cfc04
The
Packit 7cfc04
.I flags
Packit 7cfc04
argument is a bit mask that is composed by ORing together
Packit 7cfc04
zero or more of the following values:
Packit 7cfc04
.TP
Packit 7cfc04
.B SPLICE_F_MOVE
Packit 7cfc04
Attempt to move pages instead of copying.
Packit 7cfc04
This is only a hint to the kernel:
Packit 7cfc04
pages may still be copied if the kernel cannot move the
Packit 7cfc04
pages from the pipe, or if
Packit 7cfc04
the pipe buffers don't refer to full pages.
Packit 7cfc04
The initial implementation of this flag was buggy:
Packit 7cfc04
therefore starting in Linux 2.6.21 it is a no-op
Packit 7cfc04
(but is still permitted in a
Packit 7cfc04
.BR splice ()
Packit 7cfc04
call);
Packit 7cfc04
in the future, a correct implementation may be restored.
Packit 7cfc04
.TP
Packit 7cfc04
.B SPLICE_F_NONBLOCK
Packit 7cfc04
Do not block on I/O.
Packit 7cfc04
This makes the splice pipe operations nonblocking, but
Packit 7cfc04
.BR splice ()
Packit 7cfc04
may nevertheless block because the file descriptors that
Packit 7cfc04
are spliced to/from may block (unless they have the
Packit 7cfc04
.B O_NONBLOCK
Packit 7cfc04
flag set).
Packit 7cfc04
.TP
Packit 7cfc04
.B SPLICE_F_MORE
Packit 7cfc04
More data will be coming in a subsequent splice.
Packit 7cfc04
This is a helpful hint when
Packit 7cfc04
the
Packit 7cfc04
.I fd_out
Packit 7cfc04
refers to a socket (see also the description of
Packit 7cfc04
.B MSG_MORE
Packit 7cfc04
in
Packit 7cfc04
.BR send (2),
Packit 7cfc04
and the description of
Packit 7cfc04
.B TCP_CORK
Packit 7cfc04
in
Packit 7cfc04
.BR tcp (7)).
Packit 7cfc04
.TP
Packit 7cfc04
.B SPLICE_F_GIFT
Packit 7cfc04
Unused for
Packit 7cfc04
.BR splice ();
Packit 7cfc04
see
Packit 7cfc04
.BR vmsplice (2).
Packit 7cfc04
.SH RETURN VALUE
Packit 7cfc04
Upon successful completion,
Packit 7cfc04
.BR splice ()
Packit 7cfc04
returns the number of bytes
Packit 7cfc04
spliced to or from the pipe.
Packit 7cfc04
.PP
Packit 7cfc04
A return value of 0 means end of input.
Packit 7cfc04
If
Packit 7cfc04
.I fd_in
Packit 7cfc04
refers to a pipe, then this means that there was no data to transfer,
Packit 7cfc04
and it would not make sense to block because there are no writers
Packit 7cfc04
connected to the write end of the pipe.
Packit 7cfc04
.PP
Packit 7cfc04
On error,
Packit 7cfc04
.BR splice ()
Packit 7cfc04
returns \-1 and
Packit 7cfc04
.I errno
Packit 7cfc04
is set to indicate the error.
Packit 7cfc04
.SH ERRORS
Packit 7cfc04
.TP
Packit 7cfc04
.B EAGAIN
Packit 7cfc04
.B SPLICE_F_NONBLOCK
Packit 7cfc04
was specified in
Packit 7cfc04
.IR flags ,
Packit 7cfc04
and the operation would block.
Packit 7cfc04
.TP
Packit 7cfc04
.B EBADF
Packit 7cfc04
One or both file descriptors are not valid,
Packit 7cfc04
or do not have proper read-write mode.
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
The target filesystem doesn't support splicing.
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
The target file is opened in append mode.
Packit 7cfc04
.\" The append-mode error is given since 2.6.27; in earlier kernels,
Packit 7cfc04
.\" splice() in append mode was broken
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
Neither of the file descriptors refers to a pipe.
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
An offset was given for nonseekable device (e.g., a pipe).
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
.I fd_in
Packit 7cfc04
and
Packit 7cfc04
.I fd_out
Packit 7cfc04
refer to the same pipe.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOMEM
Packit 7cfc04
Out of memory.
Packit 7cfc04
.TP
Packit 7cfc04
.B ESPIPE
Packit 7cfc04
Either
Packit 7cfc04
.I off_in
Packit 7cfc04
or
Packit 7cfc04
.I off_out
Packit 7cfc04
was not NULL, but the corresponding file descriptor refers to a pipe.
Packit 7cfc04
.SH VERSIONS
Packit 7cfc04
The
Packit 7cfc04
.BR splice ()
Packit 7cfc04
system call first appeared in Linux 2.6.17;
Packit 7cfc04
library support was added to glibc in version 2.5.
Packit 7cfc04
.SH CONFORMING TO
Packit 7cfc04
This system call is Linux-specific.
Packit 7cfc04
.SH NOTES
Packit 7cfc04
The three system calls
Packit 7cfc04
.BR splice (),
Packit 7cfc04
.BR vmsplice (2),
Packit 7cfc04
and
Packit 7cfc04
.BR tee (2),
Packit 7cfc04
provide user-space programs with full control over an arbitrary
Packit 7cfc04
kernel buffer, implemented within the kernel using the same type
Packit 7cfc04
of buffer that is used for a pipe.
Packit 7cfc04
In overview, these system calls perform the following tasks:
Packit 7cfc04
.TP 1.2i
Packit 7cfc04
.BR splice ()
Packit 7cfc04
moves data from the buffer to an arbitrary file descriptor, or vice versa,
Packit 7cfc04
or from one buffer to another.
Packit 7cfc04
.TP
Packit 7cfc04
.BR tee (2)
Packit 7cfc04
"copies" the data from one buffer to another.
Packit 7cfc04
.TP
Packit 7cfc04
.BR vmsplice (2)
Packit 7cfc04
"copies" data from user space into the buffer.
Packit 7cfc04
.PP
Packit 7cfc04
Though we talk of copying, actual copies are generally avoided.
Packit 7cfc04
The kernel does this by implementing a pipe buffer as a set
Packit 7cfc04
of reference-counted pointers to pages of kernel memory.
Packit 7cfc04
The kernel creates "copies" of pages in a buffer by creating new
Packit 7cfc04
pointers (for the output buffer) referring to the pages,
Packit 7cfc04
and increasing the reference counts for the pages:
Packit 7cfc04
only pointers are copied, not the pages of the buffer.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Linus: Now, imagine using the above in a media server, for example.
Packit 7cfc04
.\" Let's say that a year or two has passed, so that the video drivers
Packit 7cfc04
.\" have been updated to be able to do the splice thing, and what can
Packit 7cfc04
.\" you do? You can:
Packit 7cfc04
.\"
Packit 7cfc04
.\" - splice from the (mpeg or whatever - let's just assume that the video
Packit 7cfc04
.\"   input is either digital or does the encoding on its own - like they
Packit 7cfc04
.\"   pretty much all do) video input into a pipe (remember: no copies - the
Packit 7cfc04
.\"   video input will just DMA directly into memory, and splice will just
Packit 7cfc04
.\"   set up the pages in the pipe buffer)
Packit 7cfc04
.\" - tee that pipe to split it up
Packit 7cfc04
.\" - splice one end to a file (ie "save the compressed stream to disk")
Packit 7cfc04
.\" - splice the other end to a real-time video decoder window for your
Packit 7cfc04
.\"   real-time viewing pleasure.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Linus: Now, the advantage of splice()/tee() is that you can
Packit 7cfc04
.\" do zero-copy movement of data, and unlike sendfile() you can
Packit 7cfc04
.\" do it on _arbitrary_ data (and, as shown by "tee()", it's more
Packit 7cfc04
.\" than just sending the data to somebody else: you can duplicate
Packit 7cfc04
.\" the data and choose to forward it to two or more different
Packit 7cfc04
.\" users - for things like logging etc.).
Packit 7cfc04
.\"
Packit 7cfc04
.PP
Packit 7cfc04
In Linux 2.6.30 and earlier,
Packit 7cfc04
exactly one of
Packit 7cfc04
.I fd_in
Packit 7cfc04
and
Packit 7cfc04
.I fd_out
Packit 7cfc04
was required to be a pipe.
Packit 7cfc04
Since Linux 2.6.31,
Packit 7cfc04
.\" commit 7c77f0b3f9208c339a4b40737bb2cb0f0319bb8d
Packit 7cfc04
both arguments may refer to pipes.
Packit 7cfc04
.SH EXAMPLE
Packit 7cfc04
See
Packit 7cfc04
.BR tee (2).
Packit 7cfc04
.SH SEE ALSO
Packit 7cfc04
.BR copy_file_range (2),
Packit 7cfc04
.BR sendfile (2),
Packit 7cfc04
.BR tee (2),
Packit 7cfc04
.BR vmsplice (2),
Packit 7cfc04
.BR pipe (7)
Packit 7cfc04
.SH COLOPHON
Packit 7cfc04
This page is part of release 4.15 of the Linux
Packit 7cfc04
.I man-pages
Packit 7cfc04
project.
Packit 7cfc04
A description of the project,
Packit 7cfc04
information about reporting bugs,
Packit 7cfc04
and the latest version of this page,
Packit 7cfc04
can be found at
Packit 7cfc04
\%https://www.kernel.org/doc/man\-pages/.