/* split.c -- split a file into pieces.                                         This is the split 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
                                                                                
/* By tege@sics.se, with rms.                                                   
                                                                                
   TODO:                                                                        
   * support -p REGEX as in BSD's split.                                        
   * support --suppress-matched as in csplit.  */                               
#include <config.h>                                                             Provides system specific information
                                                                                
#include <assert.h>                                                             ...!includes auto-comment...
#include <stdio.h>                                                              Provides standard I/O capability
#include <getopt.h>                                                             ...!includes auto-comment...
#include <signal.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
#include <sys/wait.h>                                                           ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "fd-reopen.h"                                                          ...!includes auto-comment...
#include "fcntl--.h"                                                            ...!includes auto-comment...
#include "full-write.h"                                                         ...!includes auto-comment...
#include "ioblksize.h"                                                          ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "safe-read.h"                                                          ...!includes auto-comment...
#include "sig2str.h"                                                            ...!includes auto-comment...
#include "xbinary-io.h"                                                         ...!includes auto-comment...
#include "xdectoint.h"                                                          ...!includes auto-comment...
#include "xstrtol.h"                                                            ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "split"                                                    Line 46
                                                                                
#define AUTHORS \                                                               Line 48
  proper_name ("Torbjorn Granlund"), \                                          Line 49
  proper_name ("Richard M. Stallman")                                           Line 50
                                                                                
/* Shell command to filter through, instead of creating files.  */              
static char const *filter_command;                                              Line 53
                                                                                
/* Process ID of the filter.  */                                                
static int filter_pid;                                                          Line 56
                                                                                
/* Array of open pipes.  */                                                     
static int *open_pipes;                                                         Line 59
static size_t open_pipes_alloc;                                                 Line 60
static size_t n_open_pipes;                                                     Line 61
                                                                                
/* Blocked signals.  */                                                         
static sigset_t oldblocked;                                                     Line 64
static sigset_t newblocked;                                                     Line 65
                                                                                
/* Base name of output files.  */                                               
static char const *outbase;                                                     Line 68
                                                                                
/* Name of output files.  */                                                    
static char *outfile;                                                           Line 71
                                                                                
/* Pointer to the end of the prefix in OUTFILE.                                 
   Suffixes are inserted here.  */                                              
static char *outfile_mid;                                                       Line 75
                                                                                
/* Generate new suffix when suffixes are exhausted.  */                         
static bool suffix_auto = true;                                                 Line 78
                                                                                
/* Length of OUTFILE's suffix.  */                                              
static size_t suffix_length;                                                    Line 81
                                                                                
/* Alphabet of characters to use in suffix.  */                                 
static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz";              Line 84
                                                                                
/* Numerical suffix start value.  */                                            
static const char *numeric_suffix_start;                                        Line 87
                                                                                
/* Additional suffix to append to output file names.  */                        
static char const *additional_suffix;                                           Line 90
                                                                                
/* Name of input file.  May be "-".  */                                         
static char *infile;                                                            Line 93
                                                                                
/* stat buf for input file.  */                                                 
static struct stat in_stat_buf;                                                 Line 96
                                                                                
/* Descriptor on which output file is open.  */                                 
static int output_desc = -1;                                                    Line 99
                                                                                
/* If true, print a diagnostic on standard error just before each               
   output file is opened. */                                                    
static bool verbose;                                                            Line 103
                                                                                
/* If true, don't generate zero length output files. */                         
static bool elide_empty_files;                                                  Line 106
                                                                                
/* If true, in round robin mode, immediately copy                               
   input to output, which is much slower, so disabled by default.  */           
static bool unbuffered;                                                         Line 110
                                                                                
/* The character marking end of line.  Defaults to \n below.  */                
static int eolchar = -1;                                                        Line 113
                                                                                
/* The split mode to use.  */                                                   
enum Split_type                                                                 Line 116
{                                                                               
  type_undef, type_bytes, type_byteslines, type_lines, type_digits,             Line 118
  type_chunk_bytes, type_chunk_lines, type_rr                                   Line 119
};                                                                              Block 1
                                                                                
/* For long options that have no equivalent short option, use a                 
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */      
enum                                                                            Line 124
{                                                                               
  VERBOSE_OPTION = CHAR_MAX + 1,                                                Line 126
  FILTER_OPTION,                                                                Line 127
  IO_BLKSIZE_OPTION,                                                            Line 128
  ADDITIONAL_SUFFIX_OPTION                                                      Line 129
};                                                                              Block 2
                                                                                
static struct option const longopts[] =                                         Line 132
{                                                                               
  {"bytes", required_argument, NULL, 'b'},                                      Line 134
  {"lines", required_argument, NULL, 'l'},                                      Line 135
  {"line-bytes", required_argument, NULL, 'C'},                                 Line 136
  {"number", required_argument, NULL, 'n'},                                     Line 137
  {"elide-empty-files", no_argument, NULL, 'e'},                                Line 138
  {"unbuffered", no_argument, NULL, 'u'},                                       Line 139
  {"suffix-length", required_argument, NULL, 'a'},                              Line 140
  {"additional-suffix", required_argument, NULL,                                Line 141
   ADDITIONAL_SUFFIX_OPTION},                                                   Line 142
  {"numeric-suffixes", optional_argument, NULL, 'd'},                           Line 143
  {"hex-suffixes", optional_argument, NULL, 'x'},                               Line 144
  {"filter", required_argument, NULL, FILTER_OPTION},                           Line 145
  {"verbose", no_argument, NULL, VERBOSE_OPTION},                               Line 146
  {"separator", required_argument, NULL, 't'},                                  Line 147
  {"-io-blksize", required_argument, NULL,                                      Line 148
   IO_BLKSIZE_OPTION}, /* do not document */                                    Line 149
  {GETOPT_HELP_OPTION_DECL},                                                    Line 150
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 151
  {NULL, 0, NULL, 0}                                                            Line 152
};                                                                              Block 3
                                                                                
/* Return true if the errno value, ERR, is ignorable.  */                       
static inline bool                                                              Line 156
ignorable (int err)                                                             Line 157
{                                                                               
  return filter_command && err == EPIPE;                                        Line 159
}                                                                               Block 4
                                                                                
static void                                                                     Line 162
set_suffix_length (uintmax_t n_units, enum Split_type split_type)               Line 163
{                                                                               
#define DEFAULT_SUFFIX_LENGTH 2                                                 Line 165
                                                                                
  uintmax_t suffix_needed = 0;                                                  Line 167
                                                                                
  /* The suffix auto length feature is incompatible with                        
     a user specified start value as the generated suffixes                     
     are not all consecutive.  */                                               
  if (numeric_suffix_start)                                                     Line 172
    suffix_auto = false;                                                        Line 173
                                                                                
  /* Auto-calculate the suffix length if the number of files is given.  */      
  if (split_type == type_chunk_bytes || split_type == type_chunk_lines          Line 176
      || split_type == type_rr)                                                 Line 177
    {                                                                           
      uintmax_t n_units_end = n_units;                                          Line 179
      if (numeric_suffix_start)                                                 Line 180
        {                                                                       
          uintmax_t n_start;                                                    Line 182
          strtol_error e = xstrtoumax (numeric_suffix_start, NULL, 10,          Line 183
                                       &n_start, "");                           Line 184
          if (e == LONGINT_OK && n_start <= UINTMAX_MAX - n_units)              Line 185
            {                                                                   
              /* Restrict auto adjustment so we don't keep                      
                 incrementing a suffix size arbitrarily,                        
                 as that would break sort order for files                       
                 generated from multiple split runs.  */                        
              if (n_start < n_units)                                            Line 191
                n_units_end += n_start;                                         Line 192
            }                                                                   
                                                                                
        }                                                                       
      size_t alphabet_len = strlen (suffix_alphabet);                           Line 196
      bool alphabet_slop = (n_units_end % alphabet_len) != 0;                   Line 197
      while (n_units_end /= alphabet_len)                                       Line 198
        suffix_needed++;                                                        Line 199
      suffix_needed += alphabet_slop;                                           Line 200
      suffix_auto = false;                                                      Line 201
    }                                                                           
                                                                                
  if (suffix_length)            /* set by user */                               Line 204
    {                                                                           
      if (suffix_length < suffix_needed)                                        Line 206
        {                                                                       
          die (EXIT_FAILURE, 0,                                                 Line 208
               _("the suffix length needs to be at least %"PRIuMAX),            Line 209
               suffix_needed);                                                  Line 210
        }                                                                       
      suffix_auto = false;                                                      Line 212
      return;                                                                   Line 213
    }                                                                           
  else                                                                          Line 215
    suffix_length = MAX (DEFAULT_SUFFIX_LENGTH, suffix_needed);                 Line 216
}                                                                               Block 5
                                                                                
void                                                                            Line 219
usage (int status)                                                              Line 220
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 222
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 224
    {                                                                           
      printf (_("\                                                              Line 226
Usage: %s [OPTION]... [FILE [PREFIX]]\n\                                        Line 227
"),                                                                             Line 228
              program_name);                                                    Line 229
      fputs (_("\                                                               Line 230
Output pieces of FILE to PREFIXaa, PREFIXab, ...;\n\                            Line 231
default size is 1000 lines, and default PREFIX is 'x'.\n\                       Line 232
"), stdout);                                                                    Line 233
                                                                                
      emit_stdin_note ();                                                       ...!common auto-comment...
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fprintf (stdout, _("\                                                     Line 238
  -a, --suffix-length=N   generate suffixes of length N (default %d)\n\         Line 239
      --additional-suffix=SUFFIX  append an additional SUFFIX to file names\n\  Line 240
  -b, --bytes=SIZE        put SIZE bytes per output file\n\                     Line 241
  -C, --line-bytes=SIZE   put at most SIZE bytes of records per output file\n\  Line 242
  -d                      use numeric suffixes starting at 0, not alphabetic\n\ Line 243
      --numeric-suffixes[=FROM]  same as -d, but allow setting the start value\ Line 244
\n\                                                                             
  -x                      use hex suffixes starting at 0, not alphabetic\n\     Line 246
      --hex-suffixes[=FROM]  same as -x, but allow setting the start value\n\   Line 247
  -e, --elide-empty-files  do not generate empty output files with '-n'\n\      Line 248
      --filter=COMMAND    write to shell COMMAND; file name is $FILE\n\         Line 249
  -l, --lines=NUMBER      put NUMBER lines/records per output file\n\           Line 250
  -n, --number=CHUNKS     generate CHUNKS output files; see explanation below\n\Line 251
  -t, --separator=SEP     use SEP instead of newline as the record separator;\n\Line 252
                            '\\0' (zero) specifies the NUL character\n\         Line 253
  -u, --unbuffered        immediately copy input to output with '-n r/...'\n\   Line 254
"), DEFAULT_SUFFIX_LENGTH);                                                     Line 255
      fputs (_("\                                                               Line 256
      --verbose           print a diagnostic just before each\n\                Line 257
                            output file is opened\n\                            Line 258
"), stdout);                                                                    Line 259
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 260
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 261
      emit_size_note ();                                                        Line 262
      fputs (_("\n\                                                             Line 263
CHUNKS may be:\n\                                                               Line 264
  N       split into N files based on size of input\n\                          Line 265
  K/N     output Kth of N to stdout\n\                                          Line 266
  l/N     split into N files without splitting lines/records\n\                 Line 267
  l/K/N   output Kth of N to stdout without splitting lines/records\n\          Line 268
  r/N     like 'l' but use round robin distribution\n\                          Line 269
  r/K/N   likewise but only output Kth of N to stdout\n\                        Line 270
"), stdout);                                                                    Line 271
      emit_ancillary_info (PROGRAM_NAME);                                       Line 272
    }                                                                           
  exit (status);                                                                Line 274
}                                                                               Block 6
                                                                                
/* Return the number of bytes that can be read from FD with status ST.          
   Store up to the first BUFSIZE bytes of the file's data into BUF,             
   and advance the file position by the number of bytes read.  On               
   input error, set errno and return -1.  */                                    
                                                                                
static off_t                                                                    Line 282
input_file_size (int fd, struct stat const *st, char *buf, size_t bufsize)      Line 283
{                                                                               
  off_t cur = lseek (fd, 0, SEEK_CUR);                                          Line 285
  if (cur < 0)                                                                  Line 286
    {                                                                           
      if (errno == ESPIPE)                                                      Line 288
        errno = 0; /* Suppress confusing seek error.  */                        Line 289
      return -1;                                                                Line 290
    }                                                                           
                                                                                
  off_t size = 0;                                                               Line 293
  do                                                                            
    {                                                                           
      size_t n_read = safe_read (fd, buf + size, bufsize - size);               Line 296...!syscalls auto-comment...
      if (n_read == 0)                                                          Line 297
        return size;                                                            Line 298
      if (n_read == SAFE_READ_ERROR)                                            Line 299
        return -1;                                                              Line 300
      size += n_read;                                                           Line 301
    }                                                                           
  while (size < bufsize);                                                       Line 303
                                                                                
  /* Note we check st_size _after_ the read() above                             
     because /proc files on GNU/Linux are seekable                              
     but have st_size == 0.  */                                                 
  if (st->st_size == 0)                                                         Line 308
    {                                                                           
      /* We've filled the buffer, from a seekable file,                         
         which has an st_size==0, E.g., /dev/zero on GNU/Linux.                 
         Assume there is no limit to file size.  */                             
      errno = EOVERFLOW;                                                        Line 313
      return -1;                                                                Line 314
    }                                                                           
                                                                                
  cur += size;                                                                  Line 317
  off_t end;                                                                    Line 318
  if (usable_st_size (st) && cur <= st->st_size)                                Line 319
    end = st->st_size;                                                          Line 320
  else                                                                          Line 321
    {                                                                           
      end = lseek (fd, 0, SEEK_END);                                            Line 323
      if (end < 0)                                                              Line 324
        return -1;                                                              Line 325
      if (end != cur)                                                           Line 326
        {                                                                       
          if (lseek (fd, cur, SEEK_SET) < 0)                                    Line 328
            return -1;                                                          Line 329
          if (end < cur)                                                        Line 330
            end = cur;                                                          Line 331
        }                                                                       
    }                                                                           
                                                                                
  size += end - cur;                                                            Line 335
  if (size == OFF_T_MAX)                                                        Line 336
    {                                                                           
      /* E.g., /dev/zero on GNU/Hurd.  */                                       
      errno = EOVERFLOW;                                                        Line 339
      return -1;                                                                Line 340
    }                                                                           
                                                                                
  return size;                                                                  Line 343
}                                                                               Block 7
                                                                                
/* Compute the next sequential output file name and store it into the           
   string 'outfile'.  */                                                        
                                                                                
static void                                                                     Line 349
next_file_name (void)                                                           Line 350
{                                                                               
  /* Index in suffix_alphabet of each character in the suffix.  */              
  static size_t *sufindex;                                                      Line 353
  static size_t outbase_length;                                                 Line 354
  static size_t outfile_length;                                                 Line 355
  static size_t addsuf_length;                                                  Line 356
                                                                                
  if (! outfile)                                                                Line 358
    {                                                                           
      bool widen;                                                               Line 360
                                                                                
new_name:                                                                       Line 362
      widen = !! outfile_length;                                                Line 363
                                                                                
      if (! widen)                                                              Line 365
        {                                                                       
          /* Allocate and initialize the first file name.  */                   
                                                                                
          outbase_length = strlen (outbase);                                    Line 369
          addsuf_length = additional_suffix ? strlen (additional_suffix) : 0;   Line 370
          outfile_length = outbase_length + suffix_length + addsuf_length;      Line 371
        }                                                                       
      else                                                                      Line 373
        {                                                                       
          /* Reallocate and initialize a new wider file name.                   
             We do this by subsuming the unchanging part of                     
             the generated suffix into the prefix (base), and                   
             reinitializing the now one longer suffix.  */                      
                                                                                
          outfile_length += 2;                                                  Line 380
          suffix_length++;                                                      Line 381
        }                                                                       
                                                                                
      if (outfile_length + 1 < outbase_length)                                  Line 384
        xalloc_die ();                                                          ...!common auto-comment...
      outfile = xrealloc (outfile, outfile_length + 1);                         Line 386
                                                                                
      if (! widen)                                                              Line 388
        memcpy (outfile, outbase, outbase_length);                              Line 389
      else                                                                      Line 390
        {                                                                       
          /* Append the last alphabet character to the file name prefix.  */    
          outfile[outbase_length] = suffix_alphabet[sufindex[0]];               Line 393
          outbase_length++;                                                     Line 394
        }                                                                       
                                                                                
      outfile_mid = outfile + outbase_length;                                   Line 397
      memset (outfile_mid, suffix_alphabet[0], suffix_length);                  Line 398
      if (additional_suffix)                                                    Line 399
        memcpy (outfile_mid + suffix_length, additional_suffix, addsuf_length); Line 400
      outfile[outfile_length] = 0;                                              Line 401
                                                                                
      free (sufindex);                                                          Line 403
      sufindex = xcalloc (suffix_length, sizeof *sufindex);                     Line 404
                                                                                
      if (numeric_suffix_start)                                                 Line 406
        {                                                                       
          assert (! widen);                                                     Line 408
                                                                                
          /* Update the output file name.  */                                   
          size_t i = strlen (numeric_suffix_start);                             Line 411
          memcpy (outfile_mid + suffix_length - i, numeric_suffix_start, i);    Line 412
                                                                                
          /* Update the suffix index.  */                                       
          size_t *sufindex_end = sufindex + suffix_length;                      Line 415
          while (i-- != 0)                                                      Line 416
            *--sufindex_end = numeric_suffix_start[i] - '0';                    Line 417
        }                                                                       
                                                                                
#if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX                  Line 420
      /* POSIX requires that if the output file name is too long for            
         its directory, 'split' must fail without creating any files.           
         This must be checked for explicitly on operating systems that          
         silently truncate file names.  */                                      
      {                                                                         
        char *dir = dir_name (outfile);                                         Line 426
        long name_max = pathconf (dir, _PC_NAME_MAX);                           Line 427
        if (0 <= name_max && name_max < base_len (last_component (outfile)))    Line 428
          die (EXIT_FAILURE, ENAMETOOLONG, "%s", quotef (outfile));             Line 429
        free (dir);                                                             Line 430
      }                                                                         
#endif                                                                          Line 432
    }                                                                           
  else                                                                          Line 434
    {                                                                           
      /* Increment the suffix in place, if possible.  */                        
                                                                                
      size_t i = suffix_length;                                                 Line 438
      while (i-- != 0)                                                          Line 439
        {                                                                       
          sufindex[i]++;                                                        Line 441
          if (suffix_auto && i == 0 && ! suffix_alphabet[sufindex[0] + 1])      Line 442
            goto new_name;                                                      Line 443
          outfile_mid[i] = suffix_alphabet[sufindex[i]];                        Line 444
          if (outfile_mid[i])                                                   Line 445
            return;                                                             Line 446
          sufindex[i] = 0;                                                      Line 447
          outfile_mid[i] = suffix_alphabet[sufindex[i]];                        Line 448
        }                                                                       
      die (EXIT_FAILURE, 0, _("output file suffixes exhausted"));               Line 450
    }                                                                           
}                                                                               
                                                                                
/* Create or truncate a file.  */                                               
                                                                                
static int                                                                      Line 456
create (const char *name)                                                       Line 457
{                                                                               
  if (!filter_command)                                                          Line 459
    {                                                                           
      if (verbose)                                                              Line 461
        fprintf (stdout, _("creating file %s\n"), quoteaf (name));              Line 462
                                                                                
      int fd = open (name, O_WRONLY | O_CREAT | O_BINARY, MODE_RW_UGO);         Line 464...!syscalls auto-comment...
      if (fd < 0)                                                               Line 465
        return fd;                                                              Line 466
      struct stat out_stat_buf;                                                 Line 467
      if (fstat (fd, &out_stat_buf) != 0)                                       Line 468...!syscalls auto-comment......!syscalls auto-comment...
        die (EXIT_FAILURE, errno, _("failed to stat %s"), quoteaf (name));      Line 469
      if (SAME_INODE (in_stat_buf, out_stat_buf))                               Line 470
        die (EXIT_FAILURE, 0, _("%s would overwrite input; aborting"),          ...!common auto-comment...
             quoteaf (name));                                                   Line 472
      if (ftruncate (fd, 0) != 0)                                               Line 473...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, _("%s: error truncating"), quotef (name));    Line 474
                                                                                
      return fd;                                                                Line 476
    }                                                                           
  else                                                                          Line 478
    {                                                                           
      int fd_pair[2];                                                           Line 480
      pid_t child_pid;                                                          Line 481
      char const *shell_prog = getenv ("SHELL");                                Line 482
      if (shell_prog == NULL)                                                   Line 483
        shell_prog = "/bin/sh";                                                 Line 484
      if (setenv ("FILE", name, 1) != 0)                                        Line 485
        die (EXIT_FAILURE, errno,                                               Line 486
             _("failed to set FILE environment variable"));                     Line 487
      if (verbose)                                                              Line 488
        fprintf (stdout, _("executing with FILE=%s\n"), quotef (name));         Line 489
      if (pipe (fd_pair) != 0)                                                  Line 490
        die (EXIT_FAILURE, errno, _("failed to create pipe"));                  Line 491
      child_pid = fork ();                                                      Line 492...!syscalls auto-comment...
      if (child_pid == 0)                                                       Line 493
        {                                                                       
          /* This is the child process.  If an error occurs here, the           
             parent will eventually learn about it after doing a wait,          
             at which time it will emit its own error message.  */              
          int j;                                                                Line 498
          /* We have to close any pipes that were opened during an              
             earlier call, otherwise this process will be holding a             
             write-pipe that will prevent the earlier process from              
             reading an EOF on the corresponding read-pipe.  */                 
          for (j = 0; j < n_open_pipes; ++j)                                    Line 503
            if (close (open_pipes[j]) != 0)                                     Line 504...!syscalls auto-comment...
              die (EXIT_FAILURE, errno, _("closing prior pipe"));               Line 505
          if (close (fd_pair[1]))                                               Line 506...!syscalls auto-comment...
            die (EXIT_FAILURE, errno, _("closing output pipe"));                Line 507
          if (fd_pair[0] != STDIN_FILENO)                                       Line 508
            {                                                                   
              if (dup2 (fd_pair[0], STDIN_FILENO) != STDIN_FILENO)              Line 510
                die (EXIT_FAILURE, errno, _("moving input pipe"));              Line 511
              if (close (fd_pair[0]) != 0)                                      Line 512...!syscalls auto-comment...
                die (EXIT_FAILURE, errno, _("closing input pipe"));             Line 513
            }                                                                   
          sigprocmask (SIG_SETMASK, &oldblocked, NULL);                         Line 515
          execl (shell_prog, last_component (shell_prog), "-c",                 Line 516
                 filter_command, (char *) NULL);                                Line 517
          die (EXIT_FAILURE, errno, _("failed to run command: \"%s -c %s\""),   Line 518
               shell_prog, filter_command);                                     Line 519
        }                                                                       
      if (child_pid == -1)                                                      Line 521
        die (EXIT_FAILURE, errno, _("fork system call failed"));                Line 522
      if (close (fd_pair[0]) != 0)                                              Line 523...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, _("failed to close input pipe"));             Line 524
      filter_pid = child_pid;                                                   Line 525
      if (n_open_pipes == open_pipes_alloc)                                     Line 526
        open_pipes = x2nrealloc (open_pipes, &open_pipes_alloc,                 Line 527
                                 sizeof *open_pipes);                           Line 528
      open_pipes[n_open_pipes++] = fd_pair[1];                                  Line 529
      return fd_pair[1];                                                        Line 530
    }                                                                           
}                                                                               Block 9
                                                                                
/* Close the output file, and do any associated cleanup.                        
   If FP and FD are both specified, they refer to the same open file;           
   in this case FP is closed, but FD is still used in cleanup.  */              
static void                                                                     Line 537
closeout (FILE *fp, int fd, pid_t pid, char const *name)                        Line 538
{                                                                               
  if (fp != NULL && fclose (fp) != 0 && ! ignorable (errno))                    Line 540...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, "%s", quotef (name));                             Line 541
  if (fd >= 0)                                                                  Line 542
    {                                                                           
      if (fp == NULL && close (fd) < 0)                                         Line 544...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, "%s", quotef (name));                         Line 545
      int j;                                                                    Line 546
      for (j = 0; j < n_open_pipes; ++j)                                        Line 547
        {                                                                       
          if (open_pipes[j] == fd)                                              Line 549
            {                                                                   
              open_pipes[j] = open_pipes[--n_open_pipes];                       Line 551
              break;                                                            Line 552
            }                                                                   
        }                                                                       
    }                                                                           
  if (pid > 0)                                                                  Line 556
    {                                                                           
      int wstatus = 0;                                                          Line 558
      if (waitpid (pid, &wstatus, 0) == -1 && errno != ECHILD)                  Line 559
        die (EXIT_FAILURE, errno, _("waiting for child process"));              Line 560
      if (WIFSIGNALED (wstatus))                                                Line 561
        {                                                                       
          int sig = WTERMSIG (wstatus);                                         Line 563
          if (sig != SIGPIPE)                                                   Line 564
            {                                                                   
              char signame[MAX (SIG2STR_MAX, INT_BUFSIZE_BOUND (int))];         Line 566
              if (sig2str (sig, signame) != 0)                                  Line 567
                sprintf (signame, "%d", sig);                                   Line 568
              error (sig + 128, 0,                                              Line 569
                     _("with FILE=%s, signal %s from command: %s"),             Line 570
                     quotef (name), signame, filter_command);                   Line 571
            }                                                                   
        }                                                                       
      else if (WIFEXITED (wstatus))                                             Line 574
        {                                                                       
          int ex = WEXITSTATUS (wstatus);                                       Line 576
          if (ex != 0)                                                          Line 577
            error (ex, 0, _("with FILE=%s, exit %d from command: %s"),          Line 578
                   quotef (name), ex, filter_command);                          Line 579
        }                                                                       
      else                                                                      Line 581
        {                                                                       
          /* shouldn't happen.  */                                              
          die (EXIT_FAILURE, 0,                                                 Line 584
               _("unknown status from command (0x%X)"), wstatus + 0u);          Line 585
        }                                                                       
    }                                                                           
}                                                                               Block 10
                                                                                
/* Write BYTES bytes at BP to an output file.                                   
   If NEW_FILE_FLAG is true, open the next output file.                         
   Otherwise add to the same output file already in use.                        
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 595
cwrite (bool new_file_flag, const char *bp, size_t bytes)                       Line 596...!syscalls auto-comment...
{                                                                               
  if (new_file_flag)                                                            Line 598
    {                                                                           
      if (!bp && bytes == 0 && elide_empty_files)                               Line 600
        return true;                                                            Line 601
      closeout (NULL, output_desc, filter_pid, outfile);                        Line 602
      next_file_name ();                                                        Line 603
      output_desc = create (outfile);                                           Line 604
      if (output_desc < 0)                                                      Line 605
        die (EXIT_FAILURE, errno, "%s", quotef (outfile));                      Line 606
    }                                                                           
                                                                                
  if (full_write (output_desc, bp, bytes) == bytes)                             Line 609...!syscalls auto-comment...
    return true;                                                                Line 610
  else                                                                          Line 611
    {                                                                           
      if (! ignorable (errno))                                                  Line 613
        die (EXIT_FAILURE, errno, "%s", quotef (outfile));                      Line 614
      return false;                                                             Line 615
    }                                                                           
}                                                                               Block 11
                                                                                
/* Split into pieces of exactly N_BYTES bytes.                                  
   Use buffer BUF, whose size is BUFSIZE.                                       
   BUF contains the first INITIAL_READ input bytes.  */                         
                                                                                
static void                                                                     Line 623
bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize, size_t initial_read, Line 624
             uintmax_t max_files)                                               Line 625
{                                                                               
  size_t n_read;                                                                Line 627
  bool new_file_flag = true;                                                    Line 628
  bool filter_ok = true;                                                        Line 629
  uintmax_t to_write = n_bytes;                                                 Line 630
  uintmax_t opened = 0;                                                         Line 631
  bool eof;                                                                     Line 632
                                                                                
  do                                                                            
    {                                                                           
      if (initial_read != SIZE_MAX)                                             Line 636
        {                                                                       
          n_read = initial_read;                                                Line 638
          initial_read = SIZE_MAX;                                              Line 639
          eof = n_read < bufsize;                                               Line 640
        }                                                                       
      else                                                                      Line 642
        {                                                                       
          if (! filter_ok                                                       Line 644
              && lseek (STDIN_FILENO, to_write, SEEK_CUR) != -1)                Line 645
            {                                                                   
              to_write = n_bytes;                                               Line 647
              new_file_flag = true;                                             Line 648
            }                                                                   
                                                                                
          n_read = safe_read (STDIN_FILENO, buf, bufsize);                      Line 651...!syscalls auto-comment...
          if (n_read == SAFE_READ_ERROR)                                        Line 652
            die (EXIT_FAILURE, errno, "%s", quotef (infile));                   Line 653
          eof = n_read == 0;                                                    Line 654
        }                                                                       
      char *bp_out = buf;                                                       Line 656
      while (to_write <= n_read)                                                Line 657
        {                                                                       
          if (filter_ok || new_file_flag)                                       Line 659
            filter_ok = cwrite (new_file_flag, bp_out, to_write);               Line 660...!syscalls auto-comment...
          opened += new_file_flag;                                              Line 661
          new_file_flag = !max_files || (opened < max_files);                   Line 662
          if (! filter_ok && ! new_file_flag)                                   Line 663
            {                                                                   
              /* If filters no longer accepting input, stop reading.  */        
              n_read = 0;                                                       Line 666
              eof = true;                                                       Line 667
              break;                                                            Line 668
            }                                                                   
          bp_out += to_write;                                                   Line 670
          n_read -= to_write;                                                   Line 671
          to_write = n_bytes;                                                   Line 672
        }                                                                       
      if (n_read != 0)                                                          Line 674
        {                                                                       
          if (filter_ok || new_file_flag)                                       Line 676
            filter_ok = cwrite (new_file_flag, bp_out, n_read);                 Line 677...!syscalls auto-comment...
          opened += new_file_flag;                                              Line 678
          new_file_flag = false;                                                Line 679
          if (! filter_ok && opened == max_files)                               Line 680
            {                                                                   
              /* If filters no longer accepting input, stop reading.  */        
              break;                                                            Line 683
            }                                                                   
          to_write -= n_read;                                                   Line 685
        }                                                                       
    }                                                                           
  while (! eof);                                                                Line 688
                                                                                
  /* Ensure NUMBER files are created, which truncates                           
     any existing files or notifies any consumers on fifos.                     
     FIXME: Should we do this before EXIT_FAILURE?  */                          
  while (opened++ < max_files)                                                  Line 693
    cwrite (true, NULL, 0);                                                     Line 694...!syscalls auto-comment...
}                                                                               Block 12
                                                                                
/* Split into pieces of exactly N_LINES lines.                                  
   Use buffer BUF, whose size is BUFSIZE.  */                                   
                                                                                
static void                                                                     Line 700
lines_split (uintmax_t n_lines, char *buf, size_t bufsize)                      Line 701
{                                                                               
  size_t n_read;                                                                Line 703
  char *bp, *bp_out, *eob;                                                      Line 704
  bool new_file_flag = true;                                                    Line 705
  uintmax_t n = 0;                                                              Line 706
                                                                                
  do                                                                            
    {                                                                           
      n_read = safe_read (STDIN_FILENO, buf, bufsize);                          Line 710...!syscalls auto-comment...
      if (n_read == SAFE_READ_ERROR)                                            Line 711
        die (EXIT_FAILURE, errno, "%s", quotef (infile));                       Line 712
      bp = bp_out = buf;                                                        Line 713
      eob = bp + n_read;                                                        Line 714
      *eob = eolchar;                                                           Line 715
      while (true)                                                              Line 716
        {                                                                       
          bp = memchr (bp, eolchar, eob - bp + 1);                              Line 718
          if (bp == eob)                                                        Line 719
            {                                                                   
              if (eob != bp_out) /* do not write 0 bytes! */                    Line 721
                {                                                               
                  size_t len = eob - bp_out;                                    Line 723
                  cwrite (new_file_flag, bp_out, len);                          Line 724...!syscalls auto-comment...
                  new_file_flag = false;                                        Line 725
                }                                                               
              break;                                                            Line 727
            }                                                                   
                                                                                
          ++bp;                                                                 Line 730
          if (++n >= n_lines)                                                   Line 731
            {                                                                   
              cwrite (new_file_flag, bp_out, bp - bp_out);                      Line 733...!syscalls auto-comment...
              bp_out = bp;                                                      Line 734
              new_file_flag = true;                                             Line 735
              n = 0;                                                            Line 736
            }                                                                   
        }                                                                       
    }                                                                           
  while (n_read);                                                               Line 740
}                                                                               Block 13
                                                                                
/* Split into pieces that are as large as possible while still not more         
   than N_BYTES bytes, and are split on line boundaries except                  
   where lines longer than N_BYTES bytes occur. */                              
                                                                                
static void                                                                     Line 747
line_bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize)                 Line 748
{                                                                               
  size_t n_read;                                                                Line 750
  uintmax_t n_out = 0;      /* for each split.  */                              Line 751
  size_t n_hold = 0;                                                            Line 752
  char *hold = NULL;        /* for lines > bufsize.  */                         Line 753
  size_t hold_size = 0;                                                         Line 754
  bool split_line = false;  /* Whether a \n was output in a split.  */          Line 755
                                                                                
  do                                                                            
    {                                                                           
      n_read = safe_read (STDIN_FILENO, buf, bufsize);                          Line 759...!syscalls auto-comment...
      if (n_read == SAFE_READ_ERROR)                                            Line 760
        die (EXIT_FAILURE, errno, "%s", quotef (infile));                       Line 761
      size_t n_left = n_read;                                                   Line 762
      char *sob = buf;                                                          Line 763
      while (n_left)                                                            Line 764
        {                                                                       
          size_t split_rest = 0;                                                Line 766
          char *eoc = NULL;                                                     Line 767
          char *eol;                                                            Line 768
                                                                                
          /* Determine End Of Chunk and/or End of Line,                         
             which are used below to select what to write or buffer.  */        
          if (n_bytes - n_out - n_hold <= n_left)                               Line 772
            {                                                                   
              /* Have enough for split.  */                                     
              split_rest = n_bytes - n_out - n_hold;                            Line 775
              eoc = sob + split_rest - 1;                                       Line 776
              eol = memrchr (sob, eolchar, split_rest);                         Line 777
            }                                                                   
          else                                                                  Line 779
            eol = memrchr (sob, eolchar, n_left);                               Line 780
                                                                                
          /* Output hold space if possible.  */                                 
          if (n_hold && !(!eol && n_out))                                       Line 783
            {                                                                   
              cwrite (n_out == 0, hold, n_hold);                                Line 785...!syscalls auto-comment...
              n_out += n_hold;                                                  Line 786
              if (n_hold > bufsize)                                             Line 787
                hold = xrealloc (hold, bufsize);                                Line 788
              n_hold = 0;                                                       Line 789
              hold_size = bufsize;                                              Line 790
            }                                                                   
                                                                                
          /* Output to eol if present.  */                                      
          if (eol)                                                              Line 794
            {                                                                   
              split_line = true;                                                Line 796
              size_t n_write = eol - sob + 1;                                   Line 797
              cwrite (n_out == 0, sob, n_write);                                Line 798...!syscalls auto-comment...
              n_out += n_write;                                                 Line 799
              n_left -= n_write;                                                Line 800
              sob += n_write;                                                   Line 801
              if (eoc)                                                          Line 802
                split_rest -= n_write;                                          Line 803
            }                                                                   
                                                                                
          /* Output to eoc or eob if possible.  */                              
          if (n_left && !split_line)                                            Line 807
            {                                                                   
              size_t n_write = eoc ? split_rest : n_left;                       Line 809
              cwrite (n_out == 0, sob, n_write);                                Line 810...!syscalls auto-comment...
              n_out += n_write;                                                 Line 811
              n_left -= n_write;                                                Line 812
              sob += n_write;                                                   Line 813
              if (eoc)                                                          Line 814
                split_rest -= n_write;                                          Line 815
            }                                                                   
                                                                                
          /* Update hold if needed.  */                                         
          if ((eoc && split_rest) || (!eoc && n_left))                          Line 819
            {                                                                   
              size_t n_buf = eoc ? split_rest : n_left;                         Line 821
              if (hold_size - n_hold < n_buf)                                   Line 822
                {                                                               
                  if (hold_size <= SIZE_MAX - bufsize)                          Line 824
                    hold_size += bufsize;                                       Line 825
                  else                                                          Line 826
                    xalloc_die ();                                              ...!common auto-comment...
                  hold = xrealloc (hold, hold_size);                            Line 828
                }                                                               
              memcpy (hold + n_hold, sob, n_buf);                               Line 830
              n_hold += n_buf;                                                  Line 831
              n_left -= n_buf;                                                  Line 832
              sob += n_buf;                                                     Line 833
            }                                                                   
                                                                                
          /* Reset for new split.  */                                           
          if (eoc)                                                              Line 837
            {                                                                   
              n_out = 0;                                                        Line 839
              split_line = false;                                               Line 840
            }                                                                   
        }                                                                       
    }                                                                           
  while (n_read);                                                               Line 844
                                                                                
  /* Handle no eol at end of file.  */                                          
  if (n_hold)                                                                   Line 847
    cwrite (n_out == 0, hold, n_hold);                                          Line 848...!syscalls auto-comment...
                                                                                
  free (hold);                                                                  Line 850
}                                                                               Block 14
                                                                                
/* -n l/[K/]N: Write lines to files of approximately file size / N.             
   The file is partitioned into file size / N sized portions, with the          
   last assigned any excess.  If a line _starts_ within a partition             
   it is written completely to the corresponding file.  Since lines             
   are not split even if they overlap a partition, the files written            
   can be larger or smaller than the partition size, and even empty             
   if a line is so long as to completely overlap the partition.  */             
                                                                                
static void                                                                     Line 861
lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,         Line 862
                   size_t initial_read, off_t file_size)                        Line 863
{                                                                               
  assert (n && k <= n && n <= file_size);                                       Line 865
                                                                                
  const off_t chunk_size = file_size / n;                                       Line 867
  uintmax_t chunk_no = 1;                                                       Line 868
  off_t chunk_end = chunk_size - 1;                                             Line 869
  off_t n_written = 0;                                                          Line 870
  bool new_file_flag = true;                                                    Line 871
  bool chunk_truncated = false;                                                 Line 872
                                                                                
  if (k > 1)                                                                    Line 874
    {                                                                           
      /* Start reading 1 byte before kth chunk of file.  */                     
      off_t start = (k - 1) * chunk_size - 1;                                   Line 877
      if (start < initial_read)                                                 Line 878
        {                                                                       
          memmove (buf, buf + start, initial_read - start);                     Line 880
          initial_read -= start;                                                Line 881
        }                                                                       
      else                                                                      Line 883
        {                                                                       
          if (lseek (STDIN_FILENO, start - initial_read, SEEK_CUR) < 0)         Line 885
            die (EXIT_FAILURE, errno, "%s", quotef (infile));                   Line 886
          initial_read = SIZE_MAX;                                              Line 887
        }                                                                       
      n_written = start;                                                        Line 889
      chunk_no = k - 1;                                                         Line 890
      chunk_end = chunk_no * chunk_size - 1;                                    Line 891
    }                                                                           
                                                                                
  while (n_written < file_size)                                                 Line 894
    {                                                                           
      char *bp = buf, *eob;                                                     Line 896
      size_t n_read;                                                            Line 897
      if (initial_read != SIZE_MAX)                                             Line 898
        {                                                                       
          n_read = initial_read;                                                Line 900
          initial_read = SIZE_MAX;                                              Line 901
        }                                                                       
      else                                                                      Line 903
        {                                                                       
          n_read = safe_read (STDIN_FILENO, buf, bufsize);                      Line 905...!syscalls auto-comment...
          if (n_read == SAFE_READ_ERROR)                                        Line 906
            die (EXIT_FAILURE, errno, "%s", quotef (infile));                   Line 907
        }                                                                       
      if (n_read == 0)                                                          Line 909
        break; /* eof.  */                                                      Line 910
      n_read = MIN (n_read, file_size - n_written);                             Line 911
      chunk_truncated = false;                                                  Line 912
      eob = buf + n_read;                                                       Line 913
                                                                                
      while (bp != eob)                                                         Line 915
        {                                                                       
          size_t to_write;                                                      Line 917
          bool next = false;                                                    Line 918
                                                                                
          /* Begin looking for '\n' at last byte of chunk.  */                  
          off_t skip = MIN (n_read, MAX (0, chunk_end - n_written));            Line 921
          char *bp_out = memchr (bp + skip, eolchar, n_read - skip);            Line 922
          if (bp_out++)                                                         Line 923
            next = true;                                                        Line 924
          else                                                                  Line 925
            bp_out = eob;                                                       Line 926
          to_write = bp_out - bp;                                               Line 927
                                                                                
          if (k == chunk_no)                                                    Line 929
            {                                                                   
              /* We don't use the stdout buffer here since we're writing        
                 large chunks from an existing file, so it's more efficient     
                 to write out directly.  */                                     
              if (full_write (STDOUT_FILENO, bp, to_write) != to_write)         Line 934...!syscalls auto-comment...
                die (EXIT_FAILURE, errno, "%s", _("write error"));              Line 935
            }                                                                   
          else if (! k)                                                         Line 937
            cwrite (new_file_flag, bp, to_write);                               Line 938...!syscalls auto-comment...
          n_written += to_write;                                                Line 939
          bp += to_write;                                                       Line 940
          n_read -= to_write;                                                   Line 941
          new_file_flag = next;                                                 Line 942
                                                                                
          /* A line could have been so long that it skipped                     
             entire chunks. So create empty files in that case.  */             
          while (next || chunk_end <= n_written - 1)                            Line 946
            {                                                                   
              if (!next && bp == eob)                                           Line 948
                {                                                               
                  /* replenish buf, before going to next chunk.  */             
                  chunk_truncated = true;                                       Line 951
                  break;                                                        Line 952
                }                                                               
              chunk_no++;                                                       Line 954
              if (k && chunk_no > k)                                            Line 955
                return;                                                         Line 956
              if (chunk_no == n)                                                Line 957
                chunk_end = file_size - 1; /* >= chunk_size.  */                Line 958
              else                                                              Line 959
                chunk_end += chunk_size;                                        Line 960
              if (chunk_end <= n_written - 1)                                   Line 961
                {                                                               
                  if (! k)                                                      Line 963
                    cwrite (true, NULL, 0);                                     Line 964...!syscalls auto-comment...
                }                                                               
              else                                                              Line 966
                next = false;                                                   Line 967
            }                                                                   
        }                                                                       
    }                                                                           
                                                                                
  if (chunk_truncated)                                                          Line 972
    chunk_no++;                                                                 Line 973
                                                                                
  /* Ensure NUMBER files are created, which truncates                           
     any existing files or notifies any consumers on fifos.                     
     FIXME: Should we do this before EXIT_FAILURE?  */                          
  while (!k && chunk_no++ <= n)                                                 Line 978
    cwrite (true, NULL, 0);                                                     Line 979...!syscalls auto-comment...
}                                                                               Block 15
                                                                                
/* -n K/N: Extract Kth of N chunks.  */                                         
                                                                                
static void                                                                     Line 984
bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,       Line 985
                     size_t initial_read, off_t file_size)                      Line 986
{                                                                               
  off_t start;                                                                  Line 988
  off_t end;                                                                    Line 989
                                                                                
  assert (k && n && k <= n && n <= file_size);                                  Line 991
                                                                                
  start = (k - 1) * (file_size / n);                                            Line 993
  end = (k == n) ? file_size : k * (file_size / n);                             Line 994
                                                                                
  if (start < initial_read)                                                     Line 996
    {                                                                           
      memmove (buf, buf + start, initial_read - start);                         Line 998
      initial_read -= start;                                                    Line 999
    }                                                                           
  else                                                                          Line 1001
    {                                                                           
      if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0)                            Line 1003
        die (EXIT_FAILURE, errno, "%s", quotef (infile));                       Line 1004
      initial_read = SIZE_MAX;                                                  Line 1005
    }                                                                           
                                                                                
  while (start < end)                                                           Line 1008
    {                                                                           
      size_t n_read;                                                            Line 1010
      if (initial_read != SIZE_MAX)                                             Line 1011
        {                                                                       
          n_read = initial_read;                                                Line 1013
          initial_read = SIZE_MAX;                                              Line 1014
        }                                                                       
      else                                                                      Line 1016
        {                                                                       
          n_read = safe_read (STDIN_FILENO, buf, bufsize);                      Line 1018...!syscalls auto-comment...
          if (n_read == SAFE_READ_ERROR)                                        Line 1019
            die (EXIT_FAILURE, errno, "%s", quotef (infile));                   Line 1020
        }                                                                       
      if (n_read == 0)                                                          Line 1022
        break; /* eof.  */                                                      Line 1023
      n_read = MIN (n_read, end - start);                                       Line 1024
      if (full_write (STDOUT_FILENO, buf, n_read) != n_read                     Line 1025...!syscalls auto-comment...
          && ! ignorable (errno))                                               Line 1026
        die (EXIT_FAILURE, errno, "%s", quotef ("-"));                          Line 1027
      start += n_read;                                                          Line 1028
    }                                                                           
}                                                                               Block 16
                                                                                
typedef struct of_info                                                          Line 1032
{                                                                               
  char *of_name;                                                                Line 1034
  int ofd;                                                                      Line 1035
  FILE *ofile;                                                                  Line 1036
  int opid;                                                                     Line 1037
} of_t;                                                                         Line 1038Block 17
                                                                                
enum                                                                            Line 1040
{                                                                               
  OFD_NEW = -1,                                                                 Line 1042
  OFD_APPEND = -2                                                               Line 1043
};                                                                              Block 18
                                                                                
/* Rotate file descriptors when we're writing to more output files than we      
   have available file descriptors.                                             
   Return whether we came under file resource pressure.                         
   If so, it's probably best to close each file when finished with it.  */      
                                                                                
static bool                                                                     Line 1051
ofile_open (of_t *files, size_t i_check, size_t nfiles)                         Line 1052...!syscalls auto-comment...
{                                                                               
  bool file_limit = false;                                                      Line 1054
                                                                                
  if (files[i_check].ofd <= OFD_NEW)                                            Line 1056
    {                                                                           
      int fd;                                                                   Line 1058
      size_t i_reopen = i_check ? i_check - 1 : nfiles - 1;                     Line 1059
                                                                                
      /* Another process could have opened a file in between the calls to       
         close and open, so we should keep trying until open succeeds or        
         we've closed all of our files.  */                                     
      while (true)                                                              Line 1064
        {                                                                       
          if (files[i_check].ofd == OFD_NEW)                                    Line 1066
            fd = create (files[i_check].of_name);                               Line 1067
          else /* OFD_APPEND  */                                                Line 1068
            {                                                                   
              /* Attempt to append to previously opened file.                   
                 We use O_NONBLOCK to support writing to fifos,                 
                 where the other end has closed because of our                  
                 previous close.  In that case we'll immediately                
                 get an error, rather than waiting indefinitely.                
                 In specialised cases the consumer can keep reading             
                 from the fifo, terminating on conditions in the data           
                 itself, or perhaps never in the case of 'tail -f'.             
                 I.e., for fifos it is valid to attempt this reopen.            
                                                                                
                 We don't handle the filter_command case here, as create()      
                 will exit if there are not enough files in that case.          
                 I.e., we don't support restarting filters, as that would       
                 put too much burden on users specifying --filter commands.  */ 
              fd = open (files[i_check].of_name,                                Line 1084...!syscalls auto-comment...
                         O_WRONLY | O_BINARY | O_APPEND | O_NONBLOCK);          Line 1085
            }                                                                   
                                                                                
          if (-1 < fd)                                                          Line 1088
            break;                                                              Line 1089
                                                                                
          if (!(errno == EMFILE || errno == ENFILE))                            Line 1091
            die (EXIT_FAILURE, errno, "%s", quotef (files[i_check].of_name));   Line 1092
                                                                                
          file_limit = true;                                                    Line 1094
                                                                                
          /* Search backwards for an open file to close.  */                    
          while (files[i_reopen].ofd < 0)                                       Line 1097
            {                                                                   
              i_reopen = i_reopen ? i_reopen - 1 : nfiles - 1;                  Line 1099
              /* No more open files to close, exit with E[NM]FILE.  */          
              if (i_reopen == i_check)                                          Line 1101
                die (EXIT_FAILURE, errno, "%s",                                 Line 1102
                     quotef (files[i_check].of_name));                          Line 1103
            }                                                                   
                                                                                
          if (fclose (files[i_reopen].ofile) != 0)                              Line 1106...!syscalls auto-comment...
            die (EXIT_FAILURE, errno, "%s", quotef (files[i_reopen].of_name));  Line 1107
          files[i_reopen].ofile = NULL;                                         Line 1108
          files[i_reopen].ofd = OFD_APPEND;                                     Line 1109
        }                                                                       
                                                                                
      files[i_check].ofd = fd;                                                  Line 1112
      if (!(files[i_check].ofile = fdopen (fd, "a")))                           Line 1113...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, "%s", quotef (files[i_check].of_name));       Line 1114
      files[i_check].opid = filter_pid;                                         Line 1115
      filter_pid = 0;                                                           Line 1116
    }                                                                           
                                                                                
  return file_limit;                                                            Line 1119
}                                                                               Block 19
                                                                                
/* -n r/[K/]N: Divide file into N chunks in round robin fashion.                
   When K == 0, we try to keep the files open in parallel.                      
   If we run out of file resources, then we revert                              
   to opening and closing each file for each line.  */                          
                                                                                
static void                                                                     Line 1127
lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)                  Line 1128
{                                                                               
  bool wrapped = false;                                                         Line 1130
  bool wrote = false;                                                           Line 1131
  bool file_limit;                                                              Line 1132
  size_t i_file;                                                                Line 1133
  of_t *files IF_LINT (= NULL);                                                 Line 1134
  uintmax_t line_no;                                                            Line 1135
                                                                                
  if (k)                                                                        Line 1137
    line_no = 1;                                                                Line 1138
  else                                                                          Line 1139
    {                                                                           
      if (SIZE_MAX < n)                                                         Line 1141
        xalloc_die ();                                                          ...!common auto-comment...
      files = xnmalloc (n, sizeof *files);                                      Line 1143
                                                                                
      /* Generate output file names. */                                         
      for (i_file = 0; i_file < n; i_file++)                                    Line 1146
        {                                                                       
          next_file_name ();                                                    Line 1148
          files[i_file].of_name = xstrdup (outfile);                            Line 1149
          files[i_file].ofd = OFD_NEW;                                          Line 1150
          files[i_file].ofile = NULL;                                           Line 1151
          files[i_file].opid = 0;                                               Line 1152
        }                                                                       
      i_file = 0;                                                               Line 1154
      file_limit = false;                                                       Line 1155
    }                                                                           
                                                                                
  while (true)                                                                  Line 1158
    {                                                                           
      char *bp = buf, *eob;                                                     Line 1160
      size_t n_read = safe_read (STDIN_FILENO, buf, bufsize);                   Line 1161...!syscalls auto-comment...
      if (n_read == SAFE_READ_ERROR)                                            Line 1162
        die (EXIT_FAILURE, errno, "%s", quotef (infile));                       Line 1163
      else if (n_read == 0)                                                     Line 1164
        break; /* eof.  */                                                      Line 1165
      eob = buf + n_read;                                                       Line 1166
                                                                                
      while (bp != eob)                                                         Line 1168
        {                                                                       
          size_t to_write;                                                      Line 1170
          bool next = false;                                                    Line 1171
                                                                                
          /* Find end of line. */                                               
          char *bp_out = memchr (bp, eolchar, eob - bp);                        Line 1174
          if (bp_out)                                                           Line 1175
            {                                                                   
              bp_out++;                                                         Line 1177
              next = true;                                                      Line 1178
            }                                                                   
          else                                                                  Line 1180
            bp_out = eob;                                                       Line 1181
          to_write = bp_out - bp;                                               Line 1182
                                                                                
          if (k)                                                                Line 1184
            {                                                                   
              if (line_no == k && unbuffered)                                   Line 1186
                {                                                               
                  if (full_write (STDOUT_FILENO, bp, to_write) != to_write)     Line 1188...!syscalls auto-comment...
                    die (EXIT_FAILURE, errno, "%s", _("write error"));          Line 1189
                }                                                               
              else if (line_no == k && fwrite (bp, to_write, 1, stdout) != 1)   Line 1191...!syscalls auto-comment...
                {                                                               
                  clearerr (stdout); /* To silence close_stdout().  */          Line 1193
                  die (EXIT_FAILURE, errno, "%s", _("write error"));            Line 1194
                }                                                               
              if (next)                                                         Line 1196
                line_no = (line_no == n) ? 1 : line_no + 1;                     Line 1197
            }                                                                   
          else                                                                  Line 1199
            {                                                                   
              /* Secure file descriptor. */                                     
              file_limit |= ofile_open (files, i_file, n);                      Line 1202...!syscalls auto-comment...
              if (unbuffered)                                                   Line 1203
                {                                                               
                  /* Note writing to fd, rather than flushing the FILE gives    
                     an 8% performance benefit, due to reduced data copying.  */
                  if (full_write (files[i_file].ofd, bp, to_write) != to_write  Line 1207...!syscalls auto-comment...
                      && ! ignorable (errno))                                   Line 1208
                    {                                                           
                      die (EXIT_FAILURE, errno, "%s",                           Line 1210
                           quotef (files[i_file].of_name));                     Line 1211
                    }                                                           
                }                                                               
              else if (fwrite (bp, to_write, 1, files[i_file].ofile) != 1       Line 1214...!syscalls auto-comment...
                       && ! ignorable (errno))                                  Line 1215
                {                                                               
                  die (EXIT_FAILURE, errno, "%s",                               Line 1217
                       quotef (files[i_file].of_name));                         Line 1218
                }                                                               
                                                                                
              if (! ignorable (errno))                                          Line 1221
                wrote = true;                                                   Line 1222
                                                                                
              if (file_limit)                                                   Line 1224
                {                                                               
                  if (fclose (files[i_file].ofile) != 0)                        Line 1226...!syscalls auto-comment...
                    {                                                           
                      die (EXIT_FAILURE, errno, "%s",                           Line 1228
                           quotef (files[i_file].of_name));                     Line 1229
                    }                                                           
                  files[i_file].ofile = NULL;                                   Line 1231
                  files[i_file].ofd = OFD_APPEND;                               Line 1232
                }                                                               
              if (next && ++i_file == n)                                        Line 1234
                {                                                               
                  wrapped = true;                                               Line 1236
                  /* If no filters are accepting input, stop reading.  */       
                  if (! wrote)                                                  Line 1238
                    goto no_filters;                                            Line 1239
                  wrote = false;                                                Line 1240
                  i_file = 0;                                                   Line 1241
                }                                                               
            }                                                                   
                                                                                
          bp = bp_out;                                                          Line 1245
        }                                                                       
    }                                                                           
                                                                                
no_filters:                                                                     Line 1249
  /* Ensure all files created, so that any existing files are truncated,        
     and to signal any waiting fifo consumers.                                  
     Also, close any open file descriptors.                                     
     FIXME: Should we do this before EXIT_FAILURE?  */                          
  if (!k)                                                                       Line 1254
    {                                                                           
      int ceiling = (wrapped ? n : i_file);                                     Line 1256
      for (i_file = 0; i_file < n; i_file++)                                    Line 1257
        {                                                                       
          if (i_file >= ceiling && !elide_empty_files)                          Line 1259
            file_limit |= ofile_open (files, i_file, n);                        Line 1260...!syscalls auto-comment...
          if (files[i_file].ofd >= 0)                                           Line 1261
            closeout (files[i_file].ofile, files[i_file].ofd,                   Line 1262
                      files[i_file].opid, files[i_file].of_name);               Line 1263
          files[i_file].ofd = OFD_APPEND;                                       Line 1264
        }                                                                       
    }                                                                           
  IF_LINT (free (files));                                                       Line 1267
}                                                                               Block 20
                                                                                
#define FAIL_ONLY_ONE_WAY()     \                                               Line 1270
  do        \                                                                   Line 1271
    {        \                                                                  Line 1272
      error (0, 0, _("cannot split in more than one way")); \                   Line 1273
      usage (EXIT_FAILURE);     \                                               Line 1274
    }        \                                                                  Line 1275Block 21
  while (0)                                                                     Line 1276
                                                                                
                                                                                
/* Parse K/N syntax of chunk options.  */                                       
                                                                                
static void                                                                     Line 1281
parse_chunk (uintmax_t *k_units, uintmax_t *n_units, char *slash)               Line 1282
{                                                                               
  *n_units = xdectoumax (slash + 1, 1, UINTMAX_MAX, "",                         Line 1284
                         _("invalid number of chunks"), 0);                     Line 1285
  if (slash != optarg)           /* a leading number is specified.  */          Line 1286
    {                                                                           
      *slash = '\0';                                                            Line 1288
      *k_units = xdectoumax (optarg, 1, *n_units, "",                           Line 1289
                             _("invalid chunk number"), 0);                     Line 1290
    }                                                                           
}                                                                               Block 22
                                                                                
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 1296
{                                                                               
  enum Split_type split_type = type_undef;                                      Line 1298
  size_t in_blk_size = 0; /* optimal block size of input file device */         Line 1299
  size_t page_size = getpagesize ();                                            Line 1300
  uintmax_t k_units = 0;                                                        Line 1301
  uintmax_t n_units = 0;                                                        Line 1302
                                                                                
  static char const multipliers[] = "bEGKkMmPTYZ0";                             Line 1304
  int c;                                                                        Line 1305
  int digits_optind = 0;                                                        Line 1306
  off_t file_size = OFF_T_MAX;                                                  Line 1307
                                                                                
  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
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  /* Parse command line options.  */                                            
                                                                                
  infile = bad_cast ("-");                                                      Line 1319
  outbase = bad_cast ("x");                                                     Line 1320
                                                                                
  while (true)                                                                  Line 1322
    {                                                                           
      /* This is the argv-index of the option we will read next.  */            
      int this_optind = optind ? optind : 1;                                    Line 1325
      char *slash;                                                              Line 1326
                                                                                
      c = getopt_long (argc, argv, "0123456789C:a:b:del:n:t:ux",                Line 1328
                       longopts, NULL);                                         Line 1329
      if (c == -1)                                                              Line 1330
        break;                                                                  Line 1331
                                                                                
      switch (c)                                                                Line 1333
        {                                                                       
        case 'a':                                                               Line 1335
          suffix_length = xdectoumax (optarg, 0, SIZE_MAX / sizeof (size_t),    Line 1336
                                      "", _("invalid suffix length"), 0);       Line 1337
          break;                                                                Line 1338
                                                                                
        case ADDITIONAL_SUFFIX_OPTION:                                          Line 1340
          if (last_component (optarg) != optarg)                                Line 1341
            {                                                                   
              error (0, 0,                                                      Line 1343
                     _("invalid suffix %s, contains directory separator"),      Line 1344
                     quote (optarg));                                           Line 1345
              usage (EXIT_FAILURE);                                             Line 1346
            }                                                                   
          additional_suffix = optarg;                                           Line 1348
          break;                                                                Line 1349
                                                                                
        case 'b':                                                               Line 1351
          if (split_type != type_undef)                                         Line 1352
            FAIL_ONLY_ONE_WAY ();                                               Line 1353
          split_type = type_bytes;                                              Line 1354
          /* Limit to OFF_T_MAX, because if input is a pipe, we could get more  
             data than is possible to write to a single file, so indicate that  
             immediately rather than having possibly future invocations fail. */
          n_units = xdectoumax (optarg, 1, OFF_T_MAX, multipliers,              Line 1358
                                _("invalid number of bytes"), 0);               Line 1359
          break;                                                                Line 1360
                                                                                
        case 'l':                                                               Line 1362
          if (split_type != type_undef)                                         Line 1363
            FAIL_ONLY_ONE_WAY ();                                               Line 1364
          split_type = type_lines;                                              Line 1365
          n_units = xdectoumax (optarg, 1, UINTMAX_MAX, "",                     Line 1366
                                _("invalid number of lines"), 0);               Line 1367
          break;                                                                Line 1368
                                                                                
        case 'C':                                                               Line 1370
          if (split_type != type_undef)                                         Line 1371
            FAIL_ONLY_ONE_WAY ();                                               Line 1372
          split_type = type_byteslines;                                         Line 1373
          n_units = xdectoumax (optarg, 1, MIN (SIZE_MAX, OFF_T_MAX),           Line 1374
                                multipliers, _("invalid number of bytes"), 0);  Line 1375
          break;                                                                Line 1376
                                                                                
        case 'n':                                                               Line 1378
          if (split_type != type_undef)                                         Line 1379
            FAIL_ONLY_ONE_WAY ();                                               Line 1380
          /* skip any whitespace */                                             
          while (isspace (to_uchar (*optarg)))                                  Line 1382
            optarg++;                                                           Line 1383
          if (STRNCMP_LIT (optarg, "r/") == 0)                                  Line 1384
            {                                                                   
              split_type = type_rr;                                             Line 1386
              optarg += 2;                                                      Line 1387
            }                                                                   
          else if (STRNCMP_LIT (optarg, "l/") == 0)                             Line 1389
            {                                                                   
              split_type = type_chunk_lines;                                    Line 1391
              optarg += 2;                                                      Line 1392
            }                                                                   
          else                                                                  Line 1394
            split_type = type_chunk_bytes;                                      Line 1395
          if ((slash = strchr (optarg, '/')))                                   Line 1396
            parse_chunk (&k_units, &n_units, slash);                            Line 1397
          else                                                                  Line 1398
            n_units = xdectoumax (optarg, 1, UINTMAX_MAX, "",                   Line 1399
                                  _("invalid number of chunks"), 0);            Line 1400
          break;                                                                Line 1401
                                                                                
        case 'u':                                                               Line 1403
          unbuffered = true;                                                    Line 1404
          break;                                                                Line 1405
                                                                                
        case 't':                                                               Line 1407
          {                                                                     
            char neweol = optarg[0];                                            Line 1409
            if (! neweol)                                                       Line 1410
              die (EXIT_FAILURE, 0, _("empty record separator"));               Line 1411
            if (optarg[1])                                                      Line 1412
              {                                                                 
                if (STREQ (optarg, "\\0"))                                      Line 1414
                  neweol = '\0';                                                Line 1415
                else                                                            Line 1416
                  {                                                             
                    /* Provoke with 'split -txx'.  Complain about               
                       "multi-character tab" instead of "multibyte tab", so     
                       that the diagnostic's wording does not need to be        
                       changed once multibyte characters are supported.  */     
                    die (EXIT_FAILURE, 0, _("multi-character separator %s"),    Line 1422
                         quote (optarg));                                       Line 1423
                  }                                                             
              }                                                                 
            /* Make it explicit we don't support multiple separators.  */       
            if (0 <= eolchar && neweol != eolchar)                              Line 1427
              {                                                                 
                die (EXIT_FAILURE, 0,                                           Line 1429
                     _("multiple separator characters specified"));             Line 1430
              }                                                                 
                                                                                
            eolchar = neweol;                                                   Line 1433
          }                                                                     
          break;                                                                Line 1435
                                                                                
        case '0':                                                               Line 1437
        case '1':                                                               Line 1438
        case '2':                                                               Line 1439
        case '3':                                                               Line 1440
        case '4':                                                               Line 1441
        case '5':                                                               Line 1442
        case '6':                                                               Line 1443
        case '7':                                                               Line 1444
        case '8':                                                               Line 1445
        case '9':                                                               Line 1446
          if (split_type == type_undef)                                         Line 1447
            {                                                                   
              split_type = type_digits;                                         Line 1449
              n_units = 0;                                                      Line 1450
            }                                                                   
          if (split_type != type_undef && split_type != type_digits)            Line 1452
            FAIL_ONLY_ONE_WAY ();                                               Line 1453
          if (digits_optind != 0 && digits_optind != this_optind)               Line 1454
            n_units = 0; /* More than one number given; ignore other. */        Line 1455
          digits_optind = this_optind;                                          Line 1456
          if (!DECIMAL_DIGIT_ACCUMULATE (n_units, c - '0', uintmax_t))          Line 1457
            {                                                                   
              char buffer[INT_BUFSIZE_BOUND (uintmax_t)];                       Line 1459
              die (EXIT_FAILURE, 0,                                             Line 1460
                   _("line count option -%s%c... is too large"),                Line 1461
                   umaxtostr (n_units, buffer), c);                             Line 1462
            }                                                                   
          break;                                                                Line 1464
                                                                                
        case 'd':                                                               Line 1466
        case 'x':                                                               Line 1467
          if (c == 'd')                                                         Line 1468
            suffix_alphabet = "0123456789";                                     Line 1469
          else                                                                  Line 1470
            suffix_alphabet = "0123456789abcdef";                               Line 1471
          if (optarg)                                                           Line 1472
            {                                                                   
              if (strlen (optarg) != strspn (optarg, suffix_alphabet))          Line 1474
                {                                                               
                  error (0, 0,                                                  Line 1476
                         (c == 'd') ?                                           Line 1477
                           _("%s: invalid start value for numerical suffix") :  Line 1478
                           _("%s: invalid start value for hexadecimal suffix"), Line 1479
                         quote (optarg));                                       Line 1480
                  usage (EXIT_FAILURE);                                         Line 1481
                }                                                               
              else                                                              Line 1483
                {                                                               
                  /* Skip any leading zero.  */                                 
                  while (*optarg == '0' && *(optarg + 1) != '\0')               Line 1486
                    optarg++;                                                   Line 1487
                  numeric_suffix_start = optarg;                                Line 1488
                }                                                               
            }                                                                   
          break;                                                                Line 1491
                                                                                
        case 'e':                                                               Line 1493
          elide_empty_files = true;                                             Line 1494
          break;                                                                Line 1495
                                                                                
        case FILTER_OPTION:                                                     Line 1497
          filter_command = optarg;                                              Line 1498
          break;                                                                Line 1499
                                                                                
        case IO_BLKSIZE_OPTION:                                                 Line 1501
          in_blk_size = xdectoumax (optarg, 1, SIZE_MAX - page_size,            Line 1502
                                    multipliers, _("invalid IO block size"), 0);Line 1503
          break;                                                                Line 1504
                                                                                
        case VERBOSE_OPTION:                                                    Line 1506
          verbose = true;                                                       Line 1507
          break;                                                                Line 1508
                                                                                
        case_GETOPT_HELP_CHAR;                                                  Line 1510
                                                                                
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 1512
                                                                                
        default:                                                                Line 1514
          usage (EXIT_FAILURE);                                                 Line 1515
        }                                                                       
    }                                                                           
                                                                                
  if (k_units != 0 && filter_command)                                           Line 1519
    {                                                                           
      error (0, 0, _("--filter does not process a chunk extracted to stdout")); Line 1521
      usage (EXIT_FAILURE);                                                     Line 1522
    }                                                                           
                                                                                
  /* Handle default case.  */                                                   
  if (split_type == type_undef)                                                 Line 1526
    {                                                                           
      split_type = type_lines;                                                  Line 1528
      n_units = 1000;                                                           Line 1529
    }                                                                           
                                                                                
  if (n_units == 0)                                                             Line 1532
    {                                                                           
      error (0, 0, "%s: %s", _("invalid number of lines"), quote ("0"));        Line 1534
      usage (EXIT_FAILURE);                                                     Line 1535
    }                                                                           
                                                                                
  if (eolchar < 0)                                                              Line 1538
    eolchar = '\n';                                                             Line 1539
                                                                                
  set_suffix_length (n_units, split_type);                                      Line 1541
                                                                                
  /* Get out the filename arguments.  */                                        
                                                                                
  if (optind < argc)                                                            Line 1545
    infile = argv[optind++];                                                    Line 1546
                                                                                
  if (optind < argc)                                                            Line 1548
    outbase = argv[optind++];                                                   Line 1549
                                                                                
  if (optind < argc)                                                            Line 1551
    {                                                                           
      error (0, 0, _("extra operand %s"), quote (argv[optind]));                Line 1553
      usage (EXIT_FAILURE);                                                     Line 1554
    }                                                                           
                                                                                
  /* Check that the suffix length is large enough for the numerical             
     suffix start value.  */                                                    
  if (numeric_suffix_start && strlen (numeric_suffix_start) > suffix_length)    Line 1559
    {                                                                           
      error (0, 0, _("numerical suffix start value is too large "               Line 1561
                     "for the suffix length"));                                 Line 1562
      usage (EXIT_FAILURE);                                                     Line 1563
    }                                                                           
                                                                                
  /* Open the input file.  */                                                   
  if (! STREQ (infile, "-")                                                     Line 1567
      && fd_reopen (STDIN_FILENO, infile, O_RDONLY, 0) < 0)                     Line 1568...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("cannot open %s for reading"),                  Line 1569
         quoteaf (infile));                                                     Line 1570
                                                                                
  /* Binary I/O is safer when byte counts are used.  */                         
  xset_binary_mode (STDIN_FILENO, O_BINARY);                                    Line 1573
                                                                                
  /* Get the optimal block size of input device and make a buffer.  */          
                                                                                
  if (fstat (STDIN_FILENO, &in_stat_buf) != 0)                                  Line 1577...!syscalls auto-comment......!syscalls auto-comment...
    die (EXIT_FAILURE, errno, "%s", quotef (infile));                           Line 1578
                                                                                
  bool specified_buf_size = !! in_blk_size;                                     Line 1580
  if (! specified_buf_size)                                                     Line 1581
    in_blk_size = io_blksize (in_stat_buf);                                     Line 1582
                                                                                
  void *b = xmalloc (in_blk_size + 1 + page_size - 1);                          Line 1584
  char *buf = ptr_align (b, page_size);                                         Line 1585
  size_t initial_read = SIZE_MAX;                                               Line 1586
                                                                                
  if (split_type == type_chunk_bytes || split_type == type_chunk_lines)         Line 1588
    {                                                                           
      file_size = input_file_size (STDIN_FILENO, &in_stat_buf,                  Line 1590
                                   buf, in_blk_size);                           Line 1591
      if (file_size < 0)                                                        Line 1592
        die (EXIT_FAILURE, errno, _("%s: cannot determine file size"),          Line 1593
             quotef (infile));                                                  Line 1594
      initial_read = MIN (file_size, in_blk_size);                              Line 1595
      /* Overflow, and sanity checking.  */                                     
      if (OFF_T_MAX < n_units)                                                  Line 1597
        {                                                                       
          char buffer[INT_BUFSIZE_BOUND (uintmax_t)];                           Line 1599
          die (EXIT_FAILURE, EOVERFLOW, "%s: %s",                               Line 1600
               _("invalid number of chunks"),                                   Line 1601
               quote (umaxtostr (n_units, buffer)));                            Line 1602
        }                                                                       
      /* increase file_size to n_units here, so that we still process           
         any input data, and create empty files for the rest.  */               
      file_size = MAX (file_size, n_units);                                     Line 1606
    }                                                                           
                                                                                
  /* When filtering, closure of one pipe must not terminate the process,        
     as there may still be other streams expecting input from us.  */           
  if (filter_command)                                                           Line 1611
    {                                                                           
      struct sigaction act;                                                     Line 1613
      sigemptyset (&newblocked);                                                Line 1614
      sigaction (SIGPIPE, NULL, &act);                                          Line 1615
      if (act.sa_handler != SIG_IGN)                                            Line 1616
        sigaddset (&newblocked, SIGPIPE);                                       Line 1617
      sigprocmask (SIG_BLOCK, &newblocked, &oldblocked);                        Line 1618
    }                                                                           
                                                                                
  switch (split_type)                                                           Line 1621
    {                                                                           
    case type_digits:                                                           Line 1623
    case type_lines:                                                            Line 1624
      lines_split (n_units, buf, in_blk_size);                                  Line 1625
      break;                                                                    Line 1626
                                                                                
    case type_bytes:                                                            Line 1628
      bytes_split (n_units, buf, in_blk_size, SIZE_MAX, 0);                     Line 1629
      break;                                                                    Line 1630
                                                                                
    case type_byteslines:                                                       Line 1632
      line_bytes_split (n_units, buf, in_blk_size);                             Line 1633
      break;                                                                    Line 1634
                                                                                
    case type_chunk_bytes:                                                      Line 1636
      if (k_units == 0)                                                         Line 1637
        bytes_split (file_size / n_units, buf, in_blk_size, initial_read,       Line 1638
                     n_units);                                                  Line 1639
      else                                                                      Line 1640
        bytes_chunk_extract (k_units, n_units, buf, in_blk_size, initial_read,  Line 1641
                             file_size);                                        Line 1642
      break;                                                                    Line 1643
                                                                                
    case type_chunk_lines:                                                      Line 1645
      lines_chunk_split (k_units, n_units, buf, in_blk_size, initial_read,      Line 1646
                         file_size);                                            Line 1647
      break;                                                                    Line 1648
                                                                                
    case type_rr:                                                               Line 1650
      /* Note, this is like 'sed -n ${k}~${n}p' when k > 0,                     
         but the functionality is provided for symmetry.  */                    
      lines_rr (k_units, n_units, buf, in_blk_size);                            Line 1653
      break;                                                                    Line 1654
                                                                                
    default:                                                                    Line 1656
      abort ();                                                                 ...!common auto-comment...
    }                                                                           
                                                                                
  IF_LINT (free (b));                                                           Line 1660
                                                                                
  if (close (STDIN_FILENO) != 0)                                                Line 1662...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, "%s", quotef (infile));                           Line 1663
  closeout (NULL, output_desc, filter_pid, outfile);                            Line 1664
                                                                                
  return EXIT_SUCCESS;                                                          Line 1666
}                                                                               Block 23