From: "Michael Kerrisk" <mtk-manpages@gmx.net>
To: Jens Axboe <axboe@suse.de>
Cc: linux-kernel@vger.kernel.org
Subject: splice() and file offsets
Date: Mon, 10 Jul 2006 14:11:10 +0200 [thread overview]
Message-ID: <20060710121110.26260@gmx.net> (raw)
Jens,
What are the semantics of splice() supposed to be with respect
to the current file offsets of 'fd_in' and 'fd_out', and how
is the presence or absence (NULL) of 'off_in' and 'off_out'
supposed to affect things.
Using the program below, here is what I observe for
fd_out/off_out:
1. If off_out is NULL, then
a) splice() changes the current file offset of fd_out.
2. If off_out is not NULL, then splice()
a) does not change the current file offset of fd_out, but
b) treats off_out as a value result parameter, returning
an updated offset of the file.
It is "2 a)" that surprises me. But perhaps it's expected
behaviour; or I'm doing something dumb in my test program.
If the test program is run without a third command-line
argument, then 'off_out' is specified as NULL, and we see:
$ find .. | ./t_splice out
splice() returned 69632
After splice(), offset of fd is: 69632; off_out = 0
splice() returned 32768
After splice(), offset of fd is: 102400; off_out = 0
splice() returned 100000
After splice(), offset of fd is: 202400; off_out = 0
splice() returned 14688
After splice(), offset of fd is: 217088; off_out = 0
splice() returned 31990
After splice(), offset of fd is: 249078; off_out = 0
splice() returned 0
After splice(), offset of fd is: 249078; off_out = 0
If the test program is run with a third command-line
argument, then 'off_out' is initialised to 0, and then
supplied as an argument on each splice() call, and we
see:
$ find .. | ./t_splice out x
splice() returned 20480
After splice(), offset of fd is: 0; off_out = 20480
splice() returned 49152
After splice(), offset of fd is: 0; off_out = 69632
splice() returned 100000
After splice(), offset of fd is: 0; off_out = 169632
splice() returned 35168
After splice(), offset of fd is: 0; off_out = 204800
splice() returned 44278
After splice(), offset of fd is: 0; off_out = 249078
splice() returned 0
After splice(), offset of fd is: 0; off_out = 249078
Cheers,
Michael
/* t_splice.c */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
#if defined(__i386__)
#define __NR_splice 313
#define __NR_tee 315
#else
#error unsupported arch
#endif
#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
/* we may still block on the fd we splice */
/* from/to, of course */
#define SPLICE_F_MORE (0x04) /* expect more data */
#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */
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);
}
static inline int tee(int fdin, int fdout, size_t len, unsigned int flags)
{
return syscall(__NR_tee, fdin, fdout, len, flags);
}
int
main(int argc, char *argv[])
{
int fd;
int slen;
loff_t off_out;
assert(argc >= 2);
fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
off_out = 0;
for (;;) {
slen = splice(STDIN_FILENO, NULL, fd,
(argc > 2) ? &off_out : NULL, 100000, 0);
if (slen < 0) {
perror("splice");
break;
}
fprintf(stderr, "splice() returned %ld\n", (long) slen);
fprintf(stderr, "After splice(), offset of fd is: %lld; "
"off_out = %lld\n",
(long long) lseek(fd, 0, SEEK_CUR),
(long long) off_out);
if (slen == 0)
break;
}
close(fd);
exit(EXIT_SUCCESS);
}
--
Michael Kerrisk
maintainer of Linux man pages Sections 2, 3, 4, 5, and 7
Want to help with man page maintenance?
Grab the latest tarball at
ftp://ftp.win.tue.nl/pub/linux-local/manpages/,
read the HOWTOHELP file and grep the source
files for 'FIXME'.
next reply other threads:[~2006-07-10 12:11 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-10 12:11 Michael Kerrisk [this message]
2006-07-10 12:51 ` splice() and file offsets Jens Axboe
2006-07-10 13:07 ` Michael Kerrisk
2006-07-10 13:25 ` Jens Axboe
2006-07-10 13:54 ` Michael Kerrisk
2006-07-10 14:22 ` Jens Axboe
2006-07-10 15:48 ` Michael Kerrisk
2006-07-10 16:51 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060710121110.26260@gmx.net \
--to=mtk-manpages@gmx.net \
--cc=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.