tail: avoid infloop with -c on /dev/zero
[coreutils.git] / src / wc.c
blobd70ad39363e860632a29c68a34aa7fc4f53dc62d
1 /* wc - print the number of lines, words, and bytes in files
2 Copyright (C) 1985-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Paul Rubin, phr@ocf.berkeley.edu
18 and David MacKenzie, djm@gnu.ai.mit.edu. */
20 #include <config.h>
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <getopt.h>
25 #include <sys/types.h>
26 #include <uchar.h>
28 #include <argmatch.h>
29 #include <argv-iter.h>
30 #include <fadvise.h>
31 #include <physmem.h>
32 #include <readtokens0.h>
33 #include <stat-size.h>
34 #include <xbinary-io.h>
36 #include "system.h"
37 #include "wc.h"
39 /* The official name of this program (e.g., no 'g' prefix). */
40 #define PROGRAM_NAME "wc"
42 #define AUTHORS \
43 proper_name ("Paul Rubin"), \
44 proper_name ("David MacKenzie")
46 /* Size of atomic reads. */
47 #define BUFFER_SIZE (16 * 1024)
49 static bool wc_isprint[UCHAR_MAX + 1];
50 static bool wc_isspace[UCHAR_MAX + 1];
52 static bool debug;
54 /* Cumulative number of lines, words, chars and bytes in all files so far.
55 max_line_length is the maximum over all files processed so far. */
56 static uintmax_t total_lines;
57 static uintmax_t total_words;
58 static uintmax_t total_chars;
59 static uintmax_t total_bytes;
60 static bool total_lines_overflow;
61 static bool total_words_overflow;
62 static bool total_chars_overflow;
63 static bool total_bytes_overflow;
64 static intmax_t max_line_length;
66 /* Which counts to print. */
67 static bool print_lines, print_words, print_chars, print_bytes;
68 static bool print_linelength;
70 /* The print width of each count. */
71 static int number_width;
73 /* True if we have ever read the standard input. */
74 static bool have_read_stdin;
76 /* Used to determine if file size can be determined without reading. */
77 static idx_t page_size;
79 /* Enable to _not_ treat non breaking space as a word separator. */
80 static bool posixly_correct;
82 /* The result of calling fstat or stat on a file descriptor or file. */
83 struct fstatus
85 /* If positive, fstat or stat has not been called yet. Otherwise,
86 this is the value returned from fstat or stat. */
87 int failed;
89 /* If FAILED is zero, this is the file's status. */
90 struct stat st;
93 /* For long options that have no equivalent short option, use a
94 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
95 enum
97 DEBUG_PROGRAM_OPTION = CHAR_MAX + 1,
98 FILES0_FROM_OPTION,
99 TOTAL_OPTION,
102 static struct option const longopts[] =
104 {"bytes", no_argument, nullptr, 'c'},
105 {"chars", no_argument, nullptr, 'm'},
106 {"lines", no_argument, nullptr, 'l'},
107 {"words", no_argument, nullptr, 'w'},
108 {"debug", no_argument, nullptr, DEBUG_PROGRAM_OPTION},
109 {"files0-from", required_argument, nullptr, FILES0_FROM_OPTION},
110 {"max-line-length", no_argument, nullptr, 'L'},
111 {"total", required_argument, nullptr, TOTAL_OPTION},
112 {GETOPT_HELP_OPTION_DECL},
113 {GETOPT_VERSION_OPTION_DECL},
114 {nullptr, 0, nullptr, 0}
117 enum total_type
119 total_auto, /* 0: default or --total=auto */
120 total_always, /* 1: --total=always */
121 total_only, /* 2: --total=only */
122 total_never /* 3: --total=never */
124 static char const *const total_args[] =
126 "auto", "always", "only", "never", nullptr
128 static enum total_type const total_types[] =
130 total_auto, total_always, total_only, total_never
132 ARGMATCH_VERIFY (total_args, total_types);
133 static enum total_type total_mode = total_auto;
135 #ifdef USE_AVX2_WC_LINECOUNT
136 static bool
137 avx2_supported (void)
139 bool avx_enabled = 0 < __builtin_cpu_supports ("avx2");
141 if (debug)
142 error (0, 0, (avx_enabled
143 ? _("using avx2 hardware support")
144 : _("avx2 support not detected")));
146 return avx_enabled;
148 #endif
150 void
151 usage (int status)
153 if (status != EXIT_SUCCESS)
154 emit_try_help ();
155 else
157 printf (_("\
158 Usage: %s [OPTION]... [FILE]...\n\
159 or: %s [OPTION]... --files0-from=F\n\
161 program_name, program_name);
162 fputs (_("\
163 Print newline, word, and byte counts for each FILE, and a total line if\n\
164 more than one FILE is specified. A word is a nonempty sequence of non white\n\
165 space delimited by white space characters or by start or end of input.\n\
166 "), stdout);
168 emit_stdin_note ();
170 fputs (_("\
172 The options below may be used to select which counts are printed, always in\n\
173 the following order: newline, word, character, byte, maximum line length.\n\
174 -c, --bytes print the byte counts\n\
175 -m, --chars print the character counts\n\
176 -l, --lines print the newline counts\n\
177 "), stdout);
178 fputs (_("\
179 --files0-from=F read input from the files specified by\n\
180 NUL-terminated names in file F;\n\
181 If F is - then read names from standard input\n\
182 -L, --max-line-length print the maximum display width\n\
183 -w, --words print the word counts\n\
184 "), stdout);
185 fputs (_("\
186 --total=WHEN when to print a line with total counts;\n\
187 WHEN can be: auto, always, only, never\n\
188 "), stdout);
189 fputs (HELP_OPTION_DESCRIPTION, stdout);
190 fputs (VERSION_OPTION_DESCRIPTION, stdout);
191 emit_ancillary_info (PROGRAM_NAME);
193 exit (status);
196 /* Return non zero if a non breaking space. */
197 ATTRIBUTE_PURE
198 static int
199 iswnbspace (wint_t wc)
201 return ! posixly_correct
202 && (wc == 0x00A0 || wc == 0x2007
203 || wc == 0x202F || wc == 0x2060);
206 /* FILE is the name of the file (or null for standard input)
207 associated with the specified counters. */
208 static void
209 write_counts (uintmax_t lines,
210 uintmax_t words,
211 uintmax_t chars,
212 uintmax_t bytes,
213 intmax_t linelength,
214 char const *file)
216 static char const format_sp_int[] = " %*s";
217 char const *format_int = format_sp_int + 1;
218 char buf[MAX (INT_BUFSIZE_BOUND (intmax_t),
219 INT_BUFSIZE_BOUND (uintmax_t))];
221 if (print_lines)
223 printf (format_int, number_width, umaxtostr (lines, buf));
224 format_int = format_sp_int;
226 if (print_words)
228 printf (format_int, number_width, umaxtostr (words, buf));
229 format_int = format_sp_int;
231 if (print_chars)
233 printf (format_int, number_width, umaxtostr (chars, buf));
234 format_int = format_sp_int;
236 if (print_bytes)
238 printf (format_int, number_width, umaxtostr (bytes, buf));
239 format_int = format_sp_int;
241 if (print_linelength)
242 printf (format_int, number_width, imaxtostr (linelength, buf));
243 if (file)
244 printf (" %s", strchr (file, '\n') ? quotef (file) : file);
245 putchar ('\n');
248 /* Read FD and return a summary. */
249 static struct wc_lines
250 wc_lines (int fd)
252 #ifdef USE_AVX2_WC_LINECOUNT
253 static signed char use_avx2;
254 if (!use_avx2)
255 use_avx2 = avx2_supported () ? 1 : -1;
256 if (0 < use_avx2)
257 return wc_lines_avx2 (fd);
258 #endif
260 intmax_t lines = 0, bytes = 0;
261 bool long_lines = false;
263 while (true)
265 char buf[BUFFER_SIZE + 1];
266 ssize_t bytes_read = read (fd, buf, BUFFER_SIZE);
267 if (bytes_read <= 0)
268 return (struct wc_lines) { bytes_read == 0 ? 0 : errno, lines, bytes };
270 bytes += bytes_read;
271 char *end = buf + bytes_read;
272 idx_t buflines = 0;
274 if (! long_lines)
276 /* Avoid function call overhead for shorter lines. */
277 for (char *p = buf; p < end; p++)
278 buflines += *p == '\n';
280 else
282 /* rawmemchr is more efficient with longer lines. */
283 *end = '\n';
284 for (char *p = buf; (p = rawmemchr (p, '\n')) < end; p++)
285 buflines++;
288 /* If the average line length in the block is >= 15, then use
289 memchr for the next block, where system specific optimizations
290 may outweigh function call overhead.
291 FIXME: This line length was determined in 2015, on both
292 x86_64 and ppc64, but it's worth re-evaluating in future with
293 newer compilers, CPUs, or memchr() implementations etc. */
294 long_lines = 15 * buflines <= bytes_read;
295 lines += buflines;
299 /* Count words. FILE_X is the name of the file (or null for standard
300 input) that is open on descriptor FD. *FSTATUS is its status.
301 CURRENT_POS is the current file offset if known, negative if unknown.
302 Return true if successful. */
303 static bool
304 wc (int fd, char const *file_x, struct fstatus *fstatus, off_t current_pos)
306 int err = 0;
307 char buf[BUFFER_SIZE + 1];
308 intmax_t lines, words, chars, bytes, linelength;
309 bool count_bytes, count_chars, count_complicated;
310 char const *file = file_x ? file_x : _("standard input");
312 lines = words = chars = bytes = linelength = 0;
314 /* If in the current locale, chars are equivalent to bytes, we prefer
315 counting bytes, because that's easier. */
316 if (MB_CUR_MAX > 1)
318 count_bytes = print_bytes;
319 count_chars = print_chars;
321 else
323 count_bytes = print_bytes || print_chars;
324 count_chars = false;
326 count_complicated = print_words || print_linelength;
328 /* Advise the kernel of our access pattern only if we will read(). */
329 if (!count_bytes || count_chars || print_lines || count_complicated)
330 fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
332 /* When counting only bytes, save some line- and word-counting
333 overhead. If FD is a 'regular' Unix file, using lseek is enough
334 to get its 'size' in bytes. Otherwise, read blocks of BUFFER_SIZE
335 bytes at a time until EOF. Note that the 'size' (number of bytes)
336 that wc reports is smaller than stats.st_size when the file is not
337 positioned at its beginning. That's why the lseek calls below are
338 necessary. For example the command
339 '(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
340 should make wc report '0' bytes. */
342 if (count_bytes && !count_chars && !print_lines && !count_complicated)
344 bool skip_read = false;
346 if (0 < fstatus->failed)
347 fstatus->failed = fstat (fd, &fstatus->st);
349 /* For sized files, seek to one st_blksize before EOF rather than to EOF.
350 This works better for files in proc-like file systems where
351 the size is only approximate. */
352 if (! fstatus->failed && usable_st_size (&fstatus->st)
353 && 0 <= fstatus->st.st_size)
355 off_t end_pos = fstatus->st.st_size;
356 if (current_pos < 0)
357 current_pos = lseek (fd, 0, SEEK_CUR);
359 if (end_pos % page_size)
361 /* We only need special handling of /proc and /sys files etc.
362 when they're a multiple of PAGE_SIZE. In the common case
363 for files with st_size not a multiple of PAGE_SIZE,
364 it's more efficient and accurate to use st_size.
366 Be careful here. The current position may actually be
367 beyond the end of the file. As in the example above. */
369 bytes = end_pos < current_pos ? 0 : end_pos - current_pos;
370 if (bytes && 0 <= lseek (fd, bytes, SEEK_CUR))
371 skip_read = true;
372 else
373 bytes = 0;
375 else
377 off_t hi_pos = (end_pos
378 - end_pos % (STP_BLKSIZE (&fstatus->st) + 1));
379 if (0 <= current_pos && current_pos < hi_pos
380 && 0 <= lseek (fd, hi_pos, SEEK_CUR))
381 bytes = hi_pos - current_pos;
385 if (! skip_read)
387 fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
388 for (ssize_t bytes_read;
389 (bytes_read = read (fd, buf, BUFFER_SIZE));
390 bytes += bytes_read)
391 if (bytes_read < 0)
393 err = errno;
394 break;
398 else if (!count_chars && !count_complicated)
400 /* Use a separate loop when counting only lines or lines and bytes --
401 but not chars or words. */
402 struct wc_lines w = wc_lines (fd);
403 err = w.err;
404 lines = w.lines;
405 bytes = w.bytes;
407 else if (MB_CUR_MAX > 1)
409 bool in_word = false;
410 intmax_t linepos = 0;
411 mbstate_t state; mbszero (&state);
412 bool in_shift = false;
413 idx_t prev = 0; /* Number of bytes carried over from previous round. */
415 for (ssize_t bytes_read;
416 ((bytes_read = read (fd, buf + prev, BUFFER_SIZE - prev))
417 || prev);
420 if (bytes_read < 0)
422 err = errno;
423 break;
426 bytes += bytes_read;
427 char const *p = buf;
428 char const *plim = p + prev + bytes_read;
431 char32_t wide_char;
432 idx_t charbytes;
433 bool single_byte;
435 if (!in_shift && 0 <= *p && *p < 0x80)
437 /* Handle most ASCII characters quickly, without calling
438 mbrtoc32. */
439 charbytes = 1;
440 wide_char = *p;
441 single_byte = true;
443 else
445 idx_t scanbytes = plim - (p + prev);
446 size_t n = mbrtoc32 (&wide_char, p + prev, scanbytes, &state);
447 prev = 0;
449 if (scanbytes < n)
451 if (n == (size_t) -2 && plim - p < BUFFER_SIZE
452 && bytes_read)
454 /* An incomplete character that is not ridiculously
455 long and there may be more input. Move the bytes
456 to buffer start and prepare to read more data. */
457 prev = plim - p;
458 memmove (buf, p, prev);
459 in_shift = true;
460 break;
463 /* Remember that we read a byte, but don't complain
464 about the error. Because of the decoding error,
465 this is a considered to be byte but not a
466 character (that is, chars is not incremented). */
467 p++;
468 mbszero (&state);
469 in_shift = false;
471 /* Treat encoding errors as non white space.
472 POSIX says a word is "a non-zero-length string of
473 characters delimited by white space". This is
474 wrong in some sense, as the string can be delimited
475 by start or end of input, and it is unclear what it
476 means when the input contains encoding errors.
477 Since encoding errors are not white space,
478 treat them that way here. */
479 words += !in_word;
480 in_word = true;
481 continue;
484 charbytes = n + !n;
485 single_byte = charbytes == !in_shift;
486 in_shift = !mbsinit (&state);
489 switch (wide_char)
491 case '\n':
492 lines++;
493 FALLTHROUGH;
494 case '\r':
495 case '\f':
496 if (linepos > linelength)
497 linelength = linepos;
498 linepos = 0;
499 in_word = false;
500 break;
502 case '\t':
503 linepos += 8 - (linepos % 8);
504 in_word = false;
505 break;
507 case ' ':
508 linepos++;
509 FALLTHROUGH;
510 case '\v':
511 in_word = false;
512 break;
514 default:;
515 bool in_word2;
516 if (single_byte)
518 linepos += wc_isprint[wide_char];
519 in_word2 = !wc_isspace[wide_char];
521 else
523 /* c32width can be expensive on macOS for example,
524 so avoid if not needed. */
525 if (print_linelength)
527 int width = c32width (wide_char);
528 if (width > 0)
529 linepos += width;
531 in_word2 = ! iswspace (wide_char)
532 && ! iswnbspace (wide_char);
535 /* Count words by counting word starts, i.e., each
536 white space character (or the start of input)
537 followed by non white space. */
538 words += !in_word & in_word2;
539 in_word = in_word2;
540 break;
543 p += charbytes;
544 chars++;
546 while (p < plim);
548 if (linepos > linelength)
549 linelength = linepos;
551 else
553 bool in_word = false;
554 intmax_t linepos = 0;
556 for (ssize_t bytes_read; (bytes_read = read (fd, buf, BUFFER_SIZE)); )
558 if (bytes_read < 0)
560 err = errno;
561 break;
564 bytes += bytes_read;
565 char const *p = buf;
568 unsigned char c = *p++;
569 switch (c)
571 case '\n':
572 lines++;
573 FALLTHROUGH;
574 case '\r':
575 case '\f':
576 if (linepos > linelength)
577 linelength = linepos;
578 linepos = 0;
579 in_word = false;
580 break;
582 case '\t':
583 linepos += 8 - (linepos % 8);
584 in_word = false;
585 break;
587 case ' ':
588 linepos++;
589 FALLTHROUGH;
590 case '\v':
591 in_word = false;
592 break;
594 default:
595 linepos += wc_isprint[c];
596 bool in_word2 = !wc_isspace[c];
597 words += !in_word & in_word2;
598 in_word = in_word2;
599 break;
602 while (--bytes_read);
604 if (linepos > linelength)
605 linelength = linepos;
608 if (count_chars < print_chars)
609 chars = bytes;
611 if (total_mode != total_only)
612 write_counts (lines, words, chars, bytes, linelength, file_x);
614 total_lines_overflow |= ckd_add (&total_lines, total_lines, lines);
615 total_words_overflow |= ckd_add (&total_words, total_words, words);
616 total_chars_overflow |= ckd_add (&total_chars, total_chars, chars);
617 total_bytes_overflow |= ckd_add (&total_bytes, total_bytes, bytes);
619 if (linelength > max_line_length)
620 max_line_length = linelength;
622 if (err)
623 error (0, err, "%s", quotef (file));
624 return !err;
627 static bool
628 wc_file (char const *file, struct fstatus *fstatus)
630 if (! file || STREQ (file, "-"))
632 have_read_stdin = true;
633 xset_binary_mode (STDIN_FILENO, O_BINARY);
634 return wc (STDIN_FILENO, file, fstatus, -1);
636 else
638 int fd = open (file, O_RDONLY | O_BINARY);
639 if (fd == -1)
641 error (0, errno, "%s", quotef (file));
642 return false;
644 else
646 bool ok = wc (fd, file, fstatus, 0);
647 if (close (fd) != 0)
649 error (0, errno, "%s", quotef (file));
650 return false;
652 return ok;
657 /* Return the file status for the NFILES files addressed by FILE.
658 Optimize the case where only one number is printed, for just one
659 file; in that case we can use a print width of 1, so we don't need
660 to stat the file. Handle the case of (nfiles == 0) in the same way;
661 that happens when we don't know how long the list of file names will be. */
663 static struct fstatus *
664 get_input_fstatus (idx_t nfiles, char *const *file)
666 struct fstatus *fstatus = xnmalloc (nfiles ? nfiles : 1, sizeof *fstatus);
668 if (nfiles == 0
669 || (nfiles == 1
670 && ((print_lines + print_words + print_chars
671 + print_bytes + print_linelength)
672 == 1)))
673 fstatus[0].failed = 1;
674 else
676 for (idx_t i = 0; i < nfiles; i++)
677 fstatus[i].failed = (! file[i] || STREQ (file[i], "-")
678 ? fstat (STDIN_FILENO, &fstatus[i].st)
679 : stat (file[i], &fstatus[i].st));
682 return fstatus;
685 /* Return a print width suitable for the NFILES files whose status is
686 recorded in FSTATUS. Optimize the same special case that
687 get_input_fstatus optimizes. */
689 ATTRIBUTE_PURE
690 static int
691 compute_number_width (idx_t nfiles, struct fstatus const *fstatus)
693 int width = 1;
695 if (0 < nfiles && fstatus[0].failed <= 0)
697 int minimum_width = 1;
698 uintmax_t regular_total = 0;
700 for (idx_t i = 0; i < nfiles; i++)
701 if (! fstatus[i].failed)
703 if (!S_ISREG (fstatus[i].st.st_mode))
704 minimum_width = 7;
705 else if (ckd_add (&regular_total, regular_total,
706 fstatus[i].st.st_size))
708 regular_total = UINTMAX_MAX;
709 break;
713 for (; 10 <= regular_total; regular_total /= 10)
714 width++;
715 if (width < minimum_width)
716 width = minimum_width;
719 return width;
724 main (int argc, char **argv)
726 int optc;
727 idx_t nfiles;
728 char **files;
729 char *files_from = nullptr;
730 struct fstatus *fstatus;
731 struct Tokens tok;
733 initialize_main (&argc, &argv);
734 set_program_name (argv[0]);
735 setlocale (LC_ALL, "");
736 bindtextdomain (PACKAGE, LOCALEDIR);
737 textdomain (PACKAGE);
739 atexit (close_stdout);
741 page_size = getpagesize ();
742 /* Line buffer stdout to ensure lines are written atomically and immediately
743 so that processes running in parallel do not intersperse their output. */
744 setvbuf (stdout, nullptr, _IOLBF, 0);
746 posixly_correct = (getenv ("POSIXLY_CORRECT") != nullptr);
748 print_lines = print_words = print_chars = print_bytes = false;
749 print_linelength = false;
750 total_lines = total_words = total_chars = total_bytes = max_line_length = 0;
752 while ((optc = getopt_long (argc, argv, "clLmw", longopts, nullptr)) != -1)
753 switch (optc)
755 case 'c':
756 print_bytes = true;
757 break;
759 case 'm':
760 print_chars = true;
761 break;
763 case 'l':
764 print_lines = true;
765 break;
767 case 'w':
768 print_words = true;
769 break;
771 case 'L':
772 print_linelength = true;
773 break;
775 case DEBUG_PROGRAM_OPTION:
776 debug = true;
777 break;
779 case FILES0_FROM_OPTION:
780 files_from = optarg;
781 break;
783 case TOTAL_OPTION:
784 total_mode = XARGMATCH ("--total", optarg, total_args, total_types);
785 break;
787 case_GETOPT_HELP_CHAR;
789 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
791 default:
792 usage (EXIT_FAILURE);
795 if (! (print_lines || print_words || print_chars || print_bytes
796 || print_linelength))
797 print_lines = print_words = print_bytes = true;
799 if (print_linelength)
800 for (int i = 0; i <= UCHAR_MAX; i++)
801 wc_isprint[i] = !!isprint (i);
802 if (print_words)
803 for (int i = 0; i <= UCHAR_MAX; i++)
804 wc_isspace[i] = isspace (i) || iswnbspace (btoc32 (i));
806 bool read_tokens = false;
807 struct argv_iterator *ai;
808 if (files_from)
810 FILE *stream;
812 /* When using --files0-from=F, you may not specify any files
813 on the command-line. */
814 if (optind < argc)
816 error (0, 0, _("extra operand %s"), quoteaf (argv[optind]));
817 fprintf (stderr, "%s\n",
818 _("file operands cannot be combined with --files0-from"));
819 usage (EXIT_FAILURE);
822 if (STREQ (files_from, "-"))
823 stream = stdin;
824 else
826 stream = fopen (files_from, "r");
827 if (stream == nullptr)
828 error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
829 quoteaf (files_from));
832 /* Read the file list into RAM if we can detect its size and that
833 size is reasonable. Otherwise, we'll read a name at a time. */
834 struct stat st;
835 if (fstat (fileno (stream), &st) == 0
836 && S_ISREG (st.st_mode)
837 && st.st_size <= MIN (10 * 1024 * 1024, physmem_available () / 2))
839 read_tokens = true;
840 readtokens0_init (&tok);
841 if (! readtokens0 (stream, &tok) || fclose (stream) != 0)
842 error (EXIT_FAILURE, 0, _("cannot read file names from %s"),
843 quoteaf (files_from));
844 files = tok.tok;
845 nfiles = tok.n_tok;
846 ai = argv_iter_init_argv (files);
848 else
850 files = nullptr;
851 nfiles = 0;
852 ai = argv_iter_init_stream (stream);
855 else
857 static char *stdin_only[] = { nullptr };
858 files = (optind < argc ? argv + optind : stdin_only);
859 nfiles = (optind < argc ? argc - optind : 1);
860 ai = argv_iter_init_argv (files);
863 if (!ai)
864 xalloc_die ();
866 fstatus = get_input_fstatus (nfiles, files);
867 if (total_mode == total_only)
868 number_width = 1; /* No extra padding, since no alignment requirement. */
869 else
870 number_width = compute_number_width (nfiles, fstatus);
872 bool ok = true;
873 enum argv_iter_err ai_err;
874 char *file_name;
875 for (int i = 0; (file_name = argv_iter (ai, &ai_err)); i++)
877 bool skip_file = false;
878 if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-"))
880 /* Give a better diagnostic in an unusual case:
881 printf - | wc --files0-from=- */
882 error (0, 0, _("when reading file names from stdin, "
883 "no file name of %s allowed"),
884 quoteaf (file_name));
885 skip_file = true;
888 if (!file_name[0])
890 /* Diagnose a zero-length file name. When it's one
891 among many, knowing the record number may help.
892 FIXME: currently print the record number only with
893 --files0-from=FILE. Maybe do it for argv, too? */
894 if (files_from == nullptr)
895 error (0, 0, "%s", _("invalid zero-length file name"));
896 else
898 /* Using the standard 'filename:line-number:' prefix here is
899 not totally appropriate, since NUL is the separator, not NL,
900 but it might be better than nothing. */
901 error (0, 0, "%s:%zu: %s", quotef (files_from),
902 argv_iter_n_args (ai), _("invalid zero-length file name"));
904 skip_file = true;
907 if (skip_file)
908 ok = false;
909 else
910 ok &= wc_file (file_name, &fstatus[nfiles ? i : 0]);
912 if (! nfiles)
913 fstatus[0].failed = 1;
915 switch (ai_err)
917 case AI_ERR_EOF:
918 break;
920 case AI_ERR_READ:
921 error (0, errno, _("%s: read error"), quotef (files_from));
922 ok = false;
923 break;
925 case AI_ERR_MEM:
926 xalloc_die ();
928 default:
929 unreachable ();
932 /* No arguments on the command line is fine. That means read from stdin.
933 However, no arguments on the --files0-from input stream is an error
934 means don't read anything. */
935 if (ok && !files_from && argv_iter_n_args (ai) == 0)
936 ok &= wc_file (nullptr, &fstatus[0]);
938 if (read_tokens)
939 readtokens0_free (&tok);
941 if (total_mode != total_never
942 && (total_mode != total_auto || 1 < argv_iter_n_args (ai)))
944 if (total_lines_overflow)
946 total_lines = UINTMAX_MAX;
947 error (0, EOVERFLOW, _("total lines"));
948 ok = false;
950 if (total_words_overflow)
952 total_words = UINTMAX_MAX;
953 error (0, EOVERFLOW, _("total words"));
954 ok = false;
956 if (total_chars_overflow)
958 total_chars = UINTMAX_MAX;
959 error (0, EOVERFLOW, _("total characters"));
960 ok = false;
962 if (total_bytes_overflow)
964 total_bytes = UINTMAX_MAX;
965 error (0, EOVERFLOW, _("total bytes"));
966 ok = false;
969 write_counts (total_lines, total_words, total_chars, total_bytes,
970 max_line_length,
971 total_mode != total_only ? _("total") : nullptr);
974 argv_iter_free (ai);
976 free (fstatus);
978 if (have_read_stdin && close (STDIN_FILENO) != 0)
979 error (EXIT_FAILURE, errno, "-");
981 return ok ? EXIT_SUCCESS : EXIT_FAILURE;