diff options
Diffstat (limited to 'src/yes.c')
-rw-r--r-- | src/yes.c | 62 |
1 files changed, 54 insertions, 8 deletions
@@ -1,5 +1,5 @@ /* yes - output a string repeatedly until killed - Copyright (C) 1991-2014 Free Software Foundation, Inc. + Copyright (C) 1991-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ Repeatedly output a line with all specified STRING(s), or 'y'.\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); - emit_ancillary_info (); + emit_ancillary_info (PROGRAM_NAME); } exit (status); } @@ -58,6 +58,10 @@ Repeatedly output a line with all specified STRING(s), or 'y'.\n\ int main (int argc, char **argv) { + char buf[BUFSIZ]; + char *pbuf = buf; + int i; + initialize_main (&argc, &argv); set_program_name (argv[0]); setlocale (LC_ALL, ""); @@ -77,12 +81,54 @@ main (int argc, char **argv) argv[argc++] = bad_cast ("y"); } - while (true) + /* Buffer data locally once, rather than having the + large overhead of stdio buffering each item. */ + for (i = optind; i < argc; i++) + { + size_t len = strlen (argv[i]); + if (BUFSIZ < len || BUFSIZ - len <= pbuf - buf) + break; + memcpy (pbuf, argv[i], len); + pbuf += len; + *pbuf++ = i == argc - 1 ? '\n' : ' '; + } + if (i == argc) + { + size_t line_len = pbuf - buf; + size_t lines = BUFSIZ / line_len; + while (--lines) + { + memcpy (pbuf, pbuf - line_len, line_len); + pbuf += line_len; + } + } + + /* The normal case is to continuously output the local buffer. */ + while (i == argc) + { + if (write (STDOUT_FILENO, buf, pbuf - buf) == -1) + { + error (0, errno, _("standard output")); + return EXIT_FAILURE; + } + } + + /* If the data doesn't fit in BUFSIZ then output + what we've buffered, and iterate over the remaining items. */ + while (true /* i != argc */) { - int i; - for (i = optind; i < argc; i++) - if (fputs (argv[i], stdout) == EOF - || putchar (i == argc - 1 ? '\n' : ' ') == EOF) - error (EXIT_FAILURE, errno, _("standard output")); + 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; + } } } |