/* dd -- convert a file while copying it.                                       This is the dd utility
   Copyright (C) 1985-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
                                                                                
/* Written by Paul Rubin, David MacKenzie, and Stuart Kemp. */                  
                                                                                
#include <config.h>                                                             Provides system specific information
                                                                                
#define SWAB_ALIGN_OFFSET 2                                                     Line 21
                                                                                
#include <sys/types.h>                                                          Provides system data types
#include <signal.h>                                                             ...!includes auto-comment...
#include <getopt.h>                                                             ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "close-stream.h"                                                       ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "fd-reopen.h"                                                          ...!includes auto-comment...
#include "gethrxtime.h"                                                         ...!includes auto-comment......!includes auto-comment...
#include "human.h"                                                              ...!includes auto-comment...
#include "ioblksize.h"                                                          ...!includes auto-comment...
#include "long-options.h"                                                       ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "verror.h"                                                             ...!includes auto-comment......!includes auto-comment...
#include "xstrtol.h"                                                            ...!includes auto-comment...
#include "xtime.h"                                                              ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "dd"                                                       Line 42
                                                                                
#define AUTHORS \                                                               Line 44
  proper_name ("Paul Rubin"), \                                                 Line 45
  proper_name ("David MacKenzie"), \                                            Line 46
  proper_name ("Stuart Kemp")                                                   Line 47
                                                                                
static struct option const long_options[] =                                     Line 49
{                                                                               
  {NULL, 0, NULL, 0}                                                            Line 51
};                                                                              Block 1
                                                                                
/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is           
   present.  */                                                                 
#ifndef SA_NOCLDSTOP                                                            Line 56
# define SA_NOCLDSTOP 0                                                         Line 57
# define sigprocmask(How, Set, Oset) /* empty */                                Line 58
# define sigset_t int                                                           Line 59
# if ! HAVE_SIGINTERRUPT                                                        Line 60
#  define siginterrupt(sig, flag) /* empty */                                   Line 61
# endif                                                                         Line 62
#endif                                                                          Line 63
                                                                                
/* NonStop circa 2011 lacks SA_RESETHAND; see Bug#9076.  */                     
#ifndef SA_RESETHAND                                                            Line 66
# define SA_RESETHAND 0                                                         Line 67
#endif                                                                          Line 68
                                                                                
#ifndef SIGINFO                                                                 Line 70
# define SIGINFO SIGUSR1                                                        Line 71
#endif                                                                          Line 72
                                                                                
/* This may belong in GNULIB's fcntl module instead.                            
   Define O_CIO to 0 if it is not supported by this OS. */                      
#ifndef O_CIO                                                                   Line 76
# define O_CIO 0                                                                Line 77
#endif                                                                          Line 78
                                                                                
/* On AIX 5.1 and AIX 5.2, O_NOCACHE is defined via <fcntl.h>                   
   and would interfere with our use of that name, below.  */                    
#undef O_NOCACHE                                                                Line 82
                                                                                
#if ! HAVE_FDATASYNC                                                            Line 84
# define fdatasync(fd) (errno = ENOSYS, -1)                                     Line 85
#endif                                                                          Line 86
                                                                                
#define output_char(c)    \                                                     Line 88
  do      \                                                                     Line 89
    {      \                                                                    Line 90
      obuf[oc++] = (c);    \                                                    Line 91
      if (oc >= output_blocksize)  \                                            Line 92
        write_output ();   \                                                    Line 93
    }      \                                                                    Line 94Block 2
  while (0)                                                                     Line 95
                                                                                
/* Default input and output blocksize. */                                       
#define DEFAULT_BLOCKSIZE 512                                                   Line 98
                                                                                
/* How many bytes to add to the input and output block sizes before invoking    
   malloc.  See dd_copy for details.  INPUT_BLOCK_SLOP must be no less than     
   OUTPUT_BLOCK_SLOP.  */                                                       
#define INPUT_BLOCK_SLOP (2 * SWAB_ALIGN_OFFSET + 2 * page_size - 1)            Line 103
#define OUTPUT_BLOCK_SLOP (page_size - 1)                                       Line 104
                                                                                
/* Maximum blocksize for the given SLOP.                                        
   Keep it smaller than SIZE_MAX - SLOP, so that we can                         
   allocate buffers that size.  Keep it smaller than SSIZE_MAX, for             
   the benefit of system calls like "read".  And keep it smaller than           
   OFF_T_MAX, for the benefit of the large-offset seek code.  */                
#define MAX_BLOCKSIZE(slop) MIN (SIZE_MAX - (slop), MIN (SSIZE_MAX, OFF_T_MAX)) Line 111
                                                                                
/* Conversions bit masks. */                                                    
enum                                                                            Line 114
  {                                                                             
    C_ASCII = 01,                                                               Line 116
                                                                                
    C_EBCDIC = 02,                                                              Line 118
    C_IBM = 04,                                                                 Line 119
    C_BLOCK = 010,                                                              Line 120
    C_UNBLOCK = 020,                                                            Line 121
    C_LCASE = 040,                                                              Line 122
    C_UCASE = 0100,                                                             Line 123
    C_SWAB = 0200,                                                              Line 124
    C_NOERROR = 0400,                                                           Line 125
    C_NOTRUNC = 01000,                                                          Line 126
    C_SYNC = 02000,                                                             Line 127
                                                                                
    /* Use separate input and output buffers, and combine partial               
       input blocks. */                                                         
    C_TWOBUFS = 04000,                                                          Line 131
                                                                                
    C_NOCREAT = 010000,                                                         Line 133
    C_EXCL = 020000,                                                            Line 134
    C_FDATASYNC = 040000,                                                       Line 135
    C_FSYNC = 0100000,                                                          Line 136
                                                                                
    C_SPARSE = 0200000                                                          Line 138
  };                                                                            Block 3
                                                                                
/* Status levels.  */                                                           
enum                                                                            Line 142
  {                                                                             
    STATUS_NONE = 1,                                                            Line 144
    STATUS_NOXFER = 2,                                                          Line 145
    STATUS_DEFAULT = 3,                                                         Line 146
    STATUS_PROGRESS = 4                                                         Line 147
  };                                                                            Block 4
                                                                                
/* The name of the input file, or NULL for the standard input. */               
static char const *input_file = NULL;                                           Line 151
                                                                                
/* The name of the output file, or NULL for the standard output. */             
static char const *output_file = NULL;                                          Line 154
                                                                                
/* The page size on this host.  */                                              
static size_t page_size;                                                        Line 157
                                                                                
/* The number of bytes in which atomic reads are done. */                       
static size_t input_blocksize = 0;                                              Line 160
                                                                                
/* The number of bytes in which atomic writes are done. */                      
static size_t output_blocksize = 0;                                             Line 163
                                                                                
/* Conversion buffer size, in bytes.  0 prevents conversions. */                
static size_t conversion_blocksize = 0;                                         Line 166
                                                                                
/* Skip this many records of 'input_blocksize' bytes before input. */           
static uintmax_t skip_records = 0;                                              Line 169
                                                                                
/* Skip this many bytes before input in addition of 'skip_records'              
   records.  */                                                                 
static size_t skip_bytes = 0;                                                   Line 173
                                                                                
/* Skip this many records of 'output_blocksize' bytes before output. */         
static uintmax_t seek_records = 0;                                              Line 176
                                                                                
/* Skip this many bytes in addition to 'seek_records' records before            
   output.  */                                                                  
static uintmax_t seek_bytes = 0;                                                Line 180
                                                                                
/* Whether the final output was done with a seek (rather than a write).  */     
static bool final_op_was_seek;                                                  Line 183
                                                                                
/* Copy only this many records.  The default is effectively infinity.  */       
static uintmax_t max_records = (uintmax_t) -1;                                  Line 186
                                                                                
/* Copy this many bytes in addition to 'max_records' records.  */               
static size_t max_bytes = 0;                                                    Line 189
                                                                                
/* Bit vector of conversions to apply. */                                       
static int conversions_mask = 0;                                                Line 192
                                                                                
/* Open flags for the input and output files.  */                               
static int input_flags = 0;                                                     Line 195
static int output_flags = 0;                                                    Line 196
                                                                                
/* Status flags for what is printed to stderr.  */                              
static int status_level = STATUS_DEFAULT;                                       Line 199
                                                                                
/* If nonzero, filter characters through the translation table.  */             
static bool translation_needed = false;                                         Line 202
                                                                                
/* Number of partial blocks written. */                                         
static uintmax_t w_partial = 0;                                                 Line 205
                                                                                
/* Number of full blocks written. */                                            
static uintmax_t w_full = 0;                                                    Line 208
                                                                                
/* Number of partial blocks read. */                                            
static uintmax_t r_partial = 0;                                                 Line 211
                                                                                
/* Number of full blocks read. */                                               
static uintmax_t r_full = 0;                                                    Line 214
                                                                                
/* Number of bytes written.  */                                                 
static uintmax_t w_bytes = 0;                                                   Line 217
                                                                                
/* Time that dd started.  */                                                    
static xtime_t start_time;                                                      Line 220
                                                                                
/* Next time to report periodic progress.  */                                   
static xtime_t next_time;                                                       Line 223
                                                                                
/* If positive, the number of bytes output in the current progress line.  */    
static int progress_len;                                                        Line 226
                                                                                
/* True if input is seekable.  */                                               
static bool input_seekable;                                                     Line 229
                                                                                
/* Error number corresponding to initial attempt to lseek input.                
   If ESPIPE, do not issue any more diagnostics about it.  */                   
static int input_seek_errno;                                                    Line 233
                                                                                
/* File offset of the input, in bytes, along with a flag recording              
   whether it overflowed.  */                                                   
static uintmax_t input_offset;                                                  Line 237
static bool input_offset_overflow;                                              Line 238
                                                                                
/* True if a partial read should be diagnosed.  */                              
static bool warn_partial_read;                                                  Line 241
                                                                                
/* Records truncated by conv=block. */                                          
static uintmax_t r_truncate = 0;                                                Line 244
                                                                                
/* Output representation of newline and space characters.                       
   They change if we're converting to EBCDIC.  */                               
static char newline_character = '\n';                                           Line 248
static char space_character = ' ';                                              Line 249
                                                                                
/* Input buffer. */                                                             
static char *ibuf;                                                              Line 252
                                                                                
/* Output buffer. */                                                            
static char *obuf;                                                              Line 255
                                                                                
/* Current index into 'obuf'. */                                                
static size_t oc = 0;                                                           Line 258
                                                                                
/* Index into current line, for 'conv=block' and 'conv=unblock'.  */            
static size_t col = 0;                                                          Line 261
                                                                                
/* The set of signals that are caught.  */                                      
static sigset_t caught_signals;                                                 Line 264
                                                                                
/* If nonzero, the value of the pending fatal signal.  */                       
static sig_atomic_t volatile interrupt_signal;                                  Line 267
                                                                                
/* A count of the number of pending info signals that have been received.  */   
static sig_atomic_t volatile info_signal_count;                                 Line 270
                                                                                
/* Whether to discard cache for input or output.  */                            
static bool i_nocache, o_nocache;                                               Line 273
                                                                                
/* Whether to instruct the kernel to discard the complete file.  */             
static bool i_nocache_eof, o_nocache_eof;                                       Line 276
                                                                                
/* Function used for read (to handle iflag=fullblock parameter).  */            
static ssize_t (*iread_fnc) (int fd, char *buf, size_t size);                   Line 279
                                                                                
/* A longest symbol in the struct symbol_values tables below.  */               
#define LONGEST_SYMBOL "count_bytes"                                            Line 282
                                                                                
/* A symbol and the corresponding integer value.  */                            
struct symbol_value                                                             Line 285
{                                                                               
  char symbol[sizeof LONGEST_SYMBOL];                                           Line 287
  int value;                                                                    Line 288
};                                                                              Block 5
                                                                                
/* Conversion symbols, for conv="...".  */                                      
static struct symbol_value const conversions[] =                                Line 292
{                                                                               
  {"ascii", C_ASCII | C_UNBLOCK | C_TWOBUFS}, /* EBCDIC to ASCII. */            Line 294
  {"ebcdic", C_EBCDIC | C_BLOCK | C_TWOBUFS}, /* ASCII to EBCDIC. */            Line 295
  {"ibm", C_IBM | C_BLOCK | C_TWOBUFS}, /* Different ASCII to EBCDIC. */        Line 296
  {"block", C_BLOCK | C_TWOBUFS}, /* Variable to fixed length records. */       Line 297
  {"unblock", C_UNBLOCK | C_TWOBUFS}, /* Fixed to variable length records. */   Line 298
  {"lcase", C_LCASE | C_TWOBUFS}, /* Translate upper to lower case. */          Line 299
  {"ucase", C_UCASE | C_TWOBUFS}, /* Translate lower to upper case. */          Line 300
  {"sparse", C_SPARSE},  /* Try to sparsely write output. */                    Line 301
  {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */                      Line 302
  {"noerror", C_NOERROR}, /* Ignore i/o errors. */                              Line 303
  {"nocreat", C_NOCREAT}, /* Do not create output file.  */                     Line 304
  {"excl", C_EXCL},  /* Fail if the output file already exists.  */             Line 305
  {"notrunc", C_NOTRUNC}, /* Do not truncate output file. */                    Line 306
  {"sync", C_SYNC},  /* Pad input records to ibs with NULs. */                  Line 307
  {"fdatasync", C_FDATASYNC}, /* Synchronize output data before finishing.  */  Line 308
  {"fsync", C_FSYNC},  /* Also synchronize output metadata.  */                 Line 309
  {"", 0}                                                                       Line 310
};                                                                              Block 6
                                                                                
#define FFS_MASK(x) ((x) ^ ((x) & ((x) - 1)))                                   Line 313
enum                                                                            Line 314
  {                                                                             
    /* Compute a value that's bitwise disjoint from the union                   
       of all O_ values.  */                                                    
    v = ~(0                                                                     Line 318
          | O_APPEND                                                            Line 319
          | O_BINARY                                                            Line 320
          | O_CIO                                                               Line 321
          | O_DIRECT                                                            Line 322
          | O_DIRECTORY                                                         Line 323
          | O_DSYNC                                                             Line 324
          | O_NOATIME                                                           Line 325
          | O_NOCTTY                                                            Line 326
          | O_NOFOLLOW                                                          Line 327
          | O_NOLINKS                                                           Line 328
          | O_NONBLOCK                                                          Line 329
          | O_SYNC                                                              Line 330
          | O_TEXT                                                              Line 331
          ),                                                                    
                                                                                
    /* Use its lowest bits for private flags.  */                               
    O_FULLBLOCK = FFS_MASK (v),                                                 Line 335
    v2 = v ^ O_FULLBLOCK,                                                       Line 336
                                                                                
    O_NOCACHE = FFS_MASK (v2),                                                  Line 338
    v3 = v2 ^ O_NOCACHE,                                                        Line 339
                                                                                
    O_COUNT_BYTES = FFS_MASK (v3),                                              Line 341
    v4 = v3 ^ O_COUNT_BYTES,                                                    Line 342
                                                                                
    O_SKIP_BYTES = FFS_MASK (v4),                                               Line 344
    v5 = v4 ^ O_SKIP_BYTES,                                                     Line 345
                                                                                
    O_SEEK_BYTES = FFS_MASK (v5)                                                Line 347
  };                                                                            
                                                                                
/* Ensure that we got something.  */                                            
verify (O_FULLBLOCK != 0);                                                      Line 351
verify (O_NOCACHE != 0);                                                        Line 352
verify (O_COUNT_BYTES != 0);                                                    Line 353
verify (O_SKIP_BYTES != 0);                                                     Line 354
verify (O_SEEK_BYTES != 0);                                                     Line 355
                                                                                
#define MULTIPLE_BITS_SET(i) (((i) & ((i) - 1)) != 0)                           Line 357
                                                                                
/* Ensure that this is a single-bit value.  */                                  
verify ( ! MULTIPLE_BITS_SET (O_FULLBLOCK));                                    Line 360
verify ( ! MULTIPLE_BITS_SET (O_NOCACHE));                                      Line 361
verify ( ! MULTIPLE_BITS_SET (O_COUNT_BYTES));                                  Line 362
verify ( ! MULTIPLE_BITS_SET (O_SKIP_BYTES));                                   Line 363
verify ( ! MULTIPLE_BITS_SET (O_SEEK_BYTES));                                   Line 364
                                                                                
/* Flags, for iflag="..." and oflag="...".  */                                  
static struct symbol_value const flags[] =                                      Line 367
{                                                                               
  {"append",   O_APPEND},                                                       Line 369
  {"binary",   O_BINARY},                                                       Line 370
  {"cio",   O_CIO},                                                             Line 371
  {"direct",   O_DIRECT},                                                       Line 372
  {"directory",   O_DIRECTORY},                                                 Line 373
  {"dsync",   O_DSYNC},                                                         Line 374
  {"noatime",   O_NOATIME},                                                     Line 375
  {"nocache",   O_NOCACHE},   /* Discard cache.  */                             Line 376
  {"noctty",   O_NOCTTY},                                                       Line 377
  {"nofollow",   HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0},                     Line 378
  {"nolinks",   O_NOLINKS},                                                     Line 379
  {"nonblock",   O_NONBLOCK},                                                   Line 380
  {"sync",   O_SYNC},                                                           Line 381
  {"text",   O_TEXT},                                                           Line 382
  {"fullblock",   O_FULLBLOCK}, /* Accumulate full blocks from input.  */       Line 383
  {"count_bytes", O_COUNT_BYTES},                                               Line 384
  {"skip_bytes",  O_SKIP_BYTES},                                                Line 385
  {"seek_bytes",  O_SEEK_BYTES},                                                Line 386
  {"",  0}                                                                      Line 387
};                                                                              Block 8
                                                                                
/* Status, for status="...".  */                                                
static struct symbol_value const statuses[] =                                   Line 391
{                                                                               
  {"none", STATUS_NONE},                                                        Line 393
  {"noxfer", STATUS_NOXFER},                                                    Line 394
  {"progress", STATUS_PROGRESS},                                                Line 395
  {"",  0}                                                                      Line 396
};                                                                              Block 9
                                                                                
/* Translation table formed by applying successive transformations. */          
static unsigned char trans_table[256];                                          Line 400
                                                                                
/* Standard translation tables, taken from POSIX 1003.1-2013.                   
   Beware of imitations; there are lots of ASCII<->EBCDIC tables                
   floating around the net, perhaps valid for some applications but             
   not correct here.  */                                                        
                                                                                
static char const ascii_to_ebcdic[] =                                           Line 407
{                                                                               
  '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',               Line 409
  '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',               Line 410
  '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',               Line 411
  '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',               Line 412
  '\100', '\132', '\177', '\173', '\133', '\154', '\120', '\175',               Line 413
  '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',               Line 414
  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',               Line 415
  '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',               Line 416
  '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',               Line 417
  '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',               Line 418
  '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',               Line 419
  '\347', '\350', '\351', '\255', '\340', '\275', '\232', '\155',               Line 420
  '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',               Line 421
  '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',               Line 422
  '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',               Line 423
  '\247', '\250', '\251', '\300', '\117', '\320', '\137', '\007',               Line 424
  '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',               Line 425
  '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',               Line 426
  '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',               Line 427
  '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',               Line 428
  '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',               Line 429
  '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',               Line 430
  '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',               Line 431
  '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',               Line 432
  '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',               Line 433
  '\216', '\217', '\220', '\152', '\233', '\234', '\235', '\236',               Line 434
  '\237', '\240', '\252', '\253', '\254', '\112', '\256', '\257',               Line 435
  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',               Line 436
  '\270', '\271', '\272', '\273', '\274', '\241', '\276', '\277',               Line 437
  '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',               Line 438
  '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',               Line 439
  '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'                Line 440
};                                                                              Block 10
                                                                                
static char const ascii_to_ibm[] =                                              Line 443
{                                                                               
  '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',               Line 445
  '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',               Line 446
  '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',               Line 447
  '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',               Line 448
  '\100', '\132', '\177', '\173', '\133', '\154', '\120', '\175',               Line 449
  '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',               Line 450
  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',               Line 451
  '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',               Line 452
  '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',               Line 453
  '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',               Line 454
  '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',               Line 455
  '\347', '\350', '\351', '\255', '\340', '\275', '\137', '\155',               Line 456
  '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',               Line 457
  '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',               Line 458
  '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',               Line 459
  '\247', '\250', '\251', '\300', '\117', '\320', '\241', '\007',               Line 460
  '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',               Line 461
  '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',               Line 462
  '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',               Line 463
  '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',               Line 464
  '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',               Line 465
  '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',               Line 466
  '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',               Line 467
  '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',               Line 468
  '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',               Line 469
  '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236',               Line 470
  '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257',               Line 471
  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',               Line 472
  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',               Line 473
  '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',               Line 474
  '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',               Line 475
  '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'                Line 476
};                                                                              Block 11
                                                                                
static char const ebcdic_to_ascii[] =                                           Line 479
{                                                                               
  '\000', '\001', '\002', '\003', '\234', '\011', '\206', '\177',               Line 481
  '\227', '\215', '\216', '\013', '\014', '\015', '\016', '\017',               Line 482
  '\020', '\021', '\022', '\023', '\235', '\205', '\010', '\207',               Line 483
  '\030', '\031', '\222', '\217', '\034', '\035', '\036', '\037',               Line 484
  '\200', '\201', '\202', '\203', '\204', '\012', '\027', '\033',               Line 485
  '\210', '\211', '\212', '\213', '\214', '\005', '\006', '\007',               Line 486
  '\220', '\221', '\026', '\223', '\224', '\225', '\226', '\004',               Line 487
  '\230', '\231', '\232', '\233', '\024', '\025', '\236', '\032',               Line 488
  '\040', '\240', '\241', '\242', '\243', '\244', '\245', '\246',               Line 489
  '\247', '\250', '\325', '\056', '\074', '\050', '\053', '\174',               Line 490
  '\046', '\251', '\252', '\253', '\254', '\255', '\256', '\257',               Line 491
  '\260', '\261', '\041', '\044', '\052', '\051', '\073', '\176',               Line 492
  '\055', '\057', '\262', '\263', '\264', '\265', '\266', '\267',               Line 493
  '\270', '\271', '\313', '\054', '\045', '\137', '\076', '\077',               Line 494
  '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301',               Line 495
  '\302', '\140', '\072', '\043', '\100', '\047', '\075', '\042',               Line 496
  '\303', '\141', '\142', '\143', '\144', '\145', '\146', '\147',               Line 497
  '\150', '\151', '\304', '\305', '\306', '\307', '\310', '\311',               Line 498
  '\312', '\152', '\153', '\154', '\155', '\156', '\157', '\160',               Line 499
  '\161', '\162', '\136', '\314', '\315', '\316', '\317', '\320',               Line 500
  '\321', '\345', '\163', '\164', '\165', '\166', '\167', '\170',               Line 501
  '\171', '\172', '\322', '\323', '\324', '\133', '\326', '\327',               Line 502
  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',               Line 503
  '\340', '\341', '\342', '\343', '\344', '\135', '\346', '\347',               Line 504
  '\173', '\101', '\102', '\103', '\104', '\105', '\106', '\107',               Line 505
  '\110', '\111', '\350', '\351', '\352', '\353', '\354', '\355',               Line 506
  '\175', '\112', '\113', '\114', '\115', '\116', '\117', '\120',               Line 507
  '\121', '\122', '\356', '\357', '\360', '\361', '\362', '\363',               Line 508
  '\134', '\237', '\123', '\124', '\125', '\126', '\127', '\130',               Line 509
  '\131', '\132', '\364', '\365', '\366', '\367', '\370', '\371',               Line 510
  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',               Line 511
  '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377'                Line 512
};                                                                              Block 12
                                                                                
/* True if we need to close the standard output *stream*.  */                   
static bool close_stdout_required = true;                                       Line 516
                                                                                
/* The only reason to close the standard output *stream* is if                  
   parse_long_options fails (as it does for --help or --version).               
   In any other case, dd uses only the STDOUT_FILENO file descriptor,           
   and the "cleanup" function calls "close (STDOUT_FILENO)".                    
   Closing the file descriptor and then letting the usual atexit-run            
   close_stdout function call "fclose (stdout)" would result in a               
   harmless failure of the close syscall (with errno EBADF).                    
   This function serves solely to avoid the unnecessary close_stdout            
   call, once parse_long_options has succeeded.                                 
   Meanwhile, we guarantee that the standard error stream is flushed,           
   by inlining the last half of close_stdout as needed.  */                     
static void                                                                     Line 529
maybe_close_stdout (void)                                                       Line 530
{                                                                               
  if (close_stdout_required)                                                    Line 532
    close_stdout ();                                                            Line 533
  else if (close_stream (stderr) != 0)                                          Line 534
    _exit (EXIT_FAILURE);                                                       Line 535
}                                                                               Block 13
                                                                                
/* Like error() but handle any pending newline.  */                             
                                                                                
static void _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4))                           Line 540
nl_error (int status, int errnum, const char *fmt, ...)                         Line 541
{                                                                               
  if (0 < progress_len)                                                         Line 543
    {                                                                           
      fputc ('\n', stderr);                                                     Line 545
      progress_len = 0;                                                         Line 546
    }                                                                           
                                                                                
  va_list ap;                                                                   Line 549
  va_start (ap, fmt);                                                           Line 550
  verror (status, errnum, fmt, ap);                                             Line 551
  va_end (ap);                                                                  Line 552
}                                                                               Block 14
                                                                                
#define error nl_error                                                          Line 555
                                                                                
void                                                                            Line 557
usage (int status)                                                              Line 558
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 560
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 562
    {                                                                           
      printf (_("\                                                              Line 564
Usage: %s [OPERAND]...\n\                                                       Line 565
  or:  %s OPTION\n\                                                             Line 566
"),                                                                             Line 567
              program_name, program_name);                                      Line 568
      fputs (_("\                                                               Line 569
Copy a file, converting and formatting according to the operands.\n\            Line 570
\n\                                                                             
  bs=BYTES        read and write up to BYTES bytes at a time (default: 512);\n\ Line 572
                  overrides ibs and obs\n\                                      Line 573
  cbs=BYTES       convert BYTES bytes at a time\n\                              Line 574
  conv=CONVS      convert the file as per the comma separated symbol list\n\    Line 575
  count=N         copy only N input blocks\n\                                   Line 576
  ibs=BYTES       read up to BYTES bytes at a time (default: 512)\n\            Line 577
"), stdout);                                                                    Line 578
      fputs (_("\                                                               Line 579
  if=FILE         read from FILE instead of stdin\n\                            Line 580
  iflag=FLAGS     read as per the comma separated symbol list\n\                Line 581
  obs=BYTES       write BYTES bytes at a time (default: 512)\n\                 Line 582
  of=FILE         write to FILE instead of stdout\n\                            Line 583
  oflag=FLAGS     write as per the comma separated symbol list\n\               Line 584
  seek=N          skip N obs-sized blocks at start of output\n\                 Line 585
  skip=N          skip N ibs-sized blocks at start of input\n\                  Line 586
  status=LEVEL    The LEVEL of information to print to stderr;\n\               Line 587
                  'none' suppresses everything but error messages,\n\           Line 588
                  'noxfer' suppresses the final transfer statistics,\n\         Line 589
                  'progress' shows periodic transfer statistics\n\              Line 590
"), stdout);                                                                    Line 591
      fputs (_("\                                                               Line 592
\n\                                                                             
N and BYTES may be followed by the following multiplicative suffixes:\n\        Line 594
c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024, xM=M,\n\           Line 595
GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y.\n\            Line 596
Binary prefixes can be used, too: KiB=K, MiB=M, and so on.\n\                   Line 597
\n\                                                                             
Each CONV symbol may be:\n\                                                     Line 599
\n\                                                                             
"), stdout);                                                                    Line 601
      fputs (_("\                                                               Line 602
  ascii     from EBCDIC to ASCII\n\                                             Line 603
  ebcdic    from ASCII to EBCDIC\n\                                             Line 604
  ibm       from ASCII to alternate EBCDIC\n\                                   Line 605
  block     pad newline-terminated records with spaces to cbs-size\n\           Line 606
  unblock   replace trailing spaces in cbs-size records with newline\n\         Line 607
  lcase     change upper case to lower case\n\                                  Line 608
  ucase     change lower case to upper case\n\                                  Line 609
  sparse    try to seek rather than write the output for NUL input blocks\n\    Line 610
  swab      swap every pair of input bytes\n\                                   Line 611
  sync      pad every input block with NULs to ibs-size; when used\n\           Line 612
            with block or unblock, pad with spaces rather than NULs\n\          Line 613
"), stdout);                                                                    Line 614
      fputs (_("\                                                               Line 615
  excl      fail if the output file already exists\n\                           Line 616
  nocreat   do not create the output file\n\                                    Line 617
  notrunc   do not truncate the output file\n\                                  Line 618
  noerror   continue after read errors\n\                                       Line 619
  fdatasync  physically write output file data before finishing\n\              Line 620
  fsync     likewise, but also write metadata\n\                                Line 621
"), stdout);                                                                    Line 622
      fputs (_("\                                                               Line 623
\n\                                                                             
Each FLAG symbol may be:\n\                                                     Line 625
\n\                                                                             
  append    append mode (makes sense only for output; conv=notrunc suggested)\n\Line 627
"), stdout);                                                                    Line 628
      if (O_CIO)                                                                Line 629
        fputs (_("  cio       use concurrent I/O for data\n"), stdout);         Line 630
      if (O_DIRECT)                                                             Line 631
        fputs (_("  direct    use direct I/O for data\n"), stdout);             Line 632
      if (O_DIRECTORY)                                                          Line 633
        fputs (_("  directory  fail unless a directory\n"), stdout);            Line 634
      if (O_DSYNC)                                                              Line 635
        fputs (_("  dsync     use synchronized I/O for data\n"), stdout);       Line 636
      if (O_SYNC)                                                               Line 637
        fputs (_("  sync      likewise, but also for metadata\n"), stdout);     Line 638
      fputs (_("  fullblock  accumulate full blocks of input (iflag only)\n"),  Line 639
             stdout);                                                           Line 640
      if (O_NONBLOCK)                                                           Line 641
        fputs (_("  nonblock  use non-blocking I/O\n"), stdout);                Line 642
      if (O_NOATIME)                                                            Line 643
        fputs (_("  noatime   do not update access time\n"), stdout);           Line 644
#if HAVE_POSIX_FADVISE                                                          Line 645
      if (O_NOCACHE)                                                            Line 646
        fputs (_("  nocache   Request to drop cache.  See also oflag=sync\n"),  Line 647
               stdout);                                                         Line 648
#endif                                                                          Line 649
      if (O_NOCTTY)                                                             Line 650
        fputs (_("  noctty    do not assign controlling terminal from file\n"), Line 651
               stdout);                                                         Line 652
      if (HAVE_WORKING_O_NOFOLLOW)                                              Line 653
        fputs (_("  nofollow  do not follow symlinks\n"), stdout);              Line 654
      if (O_NOLINKS)                                                            Line 655
        fputs (_("  nolinks   fail if multiply-linked\n"), stdout);             Line 656
      if (O_BINARY)                                                             Line 657
        fputs (_("  binary    use binary I/O for data\n"), stdout);             Line 658
      if (O_TEXT)                                                               Line 659
        fputs (_("  text      use text I/O for data\n"), stdout);               Line 660
      if (O_COUNT_BYTES)                                                        Line 661
        fputs (_("  count_bytes  treat 'count=N' as a byte count (iflag only)\n\Line 662
"), stdout);                                                                    Line 663
      if (O_SKIP_BYTES)                                                         Line 664
        fputs (_("  skip_bytes  treat 'skip=N' as a byte count (iflag only)\n\  Line 665
"), stdout);                                                                    Line 666
      if (O_SEEK_BYTES)                                                         Line 667
        fputs (_("  seek_bytes  treat 'seek=N' as a byte count (oflag only)\n\  Line 668
"), stdout);                                                                    Line 669
                                                                                
      {                                                                         
        printf (_("\                                                            Line 672
\n\                                                                             
Sending a %s signal to a running 'dd' process makes it\n\                       Line 674
print I/O statistics to standard error and then resume copying.\n\              Line 675
\n\                                                                             
Options are:\n\                                                                 Line 677
\n\                                                                             
"), SIGINFO == SIGUSR1 ? "USR1" : "INFO");                                      Line 679
      }                                                                         
                                                                                
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 682
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 683
      emit_ancillary_info (PROGRAM_NAME);                                       Line 684
    }                                                                           
  exit (status);                                                                Line 686
}                                                                               Block 15
                                                                                
/* Common options to use when displaying sizes and rates.  */                   
                                                                                
enum { human_opts = (human_autoscale | human_round_to_nearest                   Line 691
                     | human_space_before_unit | human_SI | human_B) };         Line 692Block 16
                                                                                
/* Ensure input buffer IBUF is allocated.  */                                   
                                                                                
static void                                                                     Line 696
alloc_ibuf (void)                                                               Line 697
{                                                                               
  if (ibuf)                                                                     Line 699
    return;                                                                     Line 700
                                                                                
  char *real_buf = malloc (input_blocksize + INPUT_BLOCK_SLOP);                 Line 702
  if (!real_buf)                                                                Line 703
    {                                                                           
      uintmax_t ibs = input_blocksize;                                          Line 705
      char hbuf[LONGEST_HUMAN_READABLE + 1];                                    Line 706
      die (EXIT_FAILURE, 0,                                                     Line 707
           _("memory exhausted by input buffer of size %"PRIuMAX" bytes (%s)"), Line 708
           ibs,                                                                 Line 709
           human_readable (input_blocksize, hbuf,                               Line 710
                           human_opts | human_base_1024, 1, 1));                Line 711
    }                                                                           
                                                                                
  real_buf += SWAB_ALIGN_OFFSET; /* allow space for swab */                     Line 714
                                                                                
  ibuf = ptr_align (real_buf, page_size);                                       Line 716
}                                                                               Block 17
                                                                                
/* Ensure output buffer OBUF is allocated/initialized.  */                      
                                                                                
static void                                                                     Line 721
alloc_obuf (void)                                                               Line 722
{                                                                               
  if (obuf)                                                                     Line 724
    return;                                                                     Line 725
                                                                                
  if (conversions_mask & C_TWOBUFS)                                             Line 727
    {                                                                           
      /* Page-align the output buffer, too.  */                                 
      char *real_obuf = malloc (output_blocksize + OUTPUT_BLOCK_SLOP);          Line 730
      if (!real_obuf)                                                           Line 731
        {                                                                       
          uintmax_t obs = output_blocksize;                                     Line 733
          char hbuf[LONGEST_HUMAN_READABLE + 1];                                Line 734
          die (EXIT_FAILURE, 0,                                                 Line 735
               _("memory exhausted by output buffer of size %"PRIuMAX           Line 736
                 " bytes (%s)"),                                                Line 737
               obs,                                                             Line 738
               human_readable (output_blocksize, hbuf,                          Line 739
                               human_opts | human_base_1024, 1, 1));            Line 740
        }                                                                       
      obuf = ptr_align (real_obuf, page_size);                                  Line 742
    }                                                                           
  else                                                                          Line 744
    {                                                                           
      alloc_ibuf ();                                                            Line 746
      obuf = ibuf;                                                              Line 747
    }                                                                           
}                                                                               Block 18
                                                                                
static void                                                                     Line 751
translate_charset (char const *new_trans)                                       Line 752
{                                                                               
  for (int i = 0; i < 256; i++)                                                 Line 754
    trans_table[i] = new_trans[trans_table[i]];                                 Line 755
  translation_needed = true;                                                    Line 756
}                                                                               Block 19
                                                                                
/* Return true if I has more than one bit set.  I must be nonnegative.  */      
                                                                                
static inline bool                                                              Line 761
multiple_bits_set (int i)                                                       Line 762
{                                                                               
  return MULTIPLE_BITS_SET (i);                                                 Line 764
}                                                                               Block 20
                                                                                
static bool                                                                     Line 767
abbreviation_lacks_prefix (char const *message)                                 Line 768
{                                                                               
  return message[strlen (message) - 2] == ' ';                                  Line 770
}                                                                               Block 21
                                                                                
/* Print transfer statistics.  */                                               
                                                                                
static void                                                                     Line 775
print_xfer_stats (xtime_t progress_time)                                        Line 776
{                                                                               
  xtime_t now = progress_time ? progress_time : gethrxtime ();                  Line 778
  static char const slash_s[] = "/s";                                           Line 779
  char hbuf[3][LONGEST_HUMAN_READABLE + sizeof slash_s];                        Line 780
  double delta_s;                                                               Line 781
  char const *bytes_per_second;                                                 Line 782
  char const *si = human_readable (w_bytes, hbuf[0], human_opts, 1, 1);         Line 783
  char const *iec = human_readable (w_bytes, hbuf[1],                           Line 784
                                    human_opts | human_base_1024, 1, 1);        Line 785
                                                                                
  /* Use integer arithmetic to compute the transfer rate,                       
     since that makes it easy to use SI abbreviations.  */                      
  char *bpsbuf = hbuf[2];                                                       Line 789
  int bpsbufsize = sizeof hbuf[2];                                              Line 790
  if (start_time < now)                                                         Line 791
    {                                                                           
      double XTIME_PRECISIONe0 = XTIME_PRECISION;                               Line 793
      uintmax_t delta_xtime = now;                                              Line 794
      delta_xtime -= start_time;                                                Line 795
      delta_s = delta_xtime / XTIME_PRECISIONe0;                                Line 796
      bytes_per_second = human_readable (w_bytes, bpsbuf, human_opts,           Line 797
                                         XTIME_PRECISION, delta_xtime);         Line 798
      strcat (bytes_per_second - bpsbuf + bpsbuf, slash_s);                     Line 799
    }                                                                           
  else                                                                          Line 801
    {                                                                           
      delta_s = 0;                                                              Line 803
      snprintf (bpsbuf, bpsbufsize, "%s B/s", _("Infinity"));                   Line 804
      bytes_per_second = bpsbuf;                                                Line 805
    }                                                                           
                                                                                
  if (progress_time)                                                            Line 808
    fputc ('\r', stderr);                                                       Line 809
                                                                                
  /* Use full seconds when printing progress, since the progress                
     report is output once per second and there is little point                 
     displaying any subsecond jitter.  Use default precision with %g            
     otherwise, as this provides more-useful output then.  With long            
     transfers %g can generate a number with an exponent; that is OK.  */       
  char delta_s_buf[24];                                                         Line 816
  snprintf (delta_s_buf, sizeof delta_s_buf,                                    Line 817
            progress_time ? "%.0f s" : "%g s", delta_s);                        Line 818
                                                                                
  int stats_len                                                                 Line 820
    = (abbreviation_lacks_prefix (si)                                           Line 821
       ? fprintf (stderr,                                                       Line 822
                  ngettext ("%"PRIuMAX" byte copied, %s, %s",                   Line 823
                            "%"PRIuMAX" bytes copied, %s, %s",                  Line 824
                            select_plural (w_bytes)),                           Line 825
                  w_bytes, delta_s_buf, bytes_per_second)                       Line 826
       : abbreviation_lacks_prefix (iec)                                        Line 827
       ? fprintf (stderr,                                                       Line 828
                  _("%"PRIuMAX" bytes (%s) copied, %s, %s"),                    Line 829
                  w_bytes, si, delta_s_buf, bytes_per_second)                   Line 830
       : fprintf (stderr,                                                       Line 831
                  _("%"PRIuMAX" bytes (%s, %s) copied, %s, %s"),                Line 832
                  w_bytes, si, iec, delta_s_buf, bytes_per_second));            Line 833
                                                                                
  if (progress_time)                                                            Line 835
    {                                                                           
      /* Erase any trailing junk on the output line by outputting               
         spaces.  In theory this could glitch the display because the           
         formatted translation of a line describing a larger file               
         could consume fewer screen columns than the strlen difference          
         from the previously formatted translation.  In practice this           
         does not seem to be a problem.  */                                     
      if (0 <= stats_len && stats_len < progress_len)                           Line 843
        fprintf (stderr, "%*s", progress_len - stats_len, "");                  Line 844
      progress_len = stats_len;                                                 Line 845
    }                                                                           
  else                                                                          Line 847
    fputc ('\n', stderr);                                                       Line 848
}                                                                               Block 22
                                                                                
static void                                                                     Line 851
print_stats (void)                                                              Line 852
{                                                                               
  if (status_level == STATUS_NONE)                                              Line 854
    return;                                                                     Line 855
                                                                                
  if (0 < progress_len)                                                         Line 857
    {                                                                           
      fputc ('\n', stderr);                                                     Line 859
      progress_len = 0;                                                         Line 860
    }                                                                           
                                                                                
  fprintf (stderr,                                                              Line 863
           _("%"PRIuMAX"+%"PRIuMAX" records in\n"                               Line 864
             "%"PRIuMAX"+%"PRIuMAX" records out\n"),                            Line 865
           r_full, r_partial, w_full, w_partial);                               Line 866
                                                                                
  if (r_truncate != 0)                                                          Line 868
    fprintf (stderr,                                                            Line 869
             ngettext ("%"PRIuMAX" truncated record\n",                         Line 870
                       "%"PRIuMAX" truncated records\n",                        Line 871
                       select_plural (r_truncate)),                             Line 872
             r_truncate);                                                       Line 873
                                                                                
  if (status_level == STATUS_NOXFER)                                            Line 875
    return;                                                                     Line 876
                                                                                
  print_xfer_stats (0);                                                         Line 878
}                                                                               Block 23
                                                                                
/* An ordinary signal was received; arrange for the program to exit.  */        
                                                                                
static void                                                                     Line 883
interrupt_handler (int sig)                                                     Line 884
{                                                                               
  if (! SA_RESETHAND)                                                           Line 886
    signal (sig, SIG_DFL);                                                      Line 887
  interrupt_signal = sig;                                                       Line 888
}                                                                               Block 24
                                                                                
/* An info signal was received; arrange for the program to print status.  */    
                                                                                
static void                                                                     Line 893
siginfo_handler (int sig)                                                       Line 894
{                                                                               
  if (! SA_NOCLDSTOP)                                                           Line 896
    signal (sig, siginfo_handler);                                              Line 897
  info_signal_count++;                                                          Line 898
}                                                                               Block 25
                                                                                
/* Install the signal handlers.  */                                             
                                                                                
static void                                                                     Line 903
install_signal_handlers (void)                                                  Line 904
{                                                                               
  bool catch_siginfo = ! (SIGINFO == SIGUSR1 && getenv ("POSIXLY_CORRECT"));    Line 906
                                                                                
#if SA_NOCLDSTOP                                                                Line 908
                                                                                
  struct sigaction act;                                                         Line 910
  sigemptyset (&caught_signals);                                                Line 911
  if (catch_siginfo)                                                            Line 912
    sigaddset (&caught_signals, SIGINFO);                                       Line 913
  sigaction (SIGINT, NULL, &act);                                               Line 914
  if (act.sa_handler != SIG_IGN)                                                Line 915
    sigaddset (&caught_signals, SIGINT);                                        Line 916
  act.sa_mask = caught_signals;                                                 Line 917
                                                                                
  if (sigismember (&caught_signals, SIGINFO))                                   Line 919
    {                                                                           
      act.sa_handler = siginfo_handler;                                         Line 921
      /* Note we don't use SA_RESTART here and instead                          
         handle EINTR explicitly in iftruncate() etc.                           
         to avoid blocking on noncommitted read()/write() calls.  */            
      act.sa_flags = 0;                                                         Line 925
      sigaction (SIGINFO, &act, NULL);                                          Line 926
    }                                                                           
                                                                                
  if (sigismember (&caught_signals, SIGINT))                                    Line 929
    {                                                                           
      act.sa_handler = interrupt_handler;                                       Line 931
      act.sa_flags = SA_NODEFER | SA_RESETHAND;                                 Line 932
      sigaction (SIGINT, &act, NULL);                                           Line 933
    }                                                                           
                                                                                
#else                                                                           Line 936
                                                                                
  if (catch_siginfo)                                                            Line 938
    {                                                                           
      signal (SIGINFO, siginfo_handler);                                        Line 940
      siginterrupt (SIGINFO, 1);                                                Line 941
    }                                                                           
  if (signal (SIGINT, SIG_IGN) != SIG_IGN)                                      Line 943
    {                                                                           
      signal (SIGINT, interrupt_handler);                                       Line 945
      siginterrupt (SIGINT, 1);                                                 Line 946
    }                                                                           
#endif                                                                          Line 948
}                                                                               Block 26
                                                                                
static void                                                                     Line 951
cleanup (void)                                                                  Line 952
{                                                                               
  if (close (STDIN_FILENO) < 0)                                                 Line 954...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("closing input file %s"), quoteaf (input_file));Line 955
                                                                                
  /* Don't remove this call to close, even though close_stdout                  
     closes standard output.  This close is necessary when cleanup              
     is called as part of a signal handler.  */                                 
  if (close (STDOUT_FILENO) < 0)                                                Line 960...!syscalls auto-comment...
    die (EXIT_FAILURE, errno,                                                   Line 961
         _("closing output file %s"), quoteaf (output_file));                   Line 962
}                                                                               Block 27
                                                                                
/* Process any pending signals.  If signals are caught, this function           
   should be called periodically.  Ideally there should never be an             
   unbounded amount of time when signals are not being processed.  */           
                                                                                
static void                                                                     Line 969
process_signals (void)                                                          Line 970
{                                                                               
  while (interrupt_signal || info_signal_count)                                 Line 972
    {                                                                           
      int interrupt;                                                            Line 974
      int infos;                                                                Line 975
      sigset_t oldset;                                                          Line 976
                                                                                
      sigprocmask (SIG_BLOCK, &caught_signals, &oldset);                        Line 978
                                                                                
      /* Reload interrupt_signal and info_signal_count, in case a new           
         signal was handled before sigprocmask took effect.  */                 
      interrupt = interrupt_signal;                                             Line 982
      infos = info_signal_count;                                                Line 983
                                                                                
      if (infos)                                                                Line 985
        info_signal_count = infos - 1;                                          Line 986
                                                                                
      sigprocmask (SIG_SETMASK, &oldset, NULL);                                 Line 988
                                                                                
      if (interrupt)                                                            Line 990
        cleanup ();                                                             Line 991
      print_stats ();                                                           Line 992
      if (interrupt)                                                            Line 993
        raise (interrupt);                                                      Line 994
    }                                                                           
}                                                                               Block 28
                                                                                
static void                                                                     Line 998
finish_up (void)                                                                Line 999
{                                                                               
  cleanup ();                                                                   Line 1001
  print_stats ();                                                               Line 1002
  process_signals ();                                                           Line 1003
}                                                                               Block 29
                                                                                
static void ATTRIBUTE_NORETURN                                                  Line 1006
quit (int code)                                                                 Line 1007
{                                                                               
  finish_up ();                                                                 Line 1009
  exit (code);                                                                  Line 1010
}                                                                               Block 30
                                                                                
/* Return LEN rounded down to a multiple of IO_BUFSIZE                          
   (to minimize calls to the expensive posix_fadvise(,POSIX_FADV_DONTNEED),     
   while storing the remainder internally per FD.                               
   Pass LEN == 0 to get the current remainder.  */                              
                                                                                
static off_t                                                                    Line 1018
cache_round (int fd, off_t len)                                                 Line 1019
{                                                                               
  static off_t i_pending, o_pending;                                            Line 1021
  off_t *pending = (fd == STDIN_FILENO ? &i_pending : &o_pending);              Line 1022
                                                                                
  if (len)                                                                      Line 1024
    {                                                                           
      uintmax_t c_pending = *pending + len;                                     Line 1026
      *pending = c_pending % IO_BUFSIZE;                                        Line 1027
      if (c_pending > *pending)                                                 Line 1028
        len = c_pending - *pending;                                             Line 1029
      else                                                                      Line 1030
        len = 0;                                                                Line 1031
    }                                                                           
  else                                                                          Line 1033
    len = *pending;                                                             Line 1034
                                                                                
  return len;                                                                   Line 1036
}                                                                               Block 31
                                                                                
/* Discard the cache from the current offset of either                          
   STDIN_FILENO or STDOUT_FILENO.                                               
   Return true on success.  */                                                  
                                                                                
static bool                                                                     Line 1043
invalidate_cache (int fd, off_t len)                                            Line 1044
{                                                                               
  int adv_ret = -1;                                                             Line 1046
  off_t offset;                                                                 Line 1047
  bool nocache_eof = (fd == STDIN_FILENO ? i_nocache_eof : o_nocache_eof);      Line 1048
                                                                                
  /* Minimize syscalls.  */                                                     
  off_t clen = cache_round (fd, len);                                           Line 1051
  if (len && !clen)                                                             Line 1052
    return true; /* Don't advise this time.  */                                 Line 1053
  else if (! len && ! clen && ! nocache_eof)                                    Line 1054
    return true;                                                                Line 1055
  off_t pending = len ? cache_round (fd, 0) : 0;                                Line 1056
                                                                                
  if (fd == STDIN_FILENO)                                                       Line 1058
    {                                                                           
      if (input_seekable)                                                       Line 1060
        offset = input_offset;                                                  Line 1061
      else                                                                      Line 1062
        {                                                                       
          offset = -1;                                                          Line 1064
          errno = ESPIPE;                                                       Line 1065
        }                                                                       
    }                                                                           
  else                                                                          Line 1068
    {                                                                           
      static off_t output_offset = -2;                                          Line 1070
                                                                                
      if (output_offset != -1)                                                  Line 1072
        {                                                                       
          if (output_offset < 0)                                                Line 1074
            output_offset = lseek (fd, 0, SEEK_CUR);                            Line 1075
          else if (len)                                                         Line 1076
            output_offset += clen + pending;                                    Line 1077
        }                                                                       
                                                                                
      offset = output_offset;                                                   Line 1080
    }                                                                           
                                                                                
  if (0 <= offset)                                                              Line 1083
   {                                                                            
     if (! len && clen && nocache_eof)                                          Line 1085
       {                                                                        
         pending = clen;                                                        Line 1087
         clen = 0;                                                              Line 1088
       }                                                                        
                                                                                
     /* Note we're being careful here to only invalidate what                   
        we've read, so as not to dump any read ahead cache.                     
        Note also the kernel is conservative and only invalidates               
        full pages in the specified range.  */                                  
#if HAVE_POSIX_FADVISE                                                          Line 1095
     offset = offset - clen - pending;                                          Line 1096
     /* ensure full page specified when invalidating to eof.  */                
     if (clen == 0)                                                             Line 1098
       offset -= offset % page_size;                                            Line 1099
     adv_ret = posix_fadvise (fd, offset, clen, POSIX_FADV_DONTNEED);           Line 1100...!syscalls auto-comment...
#else                                                                           Line 1101
     errno = ENOTSUP;                                                           Line 1102
#endif                                                                          Line 1103
   }                                                                            
                                                                                
  return adv_ret != -1 ? true : false;                                          Line 1106
}                                                                               Block 32
                                                                                
/* Read from FD into the buffer BUF of size SIZE, processing any                
   signals that arrive before bytes are read.  Return the number of             
   bytes read if successful, -1 (setting errno) on failure.  */                 
                                                                                
static ssize_t                                                                  Line 1113
iread (int fd, char *buf, size_t size)                                          Line 1114...!syscalls auto-comment...
{                                                                               
  ssize_t nread;                                                                Line 1116
  static ssize_t prev_nread;                                                    Line 1117
                                                                                
  do                                                                            
    {                                                                           
      process_signals ();                                                       Line 1121
      nread = read (fd, buf, size);                                             Line 1122...!syscalls auto-comment...
      /* Ignore final read error with iflag=direct as that                      
         returns EINVAL due to the non aligned file offset.  */                 
      if (nread == -1 && errno == EINVAL                                        Line 1125
          && 0 < prev_nread && prev_nread < size                                Line 1126
          && (input_flags & O_DIRECT))                                          Line 1127
        {                                                                       
          errno = 0;                                                            Line 1129
          nread = 0;                                                            Line 1130
        }                                                                       
    }                                                                           
  while (nread < 0 && errno == EINTR);                                          Line 1133
                                                                                
  /* Short read may be due to received signal.  */                              
  if (0 < nread && nread < size)                                                Line 1136
    process_signals ();                                                         Line 1137
                                                                                
  if (0 < nread && warn_partial_read)                                           Line 1139
    {                                                                           
      if (0 < prev_nread && prev_nread < size)                                  Line 1141
        {                                                                       
          uintmax_t prev = prev_nread;                                          Line 1143
          if (status_level != STATUS_NONE)                                      Line 1144
            error (0, 0, ngettext (("warning: partial read (%"PRIuMAX" byte); " Line 1145...!syscalls auto-comment...
                                    "suggest iflag=fullblock"),                 Line 1146
                                   ("warning: partial read (%"PRIuMAX" bytes); "Line 1147...!syscalls auto-comment...
                                    "suggest iflag=fullblock"),                 Line 1148
                                   select_plural (prev)),                       Line 1149
                   prev);                                                       Line 1150
          warn_partial_read = false;                                            Line 1151
        }                                                                       
    }                                                                           
                                                                                
  prev_nread = nread;                                                           Line 1155
  return nread;                                                                 Line 1156
}                                                                               Block 33
                                                                                
/* Wrapper around iread function to accumulate full blocks.  */                 
static ssize_t                                                                  Line 1160
iread_fullblock (int fd, char *buf, size_t size)                                Line 1161
{                                                                               
  ssize_t nread = 0;                                                            Line 1163
                                                                                
  while (0 < size)                                                              Line 1165
    {                                                                           
      ssize_t ncurr = iread (fd, buf, size);                                    Line 1167...!syscalls auto-comment...
      if (ncurr < 0)                                                            Line 1168
        return ncurr;                                                           Line 1169
      if (ncurr == 0)                                                           Line 1170
        break;                                                                  Line 1171
      nread += ncurr;                                                           Line 1172
      buf   += ncurr;                                                           Line 1173
      size  -= ncurr;                                                           Line 1174
    }                                                                           
                                                                                
  return nread;                                                                 Line 1177
}                                                                               Block 34
                                                                                
/* Write to FD the buffer BUF of size SIZE, processing any signals              
   that arrive.  Return the number of bytes written, setting errno if           
   this is less than SIZE.  Keep trying if there are partial                    
   writes.  */                                                                  
                                                                                
static size_t                                                                   Line 1185
iwrite (int fd, char const *buf, size_t size)                                   Line 1186...!syscalls auto-comment...
{                                                                               
  size_t total_written = 0;                                                     Line 1188
                                                                                
  if ((output_flags & O_DIRECT) && size < output_blocksize)                     Line 1190
    {                                                                           
      int old_flags = fcntl (STDOUT_FILENO, F_GETFL);                           Line 1192...!syscalls auto-comment...
      if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0            Line 1193...!syscalls auto-comment...
          && status_level != STATUS_NONE)                                       Line 1194
        error (0, errno, _("failed to turn off O_DIRECT: %s"),                  Line 1195
               quotef (output_file));                                           Line 1196
                                                                                
      /* Since we have just turned off O_DIRECT for the final write,            
         we try to preserve some of its semantics.  */                          
                                                                                
      /* Call invalidate_cache() to setup the appropriate offsets               
         for subsequent calls.  */                                              
      o_nocache_eof = true;                                                     Line 1203
      invalidate_cache (STDOUT_FILENO, 0);                                      Line 1204
                                                                                
      /* Attempt to ensure that that final block is committed                   
         to disk as quickly as possible.  */                                    
      conversions_mask |= C_FSYNC;                                              Line 1208
                                                                                
      /* After the subsequent fsync() we'll call invalidate_cache()             
         to attempt to clear all data from the page cache.  */                  
    }                                                                           
                                                                                
  while (total_written < size)                                                  Line 1214
    {                                                                           
      ssize_t nwritten = 0;                                                     Line 1216
      process_signals ();                                                       Line 1217
                                                                                
      /* Perform a seek for a NUL block if sparse output is enabled.  */        
      final_op_was_seek = false;                                                Line 1220
      if ((conversions_mask & C_SPARSE) && is_nul (buf, size))                  Line 1221
        {                                                                       
          if (lseek (fd, size, SEEK_CUR) < 0)                                   Line 1223
            {                                                                   
              conversions_mask &= ~C_SPARSE;                                    Line 1225
              /* Don't warn about the advisory sparse request.  */              
            }                                                                   
          else                                                                  Line 1228
            {                                                                   
              final_op_was_seek = true;                                         Line 1230
              nwritten = size;                                                  Line 1231
            }                                                                   
        }                                                                       
                                                                                
      if (!nwritten)                                                            Line 1235
        nwritten = write (fd, buf + total_written, size - total_written);       Line 1236...!syscalls auto-comment...
                                                                                
      if (nwritten < 0)                                                         Line 1238
        {                                                                       
          if (errno != EINTR)                                                   Line 1240
            break;                                                              Line 1241
        }                                                                       
      else if (nwritten == 0)                                                   Line 1243
        {                                                                       
          /* Some buggy drivers return 0 when one tries to write beyond         
             a device's end.  (Example: Linux kernel 1.2.13 on /dev/fd0.)       
             Set errno to ENOSPC so they get a sensible diagnostic.  */         
          errno = ENOSPC;                                                       Line 1248
          break;                                                                Line 1249
        }                                                                       
      else                                                                      Line 1251
        total_written += nwritten;                                              Line 1252
    }                                                                           
                                                                                
  if (o_nocache && total_written)                                               Line 1255
    invalidate_cache (fd, total_written);                                       Line 1256
                                                                                
  return total_written;                                                         Line 1258
}                                                                               Block 35
                                                                                
/* Write, then empty, the output buffer 'obuf'. */                              
                                                                                
static void                                                                     Line 1263
write_output (void)                                                             Line 1264
{                                                                               
  size_t nwritten = iwrite (STDOUT_FILENO, obuf, output_blocksize);             Line 1266...!syscalls auto-comment...
  w_bytes += nwritten;                                                          Line 1267
  if (nwritten != output_blocksize)                                             Line 1268
    {                                                                           
      error (0, errno, _("writing to %s"), quoteaf (output_file));              Line 1270
      if (nwritten != 0)                                                        Line 1271
        w_partial++;                                                            Line 1272
      quit (EXIT_FAILURE);                                                      Line 1273
    }                                                                           
  else                                                                          Line 1275
    w_full++;                                                                   Line 1276
  oc = 0;                                                                       Line 1277
}                                                                               Block 36
                                                                                
/* Restart on EINTR from fd_reopen().  */                                       
                                                                                
static int                                                                      Line 1282
ifd_reopen (int desired_fd, char const *file, int flag, mode_t mode)            Line 1283...!syscalls auto-comment...
{                                                                               
  int ret;                                                                      Line 1285
                                                                                
  do                                                                            
    {                                                                           
      process_signals ();                                                       Line 1289
      ret = fd_reopen (desired_fd, file, flag, mode);                           Line 1290...!syscalls auto-comment...
    }                                                                           
  while (ret < 0 && errno == EINTR);                                            Line 1292
                                                                                
  return ret;                                                                   Line 1294
}                                                                               Block 37
                                                                                
/* Restart on EINTR from ftruncate().  */                                       
                                                                                
static int                                                                      Line 1299
iftruncate (int fd, off_t length)                                               Line 1300...!syscalls auto-comment...
{                                                                               
  int ret;                                                                      Line 1302
                                                                                
  do                                                                            
    {                                                                           
      process_signals ();                                                       Line 1306
      ret = ftruncate (fd, length);                                             Line 1307...!syscalls auto-comment...
    }                                                                           
  while (ret < 0 && errno == EINTR);                                            Line 1309
                                                                                
  return ret;                                                                   Line 1311
}                                                                               Block 38
                                                                                
/* Return true if STR is of the form "PATTERN" or "PATTERNDELIM...".  */        
                                                                                
static bool _GL_ATTRIBUTE_PURE                                                  Line 1316
operand_matches (char const *str, char const *pattern, char delim)              Line 1317
{                                                                               
  while (*pattern)                                                              Line 1319
    if (*str++ != *pattern++)                                                   Line 1320
      return false;                                                             Line 1321
  return !*str || *str == delim;                                                Line 1322
}                                                                               Block 39
                                                                                
/* Interpret one "conv=..." or similar operand STR according to the             
   symbols in TABLE, returning the flags specified.  If the operand             
   cannot be parsed, use ERROR_MSGID to generate a diagnostic.  */              
                                                                                
static int                                                                      Line 1329
parse_symbols (char const *str, struct symbol_value const *table,               Line 1330
               bool exclusive, char const *error_msgid)                         Line 1331
{                                                                               
  int value = 0;                                                                Line 1333
                                                                                
  while (true)                                                                  Line 1335
    {                                                                           
      char const *strcomma = strchr (str, ',');                                 Line 1337
      struct symbol_value const *entry;                                         Line 1338
                                                                                
      for (entry = table;                                                       Line 1340
           ! (operand_matches (str, entry->symbol, ',') && entry->value);       Line 1341
           entry++)                                                             Line 1342
        {                                                                       
          if (! entry->symbol[0])                                               Line 1344
            {                                                                   
              size_t slen = strcomma ? strcomma - str : strlen (str);           Line 1346
              error (0, 0, "%s: %s", _(error_msgid),                            Line 1347
                     quotearg_n_style_mem (0, locale_quoting_style, str, slen));Line 1348
              usage (EXIT_FAILURE);                                             Line 1349
            }                                                                   
        }                                                                       
                                                                                
      if (exclusive)                                                            Line 1353
        value = entry->value;                                                   Line 1354
      else                                                                      Line 1355
        value |= entry->value;                                                  Line 1356
      if (!strcomma)                                                            Line 1357
        break;                                                                  Line 1358
      str = strcomma + 1;                                                       Line 1359
    }                                                                           
                                                                                
  return value;                                                                 Line 1362
}                                                                               Block 40
                                                                                
/* Return the value of STR, interpreted as a non-negative decimal integer,      
   optionally multiplied by various values.                                     
   Set *INVALID to a nonzero error value if STR does not represent a            
   number in this format.  */                                                   
                                                                                
static uintmax_t                                                                Line 1370
parse_integer (const char *str, strtol_error *invalid)                          Line 1371
{                                                                               
  uintmax_t n;                                                                  Line 1373
  char *suffix;                                                                 Line 1374
  strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");          Line 1375
                                                                                
  if (e == LONGINT_INVALID_SUFFIX_CHAR && *suffix == 'x')                       Line 1377
    {                                                                           
      uintmax_t multiplier = parse_integer (suffix + 1, invalid);               Line 1379
                                                                                
      if (multiplier != 0 && n * multiplier / multiplier != n)                  Line 1381
        {                                                                       
          *invalid = LONGINT_OVERFLOW;                                          Line 1383
          return 0;                                                             Line 1384
        }                                                                       
                                                                                
      if (n == 0 && STRPREFIX (str, "0x"))                                      Line 1387
        error (0, 0,                                                            Line 1388
               _("warning: %s is a zero multiplier; "                           Line 1389
                 "use %s if that is intended"),                                 Line 1390
               quote_n (0, "0x"), quote_n (1, "00x"));                          Line 1391
                                                                                
      n *= multiplier;                                                          Line 1393
    }                                                                           
  else if (e != LONGINT_OK)                                                     Line 1395
    {                                                                           
      *invalid = e;                                                             Line 1397
      return 0;                                                                 Line 1398
    }                                                                           
                                                                                
  return n;                                                                     Line 1401
}                                                                               Block 41
                                                                                
/* OPERAND is of the form "X=...".  Return true if X is NAME.  */               
                                                                                
static bool _GL_ATTRIBUTE_PURE                                                  Line 1406
operand_is (char const *operand, char const *name)                              Line 1407
{                                                                               
  return operand_matches (operand, name, '=');                                  Line 1409
}                                                                               Block 42
                                                                                
static void                                                                     Line 1412
scanargs (int argc, char *const *argv)                                          Line 1413
{                                                                               
  size_t blocksize = 0;                                                         Line 1415
  uintmax_t count = (uintmax_t) -1;                                             Line 1416
  uintmax_t skip = 0;                                                           Line 1417
  uintmax_t seek = 0;                                                           Line 1418
                                                                                
  for (int i = optind; i < argc; i++)                                           Line 1420
    {                                                                           
      char const *name = argv[i];                                               Line 1422
      char const *val = strchr (name, '=');                                     Line 1423
                                                                                
      if (val == NULL)                                                          Line 1425
        {                                                                       
          error (0, 0, _("unrecognized operand %s"),                            Line 1427
                 quote (name));                                                 Line 1428
          usage (EXIT_FAILURE);                                                 Line 1429
        }                                                                       
      val++;                                                                    Line 1431
                                                                                
      if (operand_is (name, "if"))                                              Line 1433
        input_file = val;                                                       Line 1434
      else if (operand_is (name, "of"))                                         Line 1435
        output_file = val;                                                      Line 1436
      else if (operand_is (name, "conv"))                                       Line 1437
        conversions_mask |= parse_symbols (val, conversions, false,             Line 1438
                                           N_("invalid conversion"));           Line 1439
      else if (operand_is (name, "iflag"))                                      Line 1440
        input_flags |= parse_symbols (val, flags, false,                        Line 1441
                                      N_("invalid input flag"));                Line 1442
      else if (operand_is (name, "oflag"))                                      Line 1443
        output_flags |= parse_symbols (val, flags, false,                       Line 1444
                                       N_("invalid output flag"));              Line 1445
      else if (operand_is (name, "status"))                                     Line 1446
        status_level = parse_symbols (val, statuses, true,                      Line 1447
                                      N_("invalid status level"));              Line 1448
      else                                                                      Line 1449
        {                                                                       
          strtol_error invalid = LONGINT_OK;                                    Line 1451
          uintmax_t n = parse_integer (val, &invalid);                          Line 1452
          uintmax_t n_min = 0;                                                  Line 1453
          uintmax_t n_max = UINTMAX_MAX;                                        Line 1454
                                                                                
          if (operand_is (name, "ibs"))                                         Line 1456
            {                                                                   
              n_min = 1;                                                        Line 1458
              n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);                         Line 1459
              input_blocksize = n;                                              Line 1460
            }                                                                   
          else if (operand_is (name, "obs"))                                    Line 1462
            {                                                                   
              n_min = 1;                                                        Line 1464
              n_max = MAX_BLOCKSIZE (OUTPUT_BLOCK_SLOP);                        Line 1465
              output_blocksize = n;                                             Line 1466
            }                                                                   
          else if (operand_is (name, "bs"))                                     Line 1468
            {                                                                   
              n_min = 1;                                                        Line 1470
              n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);                         Line 1471
              blocksize = n;                                                    Line 1472
            }                                                                   
          else if (operand_is (name, "cbs"))                                    Line 1474
            {                                                                   
              n_min = 1;                                                        Line 1476
              n_max = SIZE_MAX;                                                 Line 1477
              conversion_blocksize = n;                                         Line 1478
            }                                                                   
          else if (operand_is (name, "skip"))                                   Line 1480
            skip = n;                                                           Line 1481
          else if (operand_is (name, "seek"))                                   Line 1482
            seek = n;                                                           Line 1483
          else if (operand_is (name, "count"))                                  Line 1484
            count = n;                                                          Line 1485
          else                                                                  Line 1486
            {                                                                   
              error (0, 0, _("unrecognized operand %s"),                        Line 1488
                     quote (name));                                             Line 1489
              usage (EXIT_FAILURE);                                             Line 1490
            }                                                                   
                                                                                
          if (n < n_min)                                                        Line 1493
            invalid = LONGINT_INVALID;                                          Line 1494
          else if (n_max < n)                                                   Line 1495
            invalid = LONGINT_OVERFLOW;                                         Line 1496
                                                                                
          if (invalid != LONGINT_OK)                                            Line 1498
            die (EXIT_FAILURE, invalid == LONGINT_OVERFLOW ? EOVERFLOW : 0,     Line 1499
                 "%s: %s", _("invalid number"), quote (val));                   Line 1500
        }                                                                       
    }                                                                           
                                                                                
  if (blocksize)                                                                Line 1504
    input_blocksize = output_blocksize = blocksize;                             Line 1505
  else                                                                          Line 1506
    {                                                                           
      /* POSIX says dd aggregates partial reads into                            
         output_blocksize if bs= is not specified.  */                          
      conversions_mask |= C_TWOBUFS;                                            Line 1510
    }                                                                           
                                                                                
  if (input_blocksize == 0)                                                     Line 1513
    input_blocksize = DEFAULT_BLOCKSIZE;                                        Line 1514
  if (output_blocksize == 0)                                                    Line 1515
    output_blocksize = DEFAULT_BLOCKSIZE;                                       Line 1516
  if (conversion_blocksize == 0)                                                Line 1517
    conversions_mask &= ~(C_BLOCK | C_UNBLOCK);                                 Line 1518
                                                                                
  if (input_flags & (O_DSYNC | O_SYNC))                                         Line 1520
    input_flags |= O_RSYNC;                                                     Line 1521
                                                                                
  if (output_flags & O_FULLBLOCK)                                               Line 1523
    {                                                                           
      error (0, 0, "%s: %s", _("invalid output flag"), quote ("fullblock"));    Line 1525
      usage (EXIT_FAILURE);                                                     Line 1526
    }                                                                           
                                                                                
  if (input_flags & O_SEEK_BYTES)                                               Line 1529
    {                                                                           
      error (0, 0, "%s: %s", _("invalid input flag"), quote ("seek_bytes"));    Line 1531
      usage (EXIT_FAILURE);                                                     Line 1532
    }                                                                           
                                                                                
  if (output_flags & (O_COUNT_BYTES | O_SKIP_BYTES))                            Line 1535
    {                                                                           
      error (0, 0, "%s: %s", _("invalid output flag"),                          Line 1537
             quote (output_flags & O_COUNT_BYTES                                Line 1538
                    ? "count_bytes" : "skip_bytes"));                           Line 1539
      usage (EXIT_FAILURE);                                                     Line 1540
    }                                                                           
                                                                                
  if (input_flags & O_SKIP_BYTES && skip != 0)                                  Line 1543
    {                                                                           
      skip_records = skip / input_blocksize;                                    Line 1545
      skip_bytes = skip % input_blocksize;                                      Line 1546
    }                                                                           
  else if (skip != 0)                                                           Line 1548
    skip_records = skip;                                                        Line 1549
                                                                                
  if (input_flags & O_COUNT_BYTES && count != (uintmax_t) -1)                   Line 1551
    {                                                                           
      max_records = count / input_blocksize;                                    Line 1553
      max_bytes = count % input_blocksize;                                      Line 1554
    }                                                                           
  else if (count != (uintmax_t) -1)                                             Line 1556
    max_records = count;                                                        Line 1557
                                                                                
  if (output_flags & O_SEEK_BYTES && seek != 0)                                 Line 1559
    {                                                                           
      seek_records = seek / output_blocksize;                                   Line 1561
      seek_bytes = seek % output_blocksize;                                     Line 1562
    }                                                                           
  else if (seek != 0)                                                           Line 1564
    seek_records = seek;                                                        Line 1565
                                                                                
  /* Warn about partial reads if bs=SIZE is given and iflag=fullblock           
     is not, and if counting or skipping bytes or using direct I/O.             
     This helps to avoid confusion with miscounts, and to avoid issues          
     with direct I/O on GNU/Linux.  */                                          
  warn_partial_read =                                                           Line 1571
    (! (conversions_mask & C_TWOBUFS) && ! (input_flags & O_FULLBLOCK)          Line 1572
     && (skip_records                                                           Line 1573
         || (0 < max_records && max_records < (uintmax_t) -1)                   Line 1574
         || (input_flags | output_flags) & O_DIRECT));                          Line 1575
                                                                                
  iread_fnc = ((input_flags & O_FULLBLOCK)                                      Line 1577
               ? iread_fullblock                                                Line 1578
               : iread);                                                        Line 1579
  input_flags &= ~O_FULLBLOCK;                                                  Line 1580
                                                                                
  if (multiple_bits_set (conversions_mask & (C_ASCII | C_EBCDIC | C_IBM)))      Line 1582
    die (EXIT_FAILURE, 0, _("cannot combine any two of {ascii,ebcdic,ibm}"));   Line 1583
  if (multiple_bits_set (conversions_mask & (C_BLOCK | C_UNBLOCK)))             Line 1584
    die (EXIT_FAILURE, 0, _("cannot combine block and unblock"));               Line 1585
  if (multiple_bits_set (conversions_mask & (C_LCASE | C_UCASE)))               Line 1586
    die (EXIT_FAILURE, 0, _("cannot combine lcase and ucase"));                 Line 1587
  if (multiple_bits_set (conversions_mask & (C_EXCL | C_NOCREAT)))              Line 1588
    die (EXIT_FAILURE, 0, _("cannot combine excl and nocreat"));                Line 1589
  if (multiple_bits_set (input_flags & (O_DIRECT | O_NOCACHE))                  Line 1590
      || multiple_bits_set (output_flags & (O_DIRECT | O_NOCACHE)))             Line 1591
    die (EXIT_FAILURE, 0, _("cannot combine direct and nocache"));              Line 1592
                                                                                
  if (input_flags & O_NOCACHE)                                                  Line 1594
    {                                                                           
      i_nocache = true;                                                         Line 1596
      i_nocache_eof = (max_records == 0 && max_bytes == 0);                     Line 1597
      input_flags &= ~O_NOCACHE;                                                Line 1598
    }                                                                           
  if (output_flags & O_NOCACHE)                                                 Line 1600
    {                                                                           
      o_nocache = true;                                                         Line 1602
      o_nocache_eof = (max_records == 0 && max_bytes == 0);                     Line 1603
      output_flags &= ~O_NOCACHE;                                               Line 1604
    }                                                                           
}                                                                               Block 43
                                                                                
/* Fix up translation table. */                                                 
                                                                                
static void                                                                     Line 1610
apply_translations (void)                                                       Line 1611
{                                                                               
  int i;                                                                        Line 1613
                                                                                
  if (conversions_mask & C_ASCII)                                               Line 1615
    translate_charset (ebcdic_to_ascii);                                        Line 1616
                                                                                
  if (conversions_mask & C_UCASE)                                               Line 1618
    {                                                                           
      for (i = 0; i < 256; i++)                                                 Line 1620
        trans_table[i] = toupper (trans_table[i]);                              Line 1621
      translation_needed = true;                                                Line 1622
    }                                                                           
  else if (conversions_mask & C_LCASE)                                          Line 1624
    {                                                                           
      for (i = 0; i < 256; i++)                                                 Line 1626
        trans_table[i] = tolower (trans_table[i]);                              Line 1627
      translation_needed = true;                                                Line 1628
    }                                                                           
                                                                                
  if (conversions_mask & C_EBCDIC)                                              Line 1631
    {                                                                           
      translate_charset (ascii_to_ebcdic);                                      Line 1633
      newline_character = ascii_to_ebcdic['\n'];                                Line 1634
      space_character = ascii_to_ebcdic[' '];                                   Line 1635
    }                                                                           
  else if (conversions_mask & C_IBM)                                            Line 1637
    {                                                                           
      translate_charset (ascii_to_ibm);                                         Line 1639
      newline_character = ascii_to_ibm['\n'];                                   Line 1640
      space_character = ascii_to_ibm[' '];                                      Line 1641
    }                                                                           
}                                                                               Block 44
                                                                                
/* Apply the character-set translations specified by the user                   
   to the NREAD bytes in BUF.  */                                               
                                                                                
static void                                                                     Line 1648
translate_buffer (char *buf, size_t nread)                                      Line 1649
{                                                                               
  size_t i;                                                                     Line 1651
  char *cp;                                                                     Line 1652
  for (i = nread, cp = buf; i; i--, cp++)                                       Line 1653
    *cp = trans_table[to_uchar (*cp)];                                          Line 1654
}                                                                               Block 45
                                                                                
/* If true, the last char from the previous call to 'swab_buffer'               
   is saved in 'saved_char'.  */                                                
static bool char_is_saved = false;                                              Line 1659
                                                                                
/* Odd char from previous call.  */                                             
static char saved_char;                                                         Line 1662
                                                                                
/* Swap NREAD bytes in BUF, plus possibly an initial char from the              
   previous call.  If NREAD is odd, save the last char for the                  
   next call.   Return the new start of the BUF buffer.  */                     
                                                                                
static char *                                                                   Line 1668
swab_buffer (char *buf, size_t *nread)                                          Line 1669
{                                                                               
  char *bufstart = buf;                                                         Line 1671
                                                                                
  /* Is a char left from last time?  */                                         
  if (char_is_saved)                                                            Line 1674
    {                                                                           
      *--bufstart = saved_char;                                                 Line 1676
      (*nread)++;                                                               Line 1677
      char_is_saved = false;                                                    Line 1678
    }                                                                           
                                                                                
  if (*nread & 1)                                                               Line 1681
    {                                                                           
      /* An odd number of chars are in the buffer.  */                          
      saved_char = bufstart[--*nread];                                          Line 1684
      char_is_saved = true;                                                     Line 1685
    }                                                                           
                                                                                
  /* Do the byte-swapping by moving every second character two                  
     positions toward the end, working from the end of the buffer               
     toward the beginning.  This way we only move half of the data.  */         
                                                                                
  char *cp = bufstart + *nread; /* Start one char past the last.  */            Line 1692
  for (size_t i = *nread / 2; i; i--, cp -= 2)                                  Line 1693
    *cp = *(cp - 2);                                                            Line 1694
                                                                                
  return ++bufstart;                                                            Line 1696
}                                                                               Block 46
                                                                                
/* Add OFFSET to the input offset, setting the overflow flag if                 
   necessary.  */                                                               
                                                                                
static void                                                                     Line 1702
advance_input_offset (uintmax_t offset)                                         Line 1703
{                                                                               
  input_offset += offset;                                                       Line 1705
  if (input_offset < offset)                                                    Line 1706
    input_offset_overflow = true;                                               Line 1707
}                                                                               Block 47
                                                                                
/* This is a wrapper for lseek.  It detects and warns about a kernel            
   bug that makes lseek a no-op for tape devices, even though the kernel        
   lseek return value suggests that the function succeeded.                     
                                                                                
   The parameters are the same as those of the lseek function, but              
   with the addition of FILENAME, the name of the file associated with          
   descriptor FDESC.  The file name is used solely in the warning that's        
   printed when the bug is detected.  Return the same value that lseek          
   would have returned, but when the lseek bug is detected, return -1           
   to indicate that lseek failed.                                               
                                                                                
   The offending behavior has been confirmed with an Exabyte SCSI tape          
   drive accessed via /dev/nst0 on both Linux 2.2.17 and 2.4.16 kernels.  */    
                                                                                
#if defined __linux__ && HAVE_SYS_MTIO_H                                        Line 1724
                                                                                
# include <sys/mtio.h>                                                          Line 1726
                                                                                
# define MT_SAME_POSITION(P, Q) \                                               Line 1728
   ((P).mt_resid == (Q).mt_resid \                                              Line 1729
    && (P).mt_fileno == (Q).mt_fileno \                                         Line 1730
    && (P).mt_blkno == (Q).mt_blkno)                                            Line 1731
                                                                                
static off_t                                                                    Line 1733
skip_via_lseek (char const *filename, int fdesc, off_t offset, int whence)      Line 1734
{                                                                               
  struct mtget s1;                                                              Line 1736
  struct mtget s2;                                                              Line 1737
  bool got_original_tape_position = (ioctl (fdesc, MTIOCGET, &s1) == 0);        Line 1738...!syscalls auto-comment...
  /* known bad device type */                                                   
  /* && s.mt_type == MT_ISSCSI2 */                                              
                                                                                
  off_t new_position = lseek (fdesc, offset, whence);                           Line 1742
  if (0 <= new_position                                                         Line 1743
      && got_original_tape_position                                             Line 1744
      && ioctl (fdesc, MTIOCGET, &s2) == 0                                      Line 1745...!syscalls auto-comment...
      && MT_SAME_POSITION (s1, s2))                                             Line 1746
    {                                                                           
      if (status_level != STATUS_NONE)                                          Line 1748
        error (0, 0, _("warning: working around lseek kernel bug for file "     Line 1749
                       "(%s)\n  of mt_type=0x%0lx -- "                          Line 1750
                       "see <sys/mtio.h> for the list of types"),               Line 1751
               filename, s2.mt_type + 0Lu);                                     Line 1752
      errno = 0;                                                                Line 1753
      new_position = -1;                                                        Line 1754
    }                                                                           
                                                                                
  return new_position;                                                          Line 1757
}                                                                               Block 48
#else                                                                           Line 1759
# define skip_via_lseek(Filename, Fd, Offset, Whence) lseek (Fd, Offset, Whence)Line 1760
#endif                                                                          Line 1761
                                                                                
/* Throw away RECORDS blocks of BLOCKSIZE bytes plus BYTES bytes on             
   file descriptor FDESC, which is open with read permission for FILE.          
   Store up to BLOCKSIZE bytes of the data at a time in IBUF or OBUF, if        
   necessary. RECORDS or BYTES must be nonzero. If FDESC is                     
   STDIN_FILENO, advance the input offset. Return the number of                 
   records remaining, i.e., that were not skipped because EOF was               
   reached.  If FDESC is STDOUT_FILENO, on return, BYTES is the                 
   remaining bytes in addition to the remaining records.  */                    
                                                                                
static uintmax_t                                                                Line 1772
skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,         Line 1773
      size_t *bytes)                                                            Line 1774
{                                                                               
  uintmax_t offset = records * blocksize + *bytes;                              Line 1776
                                                                                
  /* Try lseek and if an error indicates it was an inappropriate operation --   
     or if the file offset is not representable as an off_t --                  
     fall back on using read.  */                                               
                                                                                
  errno = 0;                                                                    Line 1782
  if (records <= OFF_T_MAX / blocksize                                          Line 1783
      && 0 <= skip_via_lseek (file, fdesc, offset, SEEK_CUR))                   Line 1784
    {                                                                           
      if (fdesc == STDIN_FILENO)                                                Line 1786
        {                                                                       
           struct stat st;                                                      Line 1788
           if (fstat (STDIN_FILENO, &st) != 0)                                  Line 1789...!syscalls auto-comment......!syscalls auto-comment...
             die (EXIT_FAILURE, errno, _("cannot fstat %s"), quoteaf (file));   Line 1790
           if (usable_st_size (&st) && st.st_size < input_offset + offset)      Line 1791
             {                                                                  
               /* When skipping past EOF, return the number of _full_ blocks    
                * that are not skipped, and set offset to EOF, so the caller    
                * can determine the requested skip was not satisfied.  */       
               records = ( offset - st.st_size ) / blocksize;                   Line 1796
               offset = st.st_size - input_offset;                              Line 1797
             }                                                                  
           else                                                                 Line 1799
             records = 0;                                                       Line 1800
           advance_input_offset (offset);                                       Line 1801
        }                                                                       
      else                                                                      Line 1803
        {                                                                       
          records = 0;                                                          Line 1805
          *bytes = 0;                                                           Line 1806
        }                                                                       
      return records;                                                           Line 1808
    }                                                                           
  else                                                                          Line 1810
    {                                                                           
      int lseek_errno = errno;                                                  Line 1812
                                                                                
      /* The seek request may have failed above if it was too big               
         (> device size, > max file size, etc.)                                 
         Or it may not have been done at all (> OFF_T_MAX).                     
         Therefore try to seek to the end of the file,                          
         to avoid redundant reading.  */                                        
      if ((skip_via_lseek (file, fdesc, 0, SEEK_END)) >= 0)                     Line 1819
        {                                                                       
          /* File is seekable, and we're at the end of it, and                  
             size <= OFF_T_MAX. So there's no point using read to advance.  */  
                                                                                
          if (!lseek_errno)                                                     Line 1824
            {                                                                   
              /* The original seek was not attempted as offset > OFF_T_MAX.     
                 We should error for write as can't get to the desired          
                 location, even if OFF_T_MAX < max file size.                   
                 For read we're not going to read any data anyway,              
                 so we should error for consistency.                            
                 It would be nice to not error for /dev/{zero,null}             
                 for any offset, but that's not a significant issue.  */        
              lseek_errno = EOVERFLOW;                                          Line 1833
            }                                                                   
                                                                                
          if (fdesc == STDIN_FILENO)                                            Line 1836
            error (0, lseek_errno, _("%s: cannot skip"), quotef (file));        Line 1837
          else                                                                  Line 1838
            error (0, lseek_errno, _("%s: cannot seek"), quotef (file));        Line 1839
          /* If the file has a specific size and we've asked                    
             to skip/seek beyond the max allowable, then quit.  */              
          quit (EXIT_FAILURE);                                                  Line 1842
        }                                                                       
      /* else file_size && offset > OFF_T_MAX or file ! seekable */             
                                                                                
      char *buf;                                                                Line 1846
      if (fdesc == STDIN_FILENO)                                                Line 1847
        {                                                                       
          alloc_ibuf ();                                                        Line 1849
          buf = ibuf;                                                           Line 1850
        }                                                                       
      else                                                                      Line 1852
        {                                                                       
          alloc_obuf ();                                                        Line 1854
          buf = obuf;                                                           Line 1855
        }                                                                       
                                                                                
      do                                                                        
        {                                                                       
          ssize_t nread = iread_fnc (fdesc, buf, records ? blocksize : *bytes); Line 1860
          if (nread < 0)                                                        Line 1861
            {                                                                   
              if (fdesc == STDIN_FILENO)                                        Line 1863
                {                                                               
                  error (0, errno, _("error reading %s"), quoteaf (file));      Line 1865
                  if (conversions_mask & C_NOERROR)                             Line 1866
                    print_stats ();                                             Line 1867
                }                                                               
              else                                                              Line 1869
                error (0, lseek_errno, _("%s: cannot seek"), quotef (file));    Line 1870
              quit (EXIT_FAILURE);                                              Line 1871
            }                                                                   
          else if (nread == 0)                                                  Line 1873
            break;                                                              Line 1874
          else if (fdesc == STDIN_FILENO)                                       Line 1875
            advance_input_offset (nread);                                       Line 1876
                                                                                
          if (records != 0)                                                     Line 1878
            records--;                                                          Line 1879
          else                                                                  Line 1880
            *bytes = 0;                                                         Line 1881
        }                                                                       
      while (records || *bytes);                                                Line 1883
                                                                                
      return records;                                                           Line 1885
    }                                                                           
}                                                                               Block 49
                                                                                
/* Advance the input by NBYTES if possible, after a read error.                 
   The input file offset may or may not have advanced after the failed          
   read; adjust it to point just after the bad record regardless.               
   Return true if successful, or if the input is already known to not           
   be seekable.  */                                                             
                                                                                
static bool                                                                     Line 1895
advance_input_after_read_error (size_t nbytes)                                  Line 1896
{                                                                               
  if (! input_seekable)                                                         Line 1898
    {                                                                           
      if (input_seek_errno == ESPIPE)                                           Line 1900
        return true;                                                            Line 1901
      errno = input_seek_errno;                                                 Line 1902
    }                                                                           
  else                                                                          Line 1904
    {                                                                           
      off_t offset;                                                             Line 1906
      advance_input_offset (nbytes);                                            Line 1907
      input_offset_overflow |= (OFF_T_MAX < input_offset);                      Line 1908
      if (input_offset_overflow)                                                Line 1909
        {                                                                       
          error (0, 0, _("offset overflow while reading file %s"),              Line 1911
                 quoteaf (input_file));                                         Line 1912
          return false;                                                         Line 1913
        }                                                                       
      offset = lseek (STDIN_FILENO, 0, SEEK_CUR);                               Line 1915
      if (0 <= offset)                                                          Line 1916
        {                                                                       
          off_t diff;                                                           Line 1918
          if (offset == input_offset)                                           Line 1919
            return true;                                                        Line 1920
          diff = input_offset - offset;                                         Line 1921
          if (! (0 <= diff && diff <= nbytes) && status_level != STATUS_NONE)   Line 1922
            error (0, 0, _("warning: invalid file offset after failed read"));  Line 1923
          if (0 <= skip_via_lseek (input_file, STDIN_FILENO, diff, SEEK_CUR))   Line 1924
            return true;                                                        Line 1925
          if (errno == 0)                                                       Line 1926
            error (0, 0, _("cannot work around kernel bug after all"));         Line 1927
        }                                                                       
    }                                                                           
                                                                                
  error (0, errno, _("%s: cannot seek"), quotef (input_file));                  Line 1931
  return false;                                                                 Line 1932
}                                                                               Block 50
                                                                                
/* Copy NREAD bytes of BUF, with no conversions.  */                            
                                                                                
static void                                                                     Line 1937
copy_simple (char const *buf, size_t nread)                                     Line 1938
{                                                                               
  const char *start = buf; /* First uncopied char in BUF.  */                   Line 1940
                                                                                
  do                                                                            
    {                                                                           
      size_t nfree = MIN (nread, output_blocksize - oc);                        Line 1944
                                                                                
      memcpy (obuf + oc, start, nfree);                                         Line 1946
                                                                                
      nread -= nfree;  /* Update the number of bytes left to copy. */           Line 1948
      start += nfree;                                                           Line 1949
      oc += nfree;                                                              Line 1950
      if (oc >= output_blocksize)                                               Line 1951
        write_output ();                                                        Line 1952
    }                                                                           
  while (nread != 0);                                                           Line 1954
}                                                                               Block 51
                                                                                
/* Copy NREAD bytes of BUF, doing conv=block                                    
   (pad newline-terminated records to 'conversion_blocksize',                   
   replacing the newline with trailing spaces).  */                             
                                                                                
static void                                                                     Line 1961
copy_with_block (char const *buf, size_t nread)                                 Line 1962
{                                                                               
  for (size_t i = nread; i; i--, buf++)                                         Line 1964
    {                                                                           
      if (*buf == newline_character)                                            Line 1966
        {                                                                       
          if (col < conversion_blocksize)                                       Line 1968
            {                                                                   
              size_t j;                                                         Line 1970
              for (j = col; j < conversion_blocksize; j++)                      Line 1971
                output_char (space_character);                                  Line 1972
            }                                                                   
          col = 0;                                                              Line 1974
        }                                                                       
      else                                                                      Line 1976
        {                                                                       
          if (col == conversion_blocksize)                                      Line 1978
            r_truncate++;                                                       Line 1979
          else if (col < conversion_blocksize)                                  Line 1980
            output_char (*buf);                                                 Line 1981
          col++;                                                                Line 1982
        }                                                                       
    }                                                                           
}                                                                               Block 52
                                                                                
/* Copy NREAD bytes of BUF, doing conv=unblock                                  
   (replace trailing spaces in 'conversion_blocksize'-sized records             
   with a newline).  */                                                         
                                                                                
static void                                                                     Line 1991
copy_with_unblock (char const *buf, size_t nread)                               Line 1992
{                                                                               
  static size_t pending_spaces = 0;                                             Line 1994
                                                                                
  for (size_t i = 0; i < nread; i++)                                            Line 1996
    {                                                                           
      char c = buf[i];                                                          Line 1998
                                                                                
      if (col++ >= conversion_blocksize)                                        Line 2000
        {                                                                       
          col = pending_spaces = 0; /* Wipe out any pending spaces.  */         Line 2002
          i--;   /* Push the char back; get it later. */                        Line 2003
          output_char (newline_character);                                      Line 2004
        }                                                                       
      else if (c == space_character)                                            Line 2006
        pending_spaces++;                                                       Line 2007
      else                                                                      Line 2008
        {                                                                       
          /* 'c' is the character after a run of spaces that were not           
             at the end of the conversion buffer.  Output them.  */             
          while (pending_spaces)                                                Line 2012
            {                                                                   
              output_char (space_character);                                    Line 2014
              --pending_spaces;                                                 Line 2015
            }                                                                   
          output_char (c);                                                      Line 2017
        }                                                                       
    }                                                                           
}                                                                               Block 53
                                                                                
/* Set the file descriptor flags for FD that correspond to the nonzero bits     
   in ADD_FLAGS.  The file's name is NAME.  */                                  
                                                                                
static void                                                                     Line 2025
set_fd_flags (int fd, int add_flags, char const *name)                          Line 2026
{                                                                               
  /* Ignore file creation flags that are no-ops on file descriptors.  */        
  add_flags &= ~ (O_NOCTTY | O_NOFOLLOW);                                       Line 2029
                                                                                
  if (add_flags)                                                                Line 2031
    {                                                                           
      int old_flags = fcntl (fd, F_GETFL);                                      Line 2033...!syscalls auto-comment...
      int new_flags = old_flags | add_flags;                                    Line 2034
      bool ok = true;                                                           Line 2035
      if (old_flags < 0)                                                        Line 2036
        ok = false;                                                             Line 2037
      else if (old_flags != new_flags)                                          Line 2038
        {                                                                       
          if (new_flags & (O_DIRECTORY | O_NOLINKS))                            Line 2040
            {                                                                   
              /* NEW_FLAGS contains at least one file creation flag that        
                 requires some checking of the open file descriptor.  */        
              struct stat st;                                                   Line 2044
              if (fstat (fd, &st) != 0)                                         Line 2045...!syscalls auto-comment......!syscalls auto-comment...
                ok = false;                                                     Line 2046
              else if ((new_flags & O_DIRECTORY) && ! S_ISDIR (st.st_mode))     Line 2047
                {                                                               
                  errno = ENOTDIR;                                              Line 2049
                  ok = false;                                                   Line 2050
                }                                                               
              else if ((new_flags & O_NOLINKS) && 1 < st.st_nlink)              Line 2052
                {                                                               
                  errno = EMLINK;                                               Line 2054
                  ok = false;                                                   Line 2055
                }                                                               
              new_flags &= ~ (O_DIRECTORY | O_NOLINKS);                         Line 2057
            }                                                                   
                                                                                
          if (ok && old_flags != new_flags                                      Line 2060
              && fcntl (fd, F_SETFL, new_flags) == -1)                          Line 2061...!syscalls auto-comment...
            ok = false;                                                         Line 2062
        }                                                                       
                                                                                
      if (!ok)                                                                  Line 2065
        die (EXIT_FAILURE, errno, _("setting flags for %s"), quoteaf (name));   Line 2066
    }                                                                           
}                                                                               
                                                                                
/* The main loop.  */                                                           
                                                                                
static int                                                                      Line 2072
dd_copy (void)                                                                  Line 2073
{                                                                               
  char *bufstart;  /* Input buffer. */                                          Line 2075
  ssize_t nread;  /* Bytes read in the current block.  */                       Line 2076
                                                                                
  /* If nonzero, then the previously read block was partial and                 
     PARTREAD was its size.  */                                                 
  size_t partread = 0;                                                          Line 2080
                                                                                
  int exit_status = EXIT_SUCCESS;                                               Line 2082
  size_t n_bytes_read;                                                          Line 2083
                                                                                
  /* Leave at least one extra byte at the beginning and end of 'ibuf'           
     for conv=swab, but keep the buffer address even.  But some peculiar        
     device drivers work only with word-aligned buffers, so leave an            
     extra two bytes.  */                                                       
                                                                                
  /* Some devices require alignment on a sector or page boundary                
     (e.g. character disk devices).  Align the input buffer to a                
     page boundary to cover all bases.  Note that due to the swab               
     algorithm, we must have at least one byte in the page before               
     the input buffer;  thus we allocate 2 pages of slop in the                 
     real buffer.  8k above the blocksize shouldn't bother anyone.              
                                                                                
     The page alignment is necessary on any Linux kernel that supports          
     either the SGI raw I/O patch or Steven Tweedies raw I/O patch.             
     It is necessary when accessing raw (i.e., character special) disk          
     devices on Unixware or other SVR4-derived system.  */                      
                                                                                
  if (skip_records != 0 || skip_bytes != 0)                                     Line 2102
    {                                                                           
      uintmax_t us_bytes = input_offset + (skip_records * input_blocksize)      Line 2104
                           + skip_bytes;                                        Line 2105
      uintmax_t us_blocks = skip (STDIN_FILENO, input_file,                     Line 2106
                                  skip_records, input_blocksize, &skip_bytes);  Line 2107
      us_bytes -= input_offset;                                                 Line 2108
                                                                                
      /* POSIX doesn't say what to do when dd detects it has been               
         asked to skip past EOF, so I assume it's non-fatal.                    
         There are 3 reasons why there might be unskipped blocks/bytes:         
             1. file is too small                                               
             2. pipe has not enough data                                        
             3. partial reads  */                                               
      if ((us_blocks || (!input_offset_overflow && us_bytes))                   Line 2116
          && status_level != STATUS_NONE)                                       Line 2117
        {                                                                       
          error (0, 0,                                                          Line 2119
                 _("%s: cannot skip to specified offset"), quotef (input_file));Line 2120
        }                                                                       
    }                                                                           
                                                                                
  if (seek_records != 0 || seek_bytes != 0)                                     Line 2124
    {                                                                           
      size_t bytes = seek_bytes;                                                Line 2126
      uintmax_t write_records = skip (STDOUT_FILENO, output_file,               Line 2127
                                      seek_records, output_blocksize, &bytes);  Line 2128
                                                                                
      if (write_records != 0 || bytes != 0)                                     Line 2130
        {                                                                       
          memset (obuf, 0, write_records ? output_blocksize : bytes);           Line 2132
                                                                                
          do                                                                    
            {                                                                   
              size_t size = write_records ? output_blocksize : bytes;           Line 2136
              if (iwrite (STDOUT_FILENO, obuf, size) != size)                   Line 2137...!syscalls auto-comment...
                {                                                               
                  error (0, errno, _("writing to %s"), quoteaf (output_file));  Line 2139
                  quit (EXIT_FAILURE);                                          Line 2140
                }                                                               
                                                                                
              if (write_records != 0)                                           Line 2143
                write_records--;                                                Line 2144
              else                                                              Line 2145
                bytes = 0;                                                      Line 2146
            }                                                                   
          while (write_records || bytes);                                       Line 2148
        }                                                                       
    }                                                                           
                                                                                
  if (max_records == 0 && max_bytes == 0)                                       Line 2152
    return exit_status;                                                         Line 2153
                                                                                
  alloc_ibuf ();                                                                Line 2155
  alloc_obuf ();                                                                Line 2156
                                                                                
  while (1)                                                                     Line 2158
    {                                                                           
      if (status_level == STATUS_PROGRESS)                                      Line 2160
        {                                                                       
          xtime_t progress_time = gethrxtime ();                                Line 2162
          if (next_time <= progress_time)                                       Line 2163
            {                                                                   
              print_xfer_stats (progress_time);                                 Line 2165
              next_time += XTIME_PRECISION;                                     Line 2166
            }                                                                   
        }                                                                       
                                                                                
      if (r_partial + r_full >= max_records + !!max_bytes)                      Line 2170
        break;                                                                  Line 2171
                                                                                
      /* Zero the buffer before reading, so that if we get a read error,        
         whatever data we are able to read is followed by zeros.                
         This minimizes data loss. */                                           
      if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))        Line 2176
        memset (ibuf,                                                           Line 2177
                (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',        Line 2178
                input_blocksize);                                               Line 2179
                                                                                
      if (r_partial + r_full >= max_records)                                    Line 2181
        nread = iread_fnc (STDIN_FILENO, ibuf, max_bytes);                      Line 2182
      else                                                                      Line 2183
        nread = iread_fnc (STDIN_FILENO, ibuf, input_blocksize);                Line 2184
                                                                                
      if (nread > 0)                                                            Line 2186
        {                                                                       
          advance_input_offset (nread);                                         Line 2188
          if (i_nocache)                                                        Line 2189
            invalidate_cache (STDIN_FILENO, nread);                             Line 2190
        }                                                                       
      else if (nread == 0)                                                      Line 2192
        {                                                                       
          i_nocache_eof |= i_nocache;                                           Line 2194
          o_nocache_eof |= o_nocache && ! (conversions_mask & C_NOTRUNC);       Line 2195
          break;   /* EOF.  */                                                  Line 2196
        }                                                                       
      else                                                                      Line 2198
        {                                                                       
          if (!(conversions_mask & C_NOERROR) || status_level != STATUS_NONE)   Line 2200
            error (0, errno, _("error reading %s"), quoteaf (input_file));      Line 2201
                                                                                
          if (conversions_mask & C_NOERROR)                                     Line 2203
            {                                                                   
              print_stats ();                                                   Line 2205
              size_t bad_portion = input_blocksize - partread;                  Line 2206
                                                                                
              /* We already know this data is not cached,                       
                 but call this so that correct offsets are maintained.  */      
              invalidate_cache (STDIN_FILENO, bad_portion);                     Line 2210
                                                                                
              /* Seek past the bad block if possible. */                        
              if (!advance_input_after_read_error (bad_portion))                Line 2213
                {                                                               
                  exit_status = EXIT_FAILURE;                                   Line 2215
                                                                                
                  /* Suppress duplicate diagnostics.  */                        
                  input_seekable = false;                                       Line 2218
                  input_seek_errno = ESPIPE;                                    Line 2219
                }                                                               
              if ((conversions_mask & C_SYNC) && !partread)                     Line 2221
                /* Replace the missing input with null bytes and                
                   proceed normally.  */                                        
                nread = 0;                                                      Line 2224
              else                                                              Line 2225
                continue;                                                       Line 2226
            }                                                                   
          else                                                                  Line 2228
            {                                                                   
              /* Write any partial block. */                                    
              exit_status = EXIT_FAILURE;                                       Line 2231
              break;                                                            Line 2232
            }                                                                   
        }                                                                       
                                                                                
      n_bytes_read = nread;                                                     Line 2236
                                                                                
      if (n_bytes_read < input_blocksize)                                       Line 2238
        {                                                                       
          r_partial++;                                                          Line 2240
          partread = n_bytes_read;                                              Line 2241
          if (conversions_mask & C_SYNC)                                        Line 2242
            {                                                                   
              if (!(conversions_mask & C_NOERROR))                              Line 2244
                /* If C_NOERROR, we zeroed the block before reading. */         
                memset (ibuf + n_bytes_read,                                    Line 2246
                        (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',Line 2247
                        input_blocksize - n_bytes_read);                        Line 2248
              n_bytes_read = input_blocksize;                                   Line 2249
            }                                                                   
        }                                                                       
      else                                                                      Line 2252
        {                                                                       
          r_full++;                                                             Line 2254
          partread = 0;                                                         Line 2255
        }                                                                       
                                                                                
      if (ibuf == obuf)  /* If not C_TWOBUFS. */                                Line 2258
        {                                                                       
          size_t nwritten = iwrite (STDOUT_FILENO, obuf, n_bytes_read);         Line 2260...!syscalls auto-comment...
          w_bytes += nwritten;                                                  Line 2261
          if (nwritten != n_bytes_read)                                         Line 2262
            {                                                                   
              error (0, errno, _("error writing %s"), quoteaf (output_file));   Line 2264
              return EXIT_FAILURE;                                              Line 2265
            }                                                                   
          else if (n_bytes_read == input_blocksize)                             Line 2267
            w_full++;                                                           Line 2268
          else                                                                  Line 2269
            w_partial++;                                                        Line 2270
          continue;                                                             Line 2271
        }                                                                       
                                                                                
      /* Do any translations on the whole buffer at once.  */                   
                                                                                
      if (translation_needed)                                                   Line 2276
        translate_buffer (ibuf, n_bytes_read);                                  Line 2277
                                                                                
      if (conversions_mask & C_SWAB)                                            Line 2279
        bufstart = swab_buffer (ibuf, &n_bytes_read);                           Line 2280
      else                                                                      Line 2281
        bufstart = ibuf;                                                        Line 2282
                                                                                
      if (conversions_mask & C_BLOCK)                                           Line 2284
        copy_with_block (bufstart, n_bytes_read);                               Line 2285
      else if (conversions_mask & C_UNBLOCK)                                    Line 2286
        copy_with_unblock (bufstart, n_bytes_read);                             Line 2287
      else                                                                      Line 2288
        copy_simple (bufstart, n_bytes_read);                                   Line 2289
    }                                                                           
                                                                                
  /* If we have a char left as a result of conv=swab, output it.  */            
  if (char_is_saved)                                                            Line 2293
    {                                                                           
      if (conversions_mask & C_BLOCK)                                           Line 2295
        copy_with_block (&saved_char, 1);                                       Line 2296
      else if (conversions_mask & C_UNBLOCK)                                    Line 2297
        copy_with_unblock (&saved_char, 1);                                     Line 2298
      else                                                                      Line 2299
        output_char (saved_char);                                               Line 2300
    }                                                                           
                                                                                
  if ((conversions_mask & C_BLOCK) && col > 0)                                  Line 2303
    {                                                                           
      /* If the final input line didn't end with a '\n', pad                    
         the output block to 'conversion_blocksize' chars.  */                  
      for (size_t i = col; i < conversion_blocksize; i++)                       Line 2307
        output_char (space_character);                                          Line 2308
    }                                                                           
                                                                                
  if (col && (conversions_mask & C_UNBLOCK))                                    Line 2311
    {                                                                           
      /* If there was any output, add a final '\n'.  */                         
      output_char (newline_character);                                          Line 2314
    }                                                                           
                                                                                
  /* Write out the last block. */                                               
  if (oc != 0)                                                                  Line 2318
    {                                                                           
      size_t nwritten = iwrite (STDOUT_FILENO, obuf, oc);                       Line 2320...!syscalls auto-comment...
      w_bytes += nwritten;                                                      Line 2321
      if (nwritten != 0)                                                        Line 2322
        w_partial++;                                                            Line 2323
      if (nwritten != oc)                                                       Line 2324
        {                                                                       
          error (0, errno, _("error writing %s"), quoteaf (output_file));       Line 2326
          return EXIT_FAILURE;                                                  Line 2327
        }                                                                       
    }                                                                           
                                                                                
  /* If the last write was converted to a seek, then for a regular file         
     or shared memory object, ftruncate to extend the size.  */                 
  if (final_op_was_seek)                                                        Line 2333
    {                                                                           
      struct stat stdout_stat;                                                  Line 2335
      if (fstat (STDOUT_FILENO, &stdout_stat) != 0)                             Line 2336...!syscalls auto-comment......!syscalls auto-comment...
        {                                                                       
          error (0, errno, _("cannot fstat %s"), quoteaf (output_file));        Line 2338
          return EXIT_FAILURE;                                                  Line 2339
        }                                                                       
      if (S_ISREG (stdout_stat.st_mode) || S_TYPEISSHM (&stdout_stat))          Line 2341
        {                                                                       
          off_t output_offset = lseek (STDOUT_FILENO, 0, SEEK_CUR);             Line 2343
          if (0 <= output_offset && stdout_stat.st_size < output_offset)        Line 2344
            {                                                                   
              if (iftruncate (STDOUT_FILENO, output_offset) != 0)               Line 2346...!syscalls auto-comment...
                {                                                               
                  error (0, errno,                                              Line 2348
                         _("failed to truncate to %" PRIdMAX " bytes"           Line 2349
                           " in output file %s"),                               Line 2350
                         (intmax_t) output_offset, quoteaf (output_file));      Line 2351
                  return EXIT_FAILURE;                                          Line 2352
                }                                                               
            }                                                                   
        }                                                                       
    }                                                                           
                                                                                
  if ((conversions_mask & C_FDATASYNC) && fdatasync (STDOUT_FILENO) != 0)       Line 2358...!syscalls auto-comment...
    {                                                                           
      if (errno != ENOSYS && errno != EINVAL)                                   Line 2360
        {                                                                       
          error (0, errno, _("fdatasync failed for %s"), quoteaf (output_file));Line 2362
          exit_status = EXIT_FAILURE;                                           Line 2363
        }                                                                       
      conversions_mask |= C_FSYNC;                                              Line 2365
    }                                                                           
                                                                                
  if (conversions_mask & C_FSYNC)                                               Line 2368
    while (fsync (STDOUT_FILENO) != 0)                                          Line 2369...!syscalls auto-comment...
      if (errno != EINTR)                                                       Line 2370
        {                                                                       
          error (0, errno, _("fsync failed for %s"), quoteaf (output_file));    Line 2372
          return EXIT_FAILURE;                                                  Line 2373
        }                                                                       
                                                                                
  return exit_status;                                                           Line 2376
}                                                                               Block 55
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 2380
{                                                                               
  int i;                                                                        Line 2382
  int exit_status;                                                              Line 2383
  off_t offset;                                                                 Line 2384
                                                                                
  install_signal_handlers ();                                                   Line 2386
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  /* Arrange to close stdout if parse_long_options exits.  */                   
  atexit (maybe_close_stdout);                                                  Close stdout on exit (see gnulib)
                                                                                
  page_size = getpagesize ();                                                   Line 2397
                                                                                
  parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version,               ...!common auto-comment...
                      usage, AUTHORS, (char const *) NULL);                     Line 2400
  close_stdout_required = false;                                                Line 2401
                                                                                
  if (getopt_long (argc, argv, "", long_options, NULL) != -1)                   Line 2403
    usage (EXIT_FAILURE);                                                       Line 2404
                                                                                
  /* Initialize translation table to identity translation. */                   
  for (i = 0; i < 256; i++)                                                     Line 2407
    trans_table[i] = i;                                                         Line 2408
                                                                                
  /* Decode arguments. */                                                       
  scanargs (argc, argv);                                                        Line 2411
                                                                                
  apply_translations ();                                                        Line 2413
                                                                                
  if (input_file == NULL)                                                       Line 2415
    {                                                                           
      input_file = _("standard input");                                         Line 2417
      set_fd_flags (STDIN_FILENO, input_flags, input_file);                     Line 2418
    }                                                                           
  else                                                                          Line 2420
    {                                                                           
      if (ifd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0) Line 2422...!syscalls auto-comment...
        die (EXIT_FAILURE, errno, _("failed to open %s"),                       Line 2423
             quoteaf (input_file));                                             Line 2424
    }                                                                           
                                                                                
  offset = lseek (STDIN_FILENO, 0, SEEK_CUR);                                   Line 2427
  input_seekable = (0 <= offset);                                               Line 2428
  input_offset = MAX (0, offset);                                               Line 2429
  input_seek_errno = errno;                                                     Line 2430
                                                                                
  if (output_file == NULL)                                                      Line 2432
    {                                                                           
      output_file = _("standard output");                                       Line 2434
      set_fd_flags (STDOUT_FILENO, output_flags, output_file);                  Line 2435
    }                                                                           
  else                                                                          Line 2437
    {                                                                           
      mode_t perms = MODE_RW_UGO;                                               Line 2439
      int opts                                                                  Line 2440
        = (output_flags                                                         Line 2441
           | (conversions_mask & C_NOCREAT ? 0 : O_CREAT)                       Line 2442
           | (conversions_mask & C_EXCL ? O_EXCL : 0)                           Line 2443
           | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));   Line 2444
                                                                                
      /* Open the output file with *read* access only if we might               
         need to read to satisfy a 'seek=' request.  If we can't read           
         the file, go ahead with write-only access; it might work.  */          
      if ((! seek_records                                                       Line 2449
           || ifd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)Line 2450...!syscalls auto-comment...
          && (ifd_reopen (STDOUT_FILENO, output_file, O_WRONLY | opts, perms)   Line 2451...!syscalls auto-comment...
              < 0))                                                             Line 2452
        die (EXIT_FAILURE, errno, _("failed to open %s"),                       Line 2453
             quoteaf (output_file));                                            Line 2454
                                                                                
      if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))                 Line 2456
        {                                                                       
          uintmax_t size = seek_records * output_blocksize + seek_bytes;        Line 2458
          unsigned long int obs = output_blocksize;                             Line 2459
                                                                                
          if (OFF_T_MAX / output_blocksize < seek_records)                      Line 2461
            die (EXIT_FAILURE, 0,                                               Line 2462
                 _("offset too large: "                                         Line 2463
                   "cannot truncate to a length of seek=%"PRIuMAX""             Line 2464
                   " (%lu-byte) blocks"),                                       Line 2465
                 seek_records, obs);                                            Line 2466
                                                                                
          if (iftruncate (STDOUT_FILENO, size) != 0)                            Line 2468...!syscalls auto-comment...
            {                                                                   
              /* Complain only when ftruncate fails on a regular file, a        
                 directory, or a shared memory object, as POSIX 1003.1-2004     
                 specifies ftruncate's behavior only for these file types.      
                 For example, do not complain when Linux kernel 2.4 ftruncate   
                 fails on /dev/fd0.  */                                         
              int ftruncate_errno = errno;                                      Line 2475
              struct stat stdout_stat;                                          Line 2476
              if (fstat (STDOUT_FILENO, &stdout_stat) != 0)                     Line 2477...!syscalls auto-comment......!syscalls auto-comment...
                die (EXIT_FAILURE, errno, _("cannot fstat %s"),                 Line 2478
                     quoteaf (output_file));                                    Line 2479
              if (S_ISREG (stdout_stat.st_mode)                                 Line 2480
                  || S_ISDIR (stdout_stat.st_mode)                              Line 2481
                  || S_TYPEISSHM (&stdout_stat))                                Line 2482
                die (EXIT_FAILURE, ftruncate_errno,                             Line 2483
                     _("failed to truncate to %"PRIuMAX" bytes"                 Line 2484
                       " in output file %s"),                                   Line 2485
                     size, quoteaf (output_file));                              Line 2486
            }                                                                   
        }                                                                       
    }                                                                           
                                                                                
  start_time = gethrxtime ();                                                   Line 2491
  next_time = start_time + XTIME_PRECISION;                                     Line 2492
                                                                                
  exit_status = dd_copy ();                                                     Line 2494
                                                                                
  if (max_records == 0 && max_bytes == 0)                                       Line 2496
    {                                                                           
      /* Special case to invalidate cache to end of file.  */                   
      if (i_nocache && !invalidate_cache (STDIN_FILENO, 0))                     Line 2499
        {                                                                       
          error (0, errno, _("failed to discard cache for: %s"),                Line 2501
                 quotef (input_file));                                          Line 2502
          exit_status = EXIT_FAILURE;                                           Line 2503
        }                                                                       
      if (o_nocache && !invalidate_cache (STDOUT_FILENO, 0))                    Line 2505
        {                                                                       
          error (0, errno, _("failed to discard cache for: %s"),                Line 2507
                 quotef (output_file));                                         Line 2508
          exit_status = EXIT_FAILURE;                                           Line 2509
        }                                                                       
    }                                                                           
  else                                                                          Line 2512
    {                                                                           
      /* Invalidate any pending region or to EOF if appropriate.  */            
      if (i_nocache || i_nocache_eof)                                           Line 2515
        invalidate_cache (STDIN_FILENO, 0);                                     Line 2516
      if (o_nocache || o_nocache_eof)                                           Line 2517
        invalidate_cache (STDOUT_FILENO, 0);                                    Line 2518
    }                                                                           
                                                                                
  finish_up ();                                                                 Line 2521
  return exit_status;                                                           Line 2522
}                                                                               Block 56