9d96e407297f0efb12b2b5e107ba00d639a6dfaa
[platform/upstream/coreutils.git] / src / cat.c
1 /* cat -- concatenate files and print on the standard output.
2    Copyright (C) 88, 90, 91, 1995-2001 Free Software Foundation, Inc.
3
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 2, or (at your option)
7    any later version.
8
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.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Differences from the Unix cat:
19    * Always unbuffered, -u is ignored.
20    * Usually much faster than other versions of cat, the difference
21    is especially apparent when using the -v option.
22
23    By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman. */
24
25 #include <config.h>
26
27 #include <stdio.h>
28 #include <getopt.h>
29 #include <sys/types.h>
30 #ifndef _POSIX_SOURCE
31 # include <sys/ioctl.h>
32 #endif
33 #include "system.h"
34 #include "closeout.h"
35 #include "error.h"
36 #include "full-write.h"
37 #include "safe-read.h"
38
39 /* The official name of this program (e.g., no `g' prefix).  */
40 #define PROGRAM_NAME "cat"
41
42 #define AUTHORS N_ ("Torbjorn Granlund and Richard M. Stallman")
43
44 /* Undefine, to avoid warning about redefinition on some systems.  */
45 #undef max
46 #define max(h,i) ((h) > (i) ? (h) : (i))
47
48 /* Name under which this program was invoked.  */
49 char *program_name;
50
51 /* Name of input file.  May be "-".  */
52 static char *infile;
53
54 /* Descriptor on which input file is open.  */
55 static int input_desc;
56
57 /* Buffer for line numbers.
58    An 11 digit counter may overflow within an hour on a P2/466,
59    an 18 digit counter needs about 1000y */
60 #define LINE_COUNTER_BUF_LEN 20
61 static char line_buf[LINE_COUNTER_BUF_LEN] =
62   {
63     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
64     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0',
65     '\t', '\0'
66   };
67
68 /* Position in `line_buf' where printing starts.  This will not change
69    unless the number of lines is larger than 999999.  */
70 static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;
71
72 /* Position of the first digit in `line_buf'.  */
73 static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;
74
75 /* Position of the last digit in `line_buf'.  */
76 static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;
77
78 /* Preserves the `cat' function's local `newlines' between invocations.  */
79 static int newlines2 = 0;
80
81 /* Count of non-fatal error conditions.  */
82 static int exit_status = 0;
83
84 void
85 usage (int status)
86 {
87   if (status != 0)
88     fprintf (stderr, _("Try `%s --help' for more information.\n"),
89              program_name);
90   else
91     {
92       printf (_("\
93 Usage: %s [OPTION] [FILE]...\n\
94 "),
95               program_name);
96       fputs (_("\
97 Concatenate FILE(s), or standard input, to standard output.\n\
98 \n\
99   -A, --show-all           equivalent to -vET\n\
100   -b, --number-nonblank    number nonblank output lines\n\
101   -e                       equivalent to -vE\n\
102   -E, --show-ends          display $ at end of each line\n\
103   -n, --number             number all output lines\n\
104   -s, --squeeze-blank      never more than one single blank line\n\
105 "), stdout);
106       fputs (_("\
107   -t                       equivalent to -vT\n\
108   -T, --show-tabs          display TAB characters as ^I\n\
109   -u                       (ignored)\n\
110   -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB\n\
111       --help               display this help and exit\n\
112       --version            output version information and exit\n\
113 \n\
114 With no FILE, or when FILE is -, read standard input.\n\
115 "), stdout);
116 #if O_BINARY
117       fputs (_("\
118 \n\
119   -B, --binary             use binary writes to the console device.\n\n\
120 "), stdout);
121 #endif
122       puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
123     }
124   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
125 }
126
127 /* Compute the next line number.  */
128
129 static void
130 next_line_num (void)
131 {
132   char *endp = line_num_end;
133   do
134     {
135       if ((*endp)++ < '9')
136         return;
137       *endp-- = '0';
138     }
139   while (endp >= line_num_start);
140   if (line_num_start > line_buf)
141     *--line_num_start = '1';
142   else
143     *line_buf = '>';
144   if (line_num_start < line_num_print)
145     line_num_print--;
146 }
147
148 /* Plain cat.  Copies the file behind `input_desc' to STDOUT_FILENO.  */
149
150 static void
151 simple_cat (
152      /* Pointer to the buffer, used by reads and writes.  */
153      unsigned char *buf,
154
155      /* Number of characters preferably read or written by each read and write
156         call.  */
157      int bufsize)
158 {
159   /* Actual number of characters read, and therefore written.  */
160   ssize_t n_read;
161
162   /* Loop until the end of the file.  */
163
164   for (;;)
165     {
166       /* Read a block of input.  */
167
168       n_read = safe_read (input_desc, buf, bufsize);
169       if (n_read < 0)
170         {
171           error (0, errno, "%s", infile);
172           exit_status = 1;
173           return;
174         }
175
176       /* End of this file?  */
177
178       if (n_read == 0)
179         break;
180
181       /* Write this block out.  */
182
183       if (full_write (STDOUT_FILENO, buf, n_read) != n_read)
184         error (EXIT_FAILURE, errno, _("write error"));
185     }
186 }
187
188 /* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
189    Called if any option more than -u was specified.
190
191    A newline character is always put at the end of the buffer, to make
192    an explicit test for buffer end unnecessary.  */
193
194 static void
195 cat (
196      /* Pointer to the beginning of the input buffer.  */
197      unsigned char *inbuf,
198
199      /* Number of characters read in each read call.  */
200      int insize,
201
202      /* Pointer to the beginning of the output buffer.  */
203      unsigned char *outbuf,
204
205      /* Number of characters written by each write call.  */
206      int outsize,
207
208      /* Variables that have values according to the specified options.  */
209      int quote,
210      int output_tabs,
211      int numbers,
212      int numbers_at_empty_lines,
213      int mark_line_ends,
214      int squeeze_empty_lines)
215 {
216   /* Last character read from the input buffer.  */
217   unsigned char ch;
218
219   /* Pointer to the next character in the input buffer.  */
220   unsigned char *bpin;
221
222   /* Pointer to the first non-valid byte in the input buffer, i.e. the
223      current end of the buffer.  */
224   unsigned char *eob;
225
226   /* Pointer to the position where the next character shall be written.  */
227   unsigned char *bpout;
228
229   /* Number of characters read by the last read call.  */
230   ssize_t n_read;
231
232   /* Determines how many consecutive newlines there have been in the
233      input.  0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
234      etc.  Initially 0 to indicate that we are at the beginning of a
235      new line.  The "state" of the procedure is determined by
236      NEWLINES.  */
237   int newlines = newlines2;
238
239 #ifdef FIONREAD
240   /* If nonzero, use the FIONREAD ioctl, as an optimization.
241      (On Ultrix, it is not supported on NFS filesystems.)  */
242   int use_fionread = 1;
243 #endif
244
245   /* The inbuf pointers are initialized so that BPIN > EOB, and thereby input
246      is read immediately.  */
247
248   eob = inbuf;
249   bpin = eob + 1;
250
251   bpout = outbuf;
252
253   for (;;)
254     {
255       do
256         {
257           /* Write if there are at least OUTSIZE bytes in OUTBUF.  */
258
259           if (bpout - outbuf >= outsize)
260             {
261               unsigned char *wp = outbuf;
262               do
263                 {
264                   if (full_write (STDOUT_FILENO, wp, outsize) < 0)
265                     error (EXIT_FAILURE, errno, _("write error"));
266                   wp += outsize;
267                 }
268               while (bpout - wp >= outsize);
269
270               /* Move the remaining bytes to the beginning of the
271                  buffer.  */
272
273               memmove (outbuf, wp, bpout - wp);
274               bpout = outbuf + (bpout - wp);
275             }
276
277           /* Is INBUF empty?  */
278
279           if (bpin > eob)
280             {
281 #ifdef FIONREAD
282               int n_to_read = 0;
283
284               /* Is there any input to read immediately?
285                  If not, we are about to wait,
286                  so write all buffered output before waiting.  */
287
288               if (use_fionread
289                   && ioctl (input_desc, FIONREAD, &n_to_read) < 0)
290                 {
291                   /* Ultrix returns EOPNOTSUPP on NFS;
292                      HP-UX returns ENOTTY on pipes.
293                      SunOS returns EINVAL and
294                      More/BSD returns ENODEV on special files
295                      like /dev/null.
296                      Irix-5 returns ENOSYS on pipes.  */
297                   if (errno == EOPNOTSUPP || errno == ENOTTY
298                       || errno == EINVAL || errno == ENODEV
299 # ifdef ENOSYS
300                       || errno == ENOSYS
301 # endif
302                       )
303                     use_fionread = 0;
304                   else
305                     {
306                       error (0, errno, _("cannot do ioctl on `%s'"), infile);
307                       exit_status = 1;
308                       newlines2 = newlines;
309                       return;
310                     }
311                 }
312               if (n_to_read == 0)
313 #endif
314                 {
315                   int n_write = bpout - outbuf;
316
317                   if (full_write (STDOUT_FILENO, outbuf, n_write) < 0)
318                     error (EXIT_FAILURE, errno, _("write error"));
319                   bpout = outbuf;
320                 }
321
322               /* Read more input into INBUF.  */
323
324               n_read = safe_read (input_desc, inbuf, insize);
325               if (n_read < 0)
326                 {
327                   error (0, errno, "%s", infile);
328                   exit_status = 1;
329                   newlines2 = newlines;
330                   return;
331                 }
332               if (n_read == 0)
333                 {
334                   newlines2 = newlines;
335                   return;
336                 }
337
338               /* Update the pointers and insert a sentinel at the buffer
339                  end.  */
340
341               bpin = inbuf;
342               eob = bpin + n_read;
343               *eob = '\n';
344             }
345           else
346             {
347               /* It was a real (not a sentinel) newline.  */
348
349               /* Was the last line empty?
350                  (i.e. have two or more consecutive newlines been read?)  */
351
352               if (++newlines > 0)
353                 {
354                   if (newlines >= 2)
355                     {
356                       /* Limit this to 2 here.  Otherwise, with lots of
357                          consecutive newlines, the counter could wrap
358                          around at INT_MAX.  */
359                       newlines = 2;
360
361                       /* Are multiple adjacent empty lines to be substituted
362                          by single ditto (-s), and this was the second empty
363                          line?  */
364                       if (squeeze_empty_lines)
365                         {
366                           ch = *bpin++;
367                           continue;
368                         }
369                     }
370
371                   /* Are line numbers to be written at empty lines (-n)?  */
372
373                   if (numbers && numbers_at_empty_lines)
374                     {
375                       next_line_num ();
376                       bpout = (unsigned char *) stpcpy ((char *) bpout,
377                                                         line_num_print);
378                     }
379                 }
380
381               /* Output a currency symbol if requested (-e).  */
382
383               if (mark_line_ends)
384                 *bpout++ = '$';
385
386               /* Output the newline.  */
387
388               *bpout++ = '\n';
389             }
390           ch = *bpin++;
391         }
392       while (ch == '\n');
393
394       /* Are we at the beginning of a line, and line numbers are requested?  */
395
396       if (newlines >= 0 && numbers)
397         {
398           next_line_num ();
399           bpout = (unsigned char *) stpcpy ((char *) bpout, line_num_print);
400         }
401
402       /* Here CH cannot contain a newline character.  */
403
404       /* The loops below continue until a newline character is found,
405          which means that the buffer is empty or that a proper newline
406          has been found.  */
407
408       /* If quoting, i.e. at least one of -v, -e, or -t specified,
409          scan for chars that need conversion.  */
410       if (quote)
411         {
412           for (;;)
413             {
414               if (ch >= 32)
415                 {
416                   if (ch < 127)
417                     *bpout++ = ch;
418                   else if (ch == 127)
419                     {
420                       *bpout++ = '^';
421                       *bpout++ = '?';
422                     }
423                   else
424                     {
425                       *bpout++ = 'M';
426                       *bpout++ = '-';
427                       if (ch >= 128 + 32)
428                         {
429                           if (ch < 128 + 127)
430                             *bpout++ = ch - 128;
431                           else
432                             {
433                               *bpout++ = '^';
434                               *bpout++ = '?';
435                             }
436                         }
437                       else
438                         {
439                           *bpout++ = '^';
440                           *bpout++ = ch - 128 + 64;
441                         }
442                     }
443                 }
444               else if (ch == '\t' && output_tabs)
445                 *bpout++ = '\t';
446               else if (ch == '\n')
447                 {
448                   newlines = -1;
449                   break;
450                 }
451               else
452                 {
453                   *bpout++ = '^';
454                   *bpout++ = ch + 64;
455                 }
456
457               ch = *bpin++;
458             }
459         }
460       else
461         {
462           /* Not quoting, neither of -v, -e, or -t specified.  */
463           for (;;)
464             {
465               if (ch == '\t' && !output_tabs)
466                 {
467                   *bpout++ = '^';
468                   *bpout++ = ch + 64;
469                 }
470               else if (ch != '\n')
471                 *bpout++ = ch;
472               else
473                 {
474                   newlines = -1;
475                   break;
476                 }
477
478               ch = *bpin++;
479             }
480         }
481     }
482 }
483
484 int
485 main (int argc, char **argv)
486 {
487   /* Optimal size of i/o operations of output.  */
488   int outsize;
489
490   /* Optimal size of i/o operations of input.  */
491   int insize;
492
493   /* Pointer to the input buffer.  */
494   unsigned char *inbuf;
495
496   /* Pointer to the output buffer.  */
497   unsigned char *outbuf;
498
499   int c;
500
501   /* Index in argv to processed argument.  */
502   int argind;
503
504   /* Device number of the output (file or whatever).  */
505   dev_t out_dev;
506
507   /* I-node number of the output.  */
508   ino_t out_ino;
509
510   /* Nonzero if the output file should not be the same as any input file. */
511   int check_redirection = 1;
512
513   /* Nonzero if we have ever read standard input. */
514   int have_read_stdin = 0;
515
516   struct stat stat_buf;
517
518   /* Variables that are set according to the specified options.  */
519   int numbers = 0;
520   int numbers_at_empty_lines = 1;
521   int squeeze_empty_lines = 0;
522   int mark_line_ends = 0;
523   int quote = 0;
524   int output_tabs = 1;
525 #if O_BINARY
526   int binary_files  = 0;
527   int binary_output = 0;
528 #endif
529   int file_open_mode = O_RDONLY;
530
531 /* If nonzero, call cat, otherwise call simple_cat to do the actual work. */
532   int options = 0;
533
534   static struct option const long_options[] =
535   {
536     {"number-nonblank", no_argument, NULL, 'b'},
537     {"number", no_argument, NULL, 'n'},
538     {"squeeze-blank", no_argument, NULL, 's'},
539     {"show-nonprinting", no_argument, NULL, 'v'},
540     {"show-ends", no_argument, NULL, 'E'},
541     {"show-tabs", no_argument, NULL, 'T'},
542     {"show-all", no_argument, NULL, 'A'},
543 #if O_BINARY
544     {"binary", no_argument, NULL, 'B'},
545 #endif
546     {GETOPT_HELP_OPTION_DECL},
547     {GETOPT_VERSION_OPTION_DECL},
548     {NULL, 0, NULL, 0}
549   };
550
551   program_name = argv[0];
552   setlocale (LC_ALL, "");
553   bindtextdomain (PACKAGE, LOCALEDIR);
554   textdomain (PACKAGE);
555
556   atexit (close_stdout);
557
558   /* Parse command line options.  */
559
560   while ((c = getopt_long (argc, argv,
561 #if O_BINARY
562                            "benstuvABET"
563 #else
564                            "benstuvAET"
565 #endif
566                            , long_options, NULL)) != -1)
567     {
568       switch (c)
569         {
570         case 0:
571           break;
572
573         case 'b':
574           ++options;
575           numbers = 1;
576           numbers_at_empty_lines = 0;
577           break;
578
579         case 'e':
580           ++options;
581           mark_line_ends = 1;
582           quote = 1;
583           break;
584
585         case 'n':
586           ++options;
587           numbers = 1;
588           break;
589
590         case 's':
591           ++options;
592           squeeze_empty_lines = 1;
593           break;
594
595         case 't':
596           ++options;
597           output_tabs = 0;
598           quote = 1;
599           break;
600
601         case 'u':
602           /* We provide the -u feature unconditionally.  */
603           break;
604
605         case 'v':
606           ++options;
607           quote = 1;
608           break;
609
610         case 'A':
611           ++options;
612           quote = 1;
613           mark_line_ends = 1;
614           output_tabs = 0;
615           break;
616
617 #if O_BINARY
618         case 'B':
619           ++options;
620           binary_files = 1;
621           break;
622 #endif
623
624         case 'E':
625           ++options;
626           mark_line_ends = 1;
627           break;
628
629         case 'T':
630           ++options;
631           output_tabs = 0;
632           break;
633
634         case_GETOPT_HELP_CHAR;
635
636         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
637
638         default:
639           usage (EXIT_FAILURE);
640         }
641     }
642
643   /* Get device, i-node number, and optimal blocksize of output.  */
644
645   if (fstat (STDOUT_FILENO, &stat_buf) < 0)
646     error (EXIT_FAILURE, errno, _("standard output"));
647
648   outsize = ST_BLKSIZE (stat_buf);
649   /* Input file can be output file for non-regular files.
650      fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
651      on others, so the checking should not be done for those types,
652      and to allow things like cat < /dev/tty > /dev/tty, checking
653      is not done for device files either. */
654
655   if (S_ISREG (stat_buf.st_mode))
656     {
657       out_dev = stat_buf.st_dev;
658       out_ino = stat_buf.st_ino;
659     }
660   else
661     {
662       check_redirection = 0;
663 #ifdef lint  /* Suppress `used before initialized' warning.  */
664       out_dev = 0;
665       out_ino = 0;
666 #endif
667     }
668
669 #if O_BINARY
670   /* We always read and write in BINARY mode, since this is the
671      best way to copy the files verbatim.  Exceptions are when
672      they request line numbering, squeezing of empty lines or
673      marking lines' ends: then we use text I/O, because otherwise
674      -b, -s and -E would surprise users on DOS/Windows where a line
675      with only CR-LF is an empty line.  (Besides, if they ask for
676      one of these options, they don't care much about the original
677      file contents anyway).  */
678   if ((!isatty (STDOUT_FILENO)
679        && !(numbers || squeeze_empty_lines || mark_line_ends))
680       || binary_files)
681     {
682       /* Switch stdout to BINARY mode.  */
683       binary_output = 1;
684       SET_BINARY (STDOUT_FILENO);
685       /* When stdout is in binary mode, make sure all input files are
686          also read in binary mode.  */
687       file_open_mode |= O_BINARY;
688     }
689   else if (quote)
690     {
691       /* If they want to see the non-printables, let's show them
692          those CR characters as well, so make the input binary.
693          But keep console output in text mode, so that LF causes
694          both CR and LF on output, and the output is readable.  */
695       file_open_mode |= O_BINARY;
696       SET_BINARY (0);
697
698       /* Setting stdin to binary switches the console device to
699          raw I/O, which also affects stdout to console.  Undo that.  */
700       if (isatty (STDOUT_FILENO))
701         setmode (STDOUT_FILENO, O_TEXT);
702     }
703 #endif
704
705   /* Check if any of the input files are the same as the output file.  */
706
707   /* Main loop.  */
708
709   infile = "-";
710   argind = optind;
711
712   do
713     {
714       if (argind < argc)
715         infile = argv[argind];
716
717       if (infile[0] == '-' && infile[1] == 0)
718         {
719           have_read_stdin = 1;
720           input_desc = 0;
721
722 #if O_BINARY
723           /* Switch stdin to BINARY mode if needed.  */
724           if (binary_output)
725             {
726               int tty_in = isatty (input_desc);
727
728               /* If stdin is a terminal device, and it is the ONLY
729                  input file (i.e. we didn't write anything to the
730                  output yet), switch the output back to TEXT mode.
731                  This is so "cat > xyzzy" creates a DOS-style text
732                  file, like people expect.  */
733               if (tty_in && optind <= argc)
734                 setmode (STDOUT_FILENO, O_TEXT);
735               else
736                 {
737                   SET_BINARY (input_desc);
738 # ifdef __DJGPP__
739                   /* This is DJGPP-specific.  By default, switching console
740                      to binary mode disables SIGINT.  But we want terminal
741                      reads to be interruptible.  */
742                   if (tty_in)
743                     __djgpp_set_ctrl_c (1);
744 # endif
745                 }
746             }
747 #endif
748         }
749       else
750         {
751           input_desc = open (infile, file_open_mode);
752           if (input_desc < 0)
753             {
754               error (0, errno, "%s", infile);
755               exit_status = 1;
756               continue;
757             }
758         }
759
760       if (fstat (input_desc, &stat_buf) < 0)
761         {
762           error (0, errno, "%s", infile);
763           exit_status = 1;
764           goto contin;
765         }
766       insize = ST_BLKSIZE (stat_buf);
767
768       /* Compare the device and i-node numbers of this input file with
769          the corresponding values of the (output file associated with)
770          stdout, and skip this input file if they coincide.  Input
771          files cannot be redirected to themselves.  */
772
773       if (check_redirection
774           && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
775           && (input_desc != STDIN_FILENO))
776         {
777           error (0, 0, _("%s: input file is output file"), infile);
778           exit_status = 1;
779           goto contin;
780         }
781
782       /* Select which version of `cat' to use. If any options (more than -u,
783          --version, or --help) were specified, use `cat', otherwise use
784          `simple_cat'.  */
785
786       if (options == 0)
787         {
788           insize = max (insize, outsize);
789           inbuf = (unsigned char *) xmalloc (insize);
790
791           simple_cat (inbuf, insize);
792         }
793       else
794         {
795           inbuf = (unsigned char *) xmalloc (insize + 1);
796
797           /* Why are (OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN)
798              bytes allocated for the output buffer?
799
800              A test whether output needs to be written is done when the input
801              buffer empties or when a newline appears in the input.  After
802              output is written, at most (OUTSIZE - 1) bytes will remain in the
803              buffer.  Now INSIZE bytes of input is read.  Each input character
804              may grow by a factor of 4 (by the prepending of M-^).  If all
805              characters do, and no newlines appear in this block of input, we
806              will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
807              If the last character in the preceding block of input was a
808              newline, a line number may be written (according to the given
809              options) as the first thing in the output buffer. (Done after the
810              new input is read, but before processing of the input begins.)
811              A line number requires seldom more than LINE_COUNTER_BUF_LEN
812              positions.  */
813
814           outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4
815                                               + LINE_COUNTER_BUF_LEN);
816
817           cat (inbuf, insize, outbuf, outsize, quote,
818                output_tabs, numbers, numbers_at_empty_lines, mark_line_ends,
819                squeeze_empty_lines);
820
821           free (outbuf);
822         }
823
824       free (inbuf);
825
826     contin:
827       if (!STREQ (infile, "-") && close (input_desc) < 0)
828         {
829           error (0, errno, "%s", infile);
830           exit_status = 1;
831         }
832     }
833   while (++argind < argc);
834
835   if (have_read_stdin && close (0) < 0)
836     error (EXIT_FAILURE, errno, "-");
837
838   exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
839 }