/* 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