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