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