path: root/test-line-buffer.c
diff options
authorJonathan Nieder <>2011-01-03 01:07:16 (GMT)
committerJonathan Nieder <>2011-02-26 10:58:21 (GMT)
commitd280f68313eecb8b3838c70641a246382d5e5343 (patch)
treeb3c1b28bac14250c9616de65869ad5ac5ca48997 /test-line-buffer.c
parent7b990c90514b24097ee71edbc02cb3a497a9476b (diff)
t0081 (line-buffer): add buffering tests
POSIX makes the behavior of read(2) from a pipe fairly clear: a read from an empty pipe will block until there is data available and any other read will not block, prefering to return a partial result. Likewise, fread(3) and fgets(3) are clearly specified to act as though implemented by calling fgetc(3) in a simple loop. But the buffering behavior of fgetc is less clear. Luckily, no sane platform is going to implement fgetc by calling the equivalent of read(2) more than once. fgetc has to be able to return without filling its buffer to preserve errno when errors are encountered anyway. So let's assume the simpler behavior (trust) but add some tests to catch insane platforms that violate that when they come (verify). First check that fread can handle a 0-length read from an empty fifo. Because open(O_RDONLY) blocks until the writing end is open, open the writing end of the fifo in advance in a subshell. Next try short inputs from a pipe that is not filled all the way. Lastly (two tests) try very large inputs from a pipe that will not fit in the relevant buffers. The first of these tests reads a little more than 8192 bytes, which is BUFSIZ (the size of stdio's buffers) on this Linux machine. The second reads a little over 64 KiB (the pipe capacity on Linux) and is not run unless requested by setting the GIT_REMOTE_SVN_TEST_BIG_FILES environment variable. Signed-off-by: Jonathan Nieder <>
Diffstat (limited to 'test-line-buffer.c')
1 files changed, 19 insertions, 3 deletions
diff --git a/test-line-buffer.c b/test-line-buffer.c
index da0bc65..ec19b13 100644
--- a/test-line-buffer.c
+++ b/test-line-buffer.c
@@ -49,15 +49,31 @@ static void handle_line(const char *line, struct line_buffer *stdin_buf)
int main(int argc, char *argv[])
struct line_buffer stdin_buf = LINE_BUFFER_INIT;
+ struct line_buffer file_buf = LINE_BUFFER_INIT;
+ struct line_buffer *input = &stdin_buf;
+ const char *filename;
char *s;
- if (argc != 1)
- usage("test-line-buffer < script");
+ if (argc == 1)
+ filename = NULL;
+ else if (argc == 2)
+ filename = argv[1];
+ else
+ usage("test-line-buffer [file] < script");
if (buffer_init(&stdin_buf, NULL))
die_errno("open error");
+ if (filename) {
+ if (buffer_init(&file_buf, filename))
+ die_errno("error opening %s", filename);
+ input = &file_buf;
+ }
while ((s = buffer_read_line(&stdin_buf)))
- handle_line(s, &stdin_buf);
+ handle_line(s, input);
+ if (filename && buffer_deinit(&file_buf))
+ die("error reading from %s", filename);
if (buffer_deinit(&stdin_buf))
die("input error");
if (ferror(stdout))