summaryrefslogtreecommitdiff
path: root/src/yes.c
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivano@gnu.org>2015-03-10 12:25:48 +0000
committerPádraig Brady <P@draigBrady.com>2015-03-10 12:30:33 +0000
commite2e11119e0ac653bd0bdab91c189b7803f8df1f0 (patch)
tree47b82ed120099802b15c5422849c35bcd13402ff /src/yes.c
parent35217221c211f3116f374f305654462195aa634a (diff)
downloadcoreutils-e2e11119e0ac653bd0bdab91c189b7803f8df1f0.tar.xz
yes: improve efficiency when all args aren't buffered
* src/yes.c (main): Even when the internal buffer isn't large enough, output what we've buffered already, and interate over the rest. This improves the performance in the edge case where there are many small arguments that overflow the buffer. * tests/misc/yes.sh: Add a test case for the many small arguments case.
Diffstat (limited to 'src/yes.c')
-rw-r--r--src/yes.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/yes.c b/src/yes.c
index d6dd4b1ef..3b7b4c621 100644
--- a/src/yes.c
+++ b/src/yes.c
@@ -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;