From: "Michael Kerrisk" <mtk-manpages@gmx.net>
To: axboe@suse.de
Cc: linux-kernel@vger.kernel.org, michael.kerrisk@gmx.net
Subject: splice/tee bugs?
Date: Fri, 07 Jul 2006 09:07:03 +0200 [thread overview]
Message-ID: <20060707070703.165520@gmx.net> (raw)
Hello Jens,
While editing and extending your draft man pages for
tee(), splice(), vmsplice() I've been testing out
the splice()/tee() calls using a modified version of
the program you provided in the tee.2 manual page.
The most notable differences between my program and yours
are:
* I print some debugging info to stderr.
* I don't pass SPLICE_F_NONBLOCK to tee().
I'm running this on kernel 2.6.17, using the following
command line:
$ ls *.c | ktee r | wc
On different runs I see:
a) No output from ls through the pipeline:
tee returned 0
0 0 0
b) Very many instances of EAGAIN followed by expected results:
...
EAGAIN
EAGAIN
EAGAIN
EAGAIN
EAGAIN
EAGAIN
tee returned 19
splice returned 19
tee returned 0
2 2 19
In some of these cases the elapsed time to run the command-line
is 1 or 2 seconds in this case (instead of the more typical
0.05 seconds).
c) Occasionally the command line just hangs, producing no output.
In this case I can't kill it with ^C or ^\. This is a
hard-to-reproduce behaviour on my (x86) system, but I have
seen it several times by now.
Assuming I'm not messing up with my test method, some
observations:
Result a) seems to be occurring because tee() returns 0 if its
in_fd is not yet "ready" to deliver data. Shouldn't tee()
be blocking in this case? And should not 0 only
be returned for EOF? on the input file descriptor?
If I uncomment the usleep() line in the program, this behavior
does not occur--the program always just produces the expected
output:
tee returned 19
splice returned 19
tee returned 0
2 2 19
For behaviour b) -- why does tee() give EAGAIN when
I haven't specified SPLICE_F_NONBLOCK? (This is a
philosophical question; I can see that there are code paths
that lead to EAGAIN without SPLICE_F_NONBLOCK, but that
seems confusing behaviour for userland.)
Behaviour c) hints of a bug in tee().
Your thoughts?
Cheers,
Michael
====
/* ktee.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 len, slen;
assert(argc == 2);
fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
//usleep(100000);
do {
/*
* tee stdin to stdout.
*/
len = tee(STDIN_FILENO, STDOUT_FILENO,
INT_MAX, 0);
if (len < 0) {
if (errno == EAGAIN) {
fprintf(stderr, "EAGAIN\n");
continue;
}
perror("tee");
exit(EXIT_FAILURE);
}
fprintf(stderr, "tee returned %ld\n", (long) len);
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;
}
fprintf(stderr, "splice returned %ld\n", (long) slen);
len -= slen;
}
} while (1);
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-07 7:07 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-07 7:07 Michael Kerrisk [this message]
2006-07-07 11:07 ` splice/tee bugs? Andrew Morton
2006-07-07 11:42 ` Michael Kerrisk
2006-07-07 12:03 ` Jens Axboe
2006-07-07 12:28 ` Jens Axboe
2006-07-07 12:31 ` Michael Kerrisk
2006-07-07 12:41 ` Jens Axboe
2006-07-07 13:12 ` Jens Axboe
2006-07-07 13:14 ` Jens Axboe
2006-07-07 13:21 ` Arjan van de Ven
2006-07-07 13:26 ` Jens Axboe
2006-07-07 13:54 ` Paulo Marques
2006-07-07 14:02 ` Jens Axboe
2006-07-07 14:05 ` Michael Kerrisk
2006-07-07 14:08 ` Jens Axboe
2006-07-07 16:13 ` Luiz Fernando N. Capitulino
2006-07-07 21:43 ` Luiz Fernando N. Capitulino
2006-07-08 6:41 ` Jens Axboe
2006-07-08 21:09 ` Luiz Fernando N. Capitulino
2006-07-09 10:36 ` Jens Axboe
2006-07-09 11:16 ` Jens Axboe
2006-07-09 16:47 ` Luiz Fernando N. Capitulino
2006-07-09 17:57 ` Jens Axboe
2006-07-10 6:25 ` Michael Kerrisk
2006-07-10 6:43 ` Jens Axboe
2006-07-10 8:09 ` Michael Kerrisk
2006-07-10 8:24 ` Jens Axboe
2006-07-10 8:40 ` Michael Kerrisk
2006-07-10 8:46 ` Jens Axboe
2006-07-10 8:50 ` Michael Kerrisk
2006-07-10 9:06 ` Jens Axboe
2006-07-10 9:08 ` Michael Kerrisk
2006-07-10 8:50 ` Jens Axboe
-- strict thread matches above, loose matches on Subject: below --
2006-07-08 5:33 Chuck Ebbert
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=20060707070703.165520@gmx.net \
--to=mtk-manpages@gmx.net \
--cc=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.kerrisk@gmx.net \
/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.