/* cat -- concatenate files and print on the standard output.                   This is the cat utility
   Copyright (C) 1988-2018 Free Software Foundation, Inc.                       
                                                                                
   This program is free software: you can redistribute it and/or modify         
   it under the terms of the GNU General Public License as published by         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
/* Differences from the Unix cat:                                               
   * Always unbuffered, -u is ignored.                                          
   * Usually much faster than other versions of cat, the difference             
   is especially apparent when using the -v option.                             
                                                                                
   By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman.  */    
                                                                                
#include <config.h>                                                             Provides system specific information
                                                                                
#include <stdio.h>                                                              Provides standard I/O capability
#include <getopt.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
                                                                                
#if HAVE_STROPTS_H                                                              Line 30
# include <stropts.h>                                                           Line 31
#endif                                                                          Line 32
#include <sys/ioctl.h>                                                          ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "ioblksize.h"                                                          ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "fadvise.h"                                                            ...!includes auto-comment...
#include "full-write.h"                                                         ...!includes auto-comment...
#include "safe-read.h"                                                          ...!includes auto-comment...
#include "xbinary-io.h"                                                         ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "cat"                                                      Line 45
                                                                                
#define AUTHORS \                                                               Line 47
  proper_name ("Torbjorn Granlund"), \                                          Line 48
  proper_name ("Richard M. Stallman")                                           Line 49
                                                                                
/* Name of input file.  May be "-".  */                                         
static char const *infile;                                                      Line 52
                                                                                
/* Descriptor on which input file is open.  */                                  
static int input_desc;                                                          Line 55
                                                                                
/* Buffer for line numbers.                                                     
   An 11 digit counter may overflow within an hour on a P2/466,                 
   an 18 digit counter needs about 1000y */                                     
#define LINE_COUNTER_BUF_LEN 20                                                 Line 60
static char line_buf[LINE_COUNTER_BUF_LEN] =                                    Line 61
  {                                                                             
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',                                Line 63
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0',                                Line 64
    '\t', '\0'                                                                  Line 65
  };                                                                            Block 1
                                                                                
/* Position in 'line_buf' where printing starts.  This will not change          
   unless the number of lines is larger than 999999.  */                        
static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;              Line 70
                                                                                
/* Position of the first digit in 'line_buf'.  */                               
static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;              Line 73
                                                                                
/* Position of the last digit in 'line_buf'.  */                                
static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;                Line 76
                                                                                
/* Preserves the 'cat' function's local 'newlines' between invocations.  */     
static int newlines2 = 0;                                                       Line 79
                                                                                
void                                                                            Line 81
usage (int status)                                                              Line 82
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 84
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 86
    {                                                                           
      printf (_("\                                                              Line 88
Usage: %s [OPTION]... [FILE]...\n\                                              Line 89
"),                                                                             Line 90
              program_name);                                                    Line 91
      fputs (_("\                                                               Line 92
Concatenate FILE(s) to standard output.\n\                                      Line 93
"), stdout);                                                                    Line 94
                                                                                
      emit_stdin_note ();                                                       ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 98
\n\                                                                             
  -A, --show-all           equivalent to -vET\n\                                Line 100
  -b, --number-nonblank    number nonempty output lines, overrides -n\n\        Line 101
  -e                       equivalent to -vE\n\                                 Line 102
  -E, --show-ends          display $ at end of each line\n\                     Line 103
  -n, --number             number all output lines\n\                           Line 104
  -s, --squeeze-blank      suppress repeated empty output lines\n\              Line 105
"), stdout);                                                                    Line 106
      fputs (_("\                                                               Line 107
  -t                       equivalent to -vT\n\                                 Line 108
  -T, --show-tabs          display TAB characters as ^I\n\                      Line 109
  -u                       (ignored)\n\                                         Line 110
  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB\n\     Line 111
"), stdout);                                                                    Line 112
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 113
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 114
      printf (_("\                                                              Line 115
\n\                                                                             
Examples:\n\                                                                    Line 117
  %s f - g  Output f's contents, then standard input, then g's contents.\n\     Line 118
  %s        Copy standard input to standard output.\n\                          Line 119
"),                                                                             Line 120
              program_name, program_name);                                      Line 121
      emit_ancillary_info (PROGRAM_NAME);                                       Line 122
    }                                                                           
  exit (status);                                                                Line 124
}                                                                               Block 2
                                                                                
/* Compute the next line number.  */                                            
                                                                                
static void                                                                     Line 129
next_line_num (void)                                                            Line 130
{                                                                               
  char *endp = line_num_end;                                                    Line 132
  do                                                                            
    {                                                                           
      if ((*endp)++ < '9')                                                      Line 135
        return;                                                                 Line 136
      *endp-- = '0';                                                            Line 137
    }                                                                           
  while (endp >= line_num_start);                                               Line 139
  if (line_num_start > line_buf)                                                Line 140
    *--line_num_start = '1';                                                    Line 141
  else                                                                          Line 142
    *line_buf = '>';                                                            Line 143
  if (line_num_start < line_num_print)                                          Line 144
    line_num_print--;                                                           Line 145
}                                                                               Block 3
                                                                                
/* Plain cat.  Copies the file behind 'input_desc' to STDOUT_FILENO.            
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 151
simple_cat (                                                                    Line 152
     /* Pointer to the buffer, used by reads and writes.  */                    
     char *buf,                                                                 Line 154
                                                                                
     /* Number of characters preferably read or written by each read and write  
        call.  */                                                               
     size_t bufsize)                                                            Line 158
{                                                                               
  /* Actual number of characters read, and therefore written.  */               
  size_t n_read;                                                                Line 161
                                                                                
  /* Loop until the end of the file.  */                                        
                                                                                
  while (true)                                                                  Line 165
    {                                                                           
      /* Read a block of input.  */                                             
                                                                                
      n_read = safe_read (input_desc, buf, bufsize);                            Line 169...!syscalls auto-comment...
      if (n_read == SAFE_READ_ERROR)                                            Line 170
        {                                                                       
          error (0, errno, "%s", quotef (infile));                              Line 172
          return false;                                                         Line 173
        }                                                                       
                                                                                
      /* End of this file?  */                                                  
                                                                                
      if (n_read == 0)                                                          Line 178
        return true;                                                            Line 179
                                                                                
      /* Write this block out.  */                                              
                                                                                
      {                                                                         
        /* The following is ok, since we know that 0 < n_read.  */              
        size_t n = n_read;                                                      Line 185
        if (full_write (STDOUT_FILENO, buf, n) != n)                            Line 186...!syscalls auto-comment...
          die (EXIT_FAILURE, errno, _("write error"));                          Line 187
      }                                                                         
    }                                                                           
}                                                                               
                                                                                
/* Write any pending output to STDOUT_FILENO.                                   
   Pending is defined to be the *BPOUT - OUTBUF bytes starting at OUTBUF.       
   Then set *BPOUT to OUTPUT if it's not already that value.  */                
                                                                                
static inline void                                                              Line 196
write_pending (char *outbuf, char **bpout)                                      Line 197
{                                                                               
  size_t n_write = *bpout - outbuf;                                             Line 199
  if (0 < n_write)                                                              Line 200
    {                                                                           
      if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)               Line 202...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, _("write error"));                            Line 203
      *bpout = outbuf;                                                          Line 204
    }                                                                           
}                                                                               Block 5
                                                                                
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.               
   Return true if successful.                                                   
   Called if any option more than -u was specified.                             
                                                                                
   A newline character is always put at the end of the buffer, to make          
   an explicit test for buffer end unnecessary.  */                             
                                                                                
static bool                                                                     Line 215
cat (                                                                           Line 216
     /* Pointer to the beginning of the input buffer.  */                       
     char *inbuf,                                                               Line 218
                                                                                
     /* Number of characters read in each read call.  */                        
     size_t insize,                                                             Line 221
                                                                                
     /* Pointer to the beginning of the output buffer.  */                      
     char *outbuf,                                                              Line 224
                                                                                
     /* Number of characters written by each write call.  */                    
     size_t outsize,                                                            Line 227
                                                                                
     /* Variables that have values according to the specified options.  */      
     bool show_nonprinting,                                                     Line 230
     bool show_tabs,                                                            Line 231
     bool number,                                                               Line 232
     bool number_nonblank,                                                      Line 233
     bool show_ends,                                                            Line 234
     bool squeeze_blank)                                                        Line 235
{                                                                               
  /* Last character read from the input buffer.  */                             
  unsigned char ch;                                                             Line 238
                                                                                
  /* Pointer to the next character in the input buffer.  */                     
  char *bpin;                                                                   Line 241
                                                                                
  /* Pointer to the first non-valid byte in the input buffer, i.e., the         
     current end of the buffer.  */                                             
  char *eob;                                                                    Line 245
                                                                                
  /* Pointer to the position where the next character shall be written.  */     
  char *bpout;                                                                  Line 248
                                                                                
  /* Number of characters read by the last read call.  */                       
  size_t n_read;                                                                Line 251
                                                                                
  /* Determines how many consecutive newlines there have been in the            
     input.  0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,          
     etc.  Initially 0 to indicate that we are at the beginning of a            
     new line.  The "state" of the procedure is determined by                   
     NEWLINES.  */                                                              
  int newlines = newlines2;                                                     Line 258
                                                                                
#ifdef FIONREAD                                                                 Line 260
  /* If nonzero, use the FIONREAD ioctl, as an optimization.                    
     (On Ultrix, it is not supported on NFS file systems.)  */                  
  bool use_fionread = true;                                                     Line 263
#endif                                                                          Line 264
                                                                                
  /* The inbuf pointers are initialized so that BPIN > EOB, and thereby input   
     is read immediately.  */                                                   
                                                                                
  eob = inbuf;                                                                  Line 269
  bpin = eob + 1;                                                               Line 270
                                                                                
  bpout = outbuf;                                                               Line 272
                                                                                
  while (true)                                                                  Line 274
    {                                                                           
      do                                                                        
        {                                                                       
          /* Write if there are at least OUTSIZE bytes in OUTBUF.  */           
                                                                                
          if (outbuf + outsize <= bpout)                                        Line 280
            {                                                                   
              char *wp = outbuf;                                                Line 282
              size_t remaining_bytes;                                           Line 283
              do                                                                
                {                                                               
                  if (full_write (STDOUT_FILENO, wp, outsize) != outsize)       Line 286...!syscalls auto-comment...
                    die (EXIT_FAILURE, errno, _("write error"));                Line 287
                  wp += outsize;                                                Line 288
                  remaining_bytes = bpout - wp;                                 Line 289
                }                                                               
              while (outsize <= remaining_bytes);                               Line 291
                                                                                
              /* Move the remaining bytes to the beginning of the               
                 buffer.  */                                                    
                                                                                
              memmove (outbuf, wp, remaining_bytes);                            Line 296
              bpout = outbuf + remaining_bytes;                                 Line 297
            }                                                                   
                                                                                
          /* Is INBUF empty?  */                                                
                                                                                
          if (bpin > eob)                                                       Line 302
            {                                                                   
              bool input_pending = false;                                       Line 304
#ifdef FIONREAD                                                                 Line 305
              int n_to_read = 0;                                                Line 306
                                                                                
              /* Is there any input to read immediately?                        
                 If not, we are about to wait,                                  
                 so write all buffered output before waiting.  */               
                                                                                
              if (use_fionread                                                  Line 312
                  && ioctl (input_desc, FIONREAD, &n_to_read) < 0)              Line 313...!syscalls auto-comment...
                {                                                               
                  /* Ultrix returns EOPNOTSUPP on NFS;                          
                     HP-UX returns ENOTTY on pipes.                             
                     SunOS returns EINVAL and                                   
                     More/BSD returns ENODEV on special files                   
                     like /dev/null.                                            
                     Irix-5 returns ENOSYS on pipes.  */                        
                  if (errno == EOPNOTSUPP || errno == ENOTTY                    Line 321
                      || errno == EINVAL || errno == ENODEV                     Line 322
                      || errno == ENOSYS)                                       Line 323
                    use_fionread = false;                                       Line 324
                  else                                                          Line 325
                    {                                                           
                      error (0, errno, _("cannot do ioctl on %s"),              Line 327
                             quoteaf (infile));                                 Line 328
                      newlines2 = newlines;                                     Line 329
                      return false;                                             Line 330
                    }                                                           
                }                                                               
              if (n_to_read != 0)                                               Line 333
                input_pending = true;                                           Line 334
#endif                                                                          Line 335
                                                                                
              if (!input_pending)                                               Line 337
                write_pending (outbuf, &bpout);                                 Line 338
                                                                                
              /* Read more input into INBUF.  */                                
                                                                                
              n_read = safe_read (input_desc, inbuf, insize);                   Line 342...!syscalls auto-comment...
              if (n_read == SAFE_READ_ERROR)                                    Line 343
                {                                                               
                  error (0, errno, "%s", quotef (infile));                      Line 345
                  write_pending (outbuf, &bpout);                               Line 346
                  newlines2 = newlines;                                         Line 347
                  return false;                                                 Line 348
                }                                                               
              if (n_read == 0)                                                  Line 350
                {                                                               
                  write_pending (outbuf, &bpout);                               Line 352
                  newlines2 = newlines;                                         Line 353
                  return true;                                                  Line 354
                }                                                               
                                                                                
              /* Update the pointers and insert a sentinel at the buffer        
                 end.  */                                                       
                                                                                
              bpin = inbuf;                                                     Line 360
              eob = bpin + n_read;                                              Line 361
              *eob = '\n';                                                      Line 362
            }                                                                   
          else                                                                  Line 364
            {                                                                   
              /* It was a real (not a sentinel) newline.  */                    
                                                                                
              /* Was the last line empty?                                       
                 (i.e., have two or more consecutive newlines been read?)  */   
                                                                                
              if (++newlines > 0)                                               Line 371
                {                                                               
                  if (newlines >= 2)                                            Line 373
                    {                                                           
                      /* Limit this to 2 here.  Otherwise, with lots of         
                         consecutive newlines, the counter could wrap           
                         around at INT_MAX.  */                                 
                      newlines = 2;                                             Line 378
                                                                                
                      /* Are multiple adjacent empty lines to be substituted    
                         by single ditto (-s), and this was the second empty    
                         line?  */                                              
                      if (squeeze_blank)                                        Line 383
                        {                                                       
                          ch = *bpin++;                                         Line 385
                          continue;                                             Line 386
                        }                                                       
                    }                                                           
                                                                                
                  /* Are line numbers to be written at empty lines (-n)?  */    
                                                                                
                  if (number && !number_nonblank)                               Line 392
                    {                                                           
                      next_line_num ();                                         Line 394
                      bpout = stpcpy (bpout, line_num_print);                   Line 395
                    }                                                           
                }                                                               
                                                                                
              /* Output a currency symbol if requested (-e).  */                
                                                                                
              if (show_ends)                                                    Line 401
                *bpout++ = '$';                                                 Line 402
                                                                                
              /* Output the newline.  */                                        
                                                                                
              *bpout++ = '\n';                                                  Line 406
            }                                                                   
          ch = *bpin++;                                                         Line 408
        }                                                                       
      while (ch == '\n');                                                       Line 410
                                                                                
      /* Are we at the beginning of a line, and line numbers are requested?  */ 
                                                                                
      if (newlines >= 0 && number)                                              Line 414
        {                                                                       
          next_line_num ();                                                     Line 416
          bpout = stpcpy (bpout, line_num_print);                               Line 417
        }                                                                       
                                                                                
      /* Here CH cannot contain a newline character.  */                        
                                                                                
      /* The loops below continue until a newline character is found,           
         which means that the buffer is empty or that a proper newline          
         has been found.  */                                                    
                                                                                
      /* If quoting, i.e., at least one of -v, -e, or -t specified,             
         scan for chars that need conversion.  */                               
      if (show_nonprinting)                                                     Line 428
        {                                                                       
          while (true)                                                          Line 430
            {                                                                   
              if (ch >= 32)                                                     Line 432
                {                                                               
                  if (ch < 127)                                                 Line 434
                    *bpout++ = ch;                                              Line 435
                  else if (ch == 127)                                           Line 436
                    {                                                           
                      *bpout++ = '^';                                           Line 438
                      *bpout++ = '?';                                           Line 439
                    }                                                           
                  else                                                          Line 441
                    {                                                           
                      *bpout++ = 'M';                                           Line 443
                      *bpout++ = '-';                                           Line 444
                      if (ch >= 128 + 32)                                       Line 445
                        {                                                       
                          if (ch < 128 + 127)                                   Line 447
                            *bpout++ = ch - 128;                                Line 448
                          else                                                  Line 449
                            {                                                   
                              *bpout++ = '^';                                   Line 451
                              *bpout++ = '?';                                   Line 452
                            }                                                   
                        }                                                       
                      else                                                      Line 455
                        {                                                       
                          *bpout++ = '^';                                       Line 457
                          *bpout++ = ch - 128 + 64;                             Line 458
                        }                                                       
                    }                                                           
                }                                                               
              else if (ch == '\t' && !show_tabs)                                Line 462
                *bpout++ = '\t';                                                Line 463
              else if (ch == '\n')                                              Line 464
                {                                                               
                  newlines = -1;                                                Line 466
                  break;                                                        Line 467
                }                                                               
              else                                                              Line 469
                {                                                               
                  *bpout++ = '^';                                               Line 471
                  *bpout++ = ch + 64;                                           Line 472
                }                                                               
                                                                                
              ch = *bpin++;                                                     Line 475
            }                                                                   
        }                                                                       
      else                                                                      Line 478
        {                                                                       
          /* Not quoting, neither of -v, -e, or -t specified.  */               
          while (true)                                                          Line 481
            {                                                                   
              if (ch == '\t' && show_tabs)                                      Line 483
                {                                                               
                  *bpout++ = '^';                                               Line 485
                  *bpout++ = ch + 64;                                           Line 486
                }                                                               
              else if (ch != '\n')                                              Line 488
                *bpout++ = ch;                                                  Line 489
              else                                                              Line 490
                {                                                               
                  newlines = -1;                                                Line 492
                  break;                                                        Line 493
                }                                                               
                                                                                
              ch = *bpin++;                                                     Line 496
            }                                                                   
        }                                                                       
    }                                                                           
}                                                                               
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 503
{                                                                               
  /* Optimal size of i/o operations of output.  */                              
  size_t outsize;                                                               Line 506
                                                                                
  /* Optimal size of i/o operations of input.  */                               
  size_t insize;                                                                Line 509
                                                                                
  size_t page_size = getpagesize ();                                            Line 511
                                                                                
  /* Pointer to the input buffer.  */                                           
  char *inbuf;                                                                  Line 514
                                                                                
  /* Pointer to the output buffer.  */                                          
  char *outbuf;                                                                 Line 517
                                                                                
  bool ok = true;                                                               Line 519
  int c;                                                                        Line 520
                                                                                
  /* Index in argv to processed argument.  */                                   
  int argind;                                                                   Line 523
                                                                                
  /* Device number of the output (file or whatever).  */                        
  dev_t out_dev;                                                                Line 526
                                                                                
  /* I-node number of the output.  */                                           
  ino_t out_ino;                                                                Line 529
                                                                                
  /* True if the output is a regular file.  */                                  
  bool out_isreg;                                                               Line 532
                                                                                
  /* Nonzero if we have ever read standard input.  */                           
  bool have_read_stdin = false;                                                 Line 535
                                                                                
  struct stat stat_buf;                                                         Line 537
                                                                                
  /* Variables that are set according to the specified options.  */             
  bool number = false;                                                          Line 540
  bool number_nonblank = false;                                                 Line 541
  bool squeeze_blank = false;                                                   Line 542
  bool show_ends = false;                                                       Line 543
  bool show_nonprinting = false;                                                Line 544
  bool show_tabs = false;                                                       Line 545
  int file_open_mode = O_RDONLY;                                                Line 546
                                                                                
  static struct option const long_options[] =                                   Line 548
  {                                                                             
    {"number-nonblank", no_argument, NULL, 'b'},                                Line 550
    {"number", no_argument, NULL, 'n'},                                         Line 551
    {"squeeze-blank", no_argument, NULL, 's'},                                  Line 552
    {"show-nonprinting", no_argument, NULL, 'v'},                               Line 553
    {"show-ends", no_argument, NULL, 'E'},                                      Line 554
    {"show-tabs", no_argument, NULL, 'T'},                                      Line 555
    {"show-all", no_argument, NULL, 'A'},                                       Line 556
    {GETOPT_HELP_OPTION_DECL},                                                  Line 557
    {GETOPT_VERSION_OPTION_DECL},                                               Line 558
    {NULL, 0, NULL, 0}                                                          Line 559
  };                                                                            
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  /* Arrange to close stdout if we exit via the                                 
     case_GETOPT_HELP_CHAR or case_GETOPT_VERSION_CHAR code.                    
     Normally STDOUT_FILENO is used rather than stdout, so                      
     close_stdout does nothing.  */                                             
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  /* Parse command line options.  */                                            
                                                                                
  while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))       Line 576
         != -1)                                                                 Line 577
    {                                                                           
      switch (c)                                                                Line 579
        {                                                                       
        case 'b':                                                               Line 581
          number = true;                                                        Line 582
          number_nonblank = true;                                               Line 583
          break;                                                                Line 584
                                                                                
        case 'e':                                                               Line 586
          show_ends = true;                                                     Line 587
          show_nonprinting = true;                                              Line 588
          break;                                                                Line 589
                                                                                
        case 'n':                                                               Line 591
          number = true;                                                        Line 592
          break;                                                                Line 593
                                                                                
        case 's':                                                               Line 595
          squeeze_blank = true;                                                 Line 596
          break;                                                                Line 597
                                                                                
        case 't':                                                               Line 599
          show_tabs = true;                                                     Line 600
          show_nonprinting = true;                                              Line 601
          break;                                                                Line 602
                                                                                
        case 'u':                                                               Line 604
          /* We provide the -u feature unconditionally.  */                     
          break;                                                                Line 606
                                                                                
        case 'v':                                                               Line 608
          show_nonprinting = true;                                              Line 609
          break;                                                                Line 610
                                                                                
        case 'A':                                                               Line 612
          show_nonprinting = true;                                              Line 613
          show_ends = true;                                                     Line 614
          show_tabs = true;                                                     Line 615
          break;                                                                Line 616
                                                                                
        case 'E':                                                               Line 618
          show_ends = true;                                                     Line 619
          break;                                                                Line 620
                                                                                
        case 'T':                                                               Line 622
          show_tabs = true;                                                     Line 623
          break;                                                                Line 624
                                                                                
        case_GETOPT_HELP_CHAR;                                                  Line 626
                                                                                
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 628
                                                                                
        default:                                                                Line 630
          usage (EXIT_FAILURE);                                                 Line 631
        }                                                                       
    }                                                                           
                                                                                
  /* Get device, i-node number, and optimal blocksize of output.  */            
                                                                                
  if (fstat (STDOUT_FILENO, &stat_buf) < 0)                                     Line 637...!syscalls auto-comment......!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("standard output"));                            Line 638
                                                                                
  outsize = io_blksize (stat_buf);                                              Line 640
  out_dev = stat_buf.st_dev;                                                    Line 641
  out_ino = stat_buf.st_ino;                                                    Line 642
  out_isreg = S_ISREG (stat_buf.st_mode) != 0;                                  Line 643
                                                                                
  if (! (number || show_ends || squeeze_blank))                                 Line 645
    {                                                                           
      file_open_mode |= O_BINARY;                                               Line 647
      xset_binary_mode (STDOUT_FILENO, O_BINARY);                               Line 648
    }                                                                           
                                                                                
  /* Check if any of the input files are the same as the output file.  */       
                                                                                
  /* Main loop.  */                                                             
                                                                                
  infile = "-";                                                                 Line 655
  argind = optind;                                                              Line 656
                                                                                
  do                                                                            
    {                                                                           
      if (argind < argc)                                                        Line 660
        infile = argv[argind];                                                  Line 661
                                                                                
      if (STREQ (infile, "-"))                                                  Line 663
        {                                                                       
          have_read_stdin = true;                                               Line 665
          input_desc = STDIN_FILENO;                                            Line 666
          if (file_open_mode & O_BINARY)                                        Line 667
            xset_binary_mode (STDIN_FILENO, O_BINARY);                          Line 668
        }                                                                       
      else                                                                      Line 670
        {                                                                       
          input_desc = open (infile, file_open_mode);                           Line 672...!syscalls auto-comment...
          if (input_desc < 0)                                                   Line 673
            {                                                                   
              error (0, errno, "%s", quotef (infile));                          Line 675
              ok = false;                                                       Line 676
              continue;                                                         Line 677
            }                                                                   
        }                                                                       
                                                                                
      if (fstat (input_desc, &stat_buf) < 0)                                    Line 681...!syscalls auto-comment......!syscalls auto-comment...
        {                                                                       
          error (0, errno, "%s", quotef (infile));                              Line 683
          ok = false;                                                           Line 684
          goto contin;                                                          Line 685
        }                                                                       
      insize = io_blksize (stat_buf);                                           Line 687
                                                                                
      fdadvise (input_desc, 0, 0, FADVISE_SEQUENTIAL);                          Line 689
                                                                                
      /* Don't copy a nonempty regular file to itself, as that would            
         merely exhaust the output device.  It's better to catch this           
         error earlier rather than later.  */                                   
                                                                                
      if (out_isreg                                                             Line 695
          && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino           Line 696
          && lseek (input_desc, 0, SEEK_CUR) < stat_buf.st_size)                Line 697
        {                                                                       
          error (0, 0, _("%s: input file is output file"), quotef (infile));    Line 699
          ok = false;                                                           Line 700
          goto contin;                                                          Line 701
        }                                                                       
                                                                                
      /* Select which version of 'cat' to use.  If any format-oriented          
         options were given use 'cat'; otherwise use 'simple_cat'.  */          
                                                                                
      if (! (number || show_ends || show_nonprinting                            Line 707
             || show_tabs || squeeze_blank))                                    Line 708
        {                                                                       
          insize = MAX (insize, outsize);                                       Line 710
          inbuf = xmalloc (insize + page_size - 1);                             Line 711
                                                                                
          ok &= simple_cat (ptr_align (inbuf, page_size), insize);              Line 713
        }                                                                       
      else                                                                      Line 715
        {                                                                       
          inbuf = xmalloc (insize + 1 + page_size - 1);                         Line 717
                                                                                
          /* Why are                                                            
             (OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)  
             bytes allocated for the output buffer?                             
                                                                                
             A test whether output needs to be written is done when the input   
             buffer empties or when a newline appears in the input.  After      
             output is written, at most (OUTSIZE - 1) bytes will remain in the  
             buffer.  Now INSIZE bytes of input is read.  Each input character  
             may grow by a factor of 4 (by the prepending of M-^).  If all      
             characters do, and no newlines appear in this block of input, we   
             will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.  
             If the last character in the preceding block of input was a        
             newline, a line number may be written (according to the given      
             options) as the first thing in the output buffer. (Done after the  
             new input is read, but before processing of the input begins.)     
             A line number requires seldom more than LINE_COUNTER_BUF_LEN       
             positions.                                                         
                                                                                
             Align the output buffer to a page size boundary, for efficiency    
             on some paging implementations, so add PAGE_SIZE - 1 bytes to the  
             request to make room for the alignment.  */                        
                                                                                
          outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN     Line 741
                            + page_size - 1);                                   Line 742
                                                                                
          ok &= cat (ptr_align (inbuf, page_size), insize,                      Line 744
                     ptr_align (outbuf, page_size), outsize, show_nonprinting,  Line 745
                     show_tabs, number, number_nonblank, show_ends,             Line 746
                     squeeze_blank);                                            Line 747
                                                                                
          free (outbuf);                                                        Line 749
        }                                                                       
                                                                                
      free (inbuf);                                                             Line 752
                                                                                
    contin:                                                                     Line 754
      if (!STREQ (infile, "-") && close (input_desc) < 0)                       Line 755...!syscalls auto-comment...
        {                                                                       
          error (0, errno, "%s", quotef (infile));                              Line 757
          ok = false;                                                           Line 758
        }                                                                       
    }                                                                           
  while (++argind < argc);                                                      Line 761
                                                                                
  if (have_read_stdin && close (STDIN_FILENO) < 0)                              Line 763...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("closing standard input"));                     Line 764
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 766
}