diff options
-rw-r--r-- | src/yes.c | 26 | ||||
-rwxr-xr-x | tests/misc/yes.sh | 12 |
2 files changed, 26 insertions, 12 deletions
@@ -82,7 +82,7 @@ main (int argc, char **argv) } /* Buffer data locally once, rather than having the - large overhead of stdio buffering each item. */ + large overhead of stdio buffering each item. */ for (i = optind; i < argc; i++) { size_t len = strlen (argv[i]); @@ -92,9 +92,7 @@ main (int argc, char **argv) pbuf += len; *pbuf++ = i == argc - 1 ? '\n' : ' '; } - if (i < argc) - pbuf = NULL; - else + if (i == argc) { size_t line_len = pbuf - buf; size_t lines = BUFSIZ / line_len; @@ -106,7 +104,7 @@ main (int argc, char **argv) } /* The normal case is to continuously output the local buffer. */ - while (pbuf) + while (i == argc) { if (write (STDOUT_FILENO, buf, pbuf - buf) == -1) { @@ -115,13 +113,19 @@ main (int argc, char **argv) } } - /* If the data doesn't fit in BUFSIZ then it's large - and not too inefficient to output through stdio. */ - while (! pbuf) + /* If the data doesn't fit in BUFSIZ then output + what we've buffered, and iterate over the remaining items. */ + while (i != argc) { - for (i = optind; i < argc; i++) - if (fputs (argv[i], stdout) == EOF - || putchar (i == argc - 1 ? '\n' : ' ') == EOF) + int j; + if ((pbuf - buf) && fwrite (buf, pbuf - buf, 1, stdout) != 1) + { + error (0, errno, _("standard output")); + return EXIT_FAILURE; + } + for (j = i; j < argc; j++) + if (fputs (argv[j], stdout) == EOF + || putchar (j == argc - 1 ? '\n' : ' ') == EOF) { error (0, errno, _("standard output")); return EXIT_FAILURE; diff --git a/tests/misc/yes.sh b/tests/misc/yes.sh index 4ed300a4f..79f8b87c0 100755 --- a/tests/misc/yes.sh +++ b/tests/misc/yes.sh @@ -19,7 +19,7 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ yes -# Check various buffer sizes, with the most important +# Check various single item sizes, with the most important # size being BUFSIZ used for the local buffer to yes(1). # Note a \n is added, so actual sizes required internally # are 1 more than the size used here. @@ -29,4 +29,14 @@ for size in 1 1999 4095 4096 8191 8192 16383 16384; do compare out.1 out.2 || fail=1 done +# Check the many small items case, +# both fitting and overflowing the internal buffer +if env true $(seq 4000); then + for i in 100 4000; do + seq $i | paste -s -d ' ' | sed p > out.1 + yes $(seq $i) | head -n2 > out.2 + compare out.1 out.2 || fail=1 + done +fi + Exit $fail |