This is an article where Linus Torvalds explicitly describes splice():
The splice system calls first appeared in the Linux kernel version 2.6.17 and was authored by Jens Axboe.
/* Our call to splice (no header currently). */
static inline int splice(int fdin, loff_t *off_in, int fdout, loff_t *off_out,
size_t len, unsigned int flags)
{
return syscall(__NR_splice, fdin, off_in, fdout, off_out, len, flags);
}
Some constants that are of interest are:
/* Splice flags (not laid down in stone yet). */
#ifndef SPLICE_F_MOVE
#define SPLICE_F_MOVE 0x01
#endif
#ifndef SPLICE_F_NONBLOCK
#define SPLICE_F_NONBLOCK 0x02
#endif
#ifndef SPLICE_F_MORE
#define SPLICE_F_MORE 0x04
#endif
#ifndef SPLICE_F_GIFT
#define SPLICE_F_GIFT 0x08
#endif
#ifndef __NR_splice
#define __NR_splice 313
#endif
/* Transfer from disk to a log. */
int log_blocks (struct log_handle * handle, int fd, loff_t offset, size_t size)
{
int filedes [2];
int ret;
size_t to_write = size;
ret = pipe (filedes);
if (ret < 0)
goto out;
/* splice the file into the pipe (data in kernel memory). */
while (to_write > 0) {
ret = splice (fd, &offset, filedes [1], NULL, to_write,
SPLICE_F_MORE | SPLICE_F_MOVE);
if (ret < 0)
goto pipe;
else
to_write -= ret;
}
to_write = size;
/* splice the data in the pipe (in kernel memory) into the file. */
while (to_write > 0) {
ret = splice (filedes [0], NULL, handle->fd,
&(handle->fd_offset), to_write,
SPLICE_F_MORE | SPLICE_F_MOVE);
if (ret < 0)
goto pipe;
else
to_write -= ret;
}
pipe:
close (filedes [0]);
close (filedes [1]);
out:
if (ret < 0)
return -errno;
return 0;
}