~ubuntu-branches/ubuntu/utopic/coreutils/utopic-proposed

« back to all changes in this revision

Viewing changes to src/dd.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-11-28 03:03:42 UTC
  • mfrom: (8.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20121128030342-21zanj8354gas5gr
Tags: 8.20-3ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Make 'uname -i -p' return the real processor/hardware, instead of
    unknown.
  - Build-depend on gettext:any instead of on gettext, so that apt-get can
    properly resolve build-dependencies on the tool when cross-building.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* dd -- convert a file while copying it.
2
 
   Copyright (C) 1985, 1990-1991, 1995-2011 Free Software Foundation, Inc.
 
2
   Copyright (C) 1985-2012 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software: you can redistribute it and/or modify
5
5
   it under the terms of the GNU General Public License as published by
20
20
 
21
21
#define SWAB_ALIGN_OFFSET 2
22
22
 
 
23
#include <assert.h>
23
24
#include <sys/types.h>
24
25
#include <signal.h>
25
26
#include <getopt.h>
36
37
#include "xstrtol.h"
37
38
#include "xtime.h"
38
39
 
39
 
/* The official name of this program (e.g., no `g' prefix).  */
 
40
/* The official name of this program (e.g., no 'g' prefix).  */
40
41
#define PROGRAM_NAME "dd"
41
42
 
42
43
#define AUTHORS \
126
127
    C_NOCREAT = 010000,
127
128
    C_EXCL = 020000,
128
129
    C_FDATASYNC = 040000,
129
 
    C_FSYNC = 0100000
 
130
    C_FSYNC = 0100000,
 
131
 
 
132
    C_SPARSE = 0200000
130
133
  };
131
134
 
132
135
/* Status bit masks.  */
133
136
enum
134
137
  {
135
 
    STATUS_NOXFER = 01
 
138
    STATUS_NOXFER = 01,
 
139
    STATUS_NOCOUNTS = 02,
 
140
    STATUS_LAST = STATUS_NOCOUNTS,
 
141
    STATUS_NONE = STATUS_LAST | (STATUS_LAST - 1)
136
142
  };
137
143
 
138
144
/* The name of the input file, or NULL for the standard input. */
153
159
/* Conversion buffer size, in bytes.  0 prevents conversions. */
154
160
static size_t conversion_blocksize = 0;
155
161
 
156
 
/* Skip this many records of `input_blocksize' bytes before input. */
 
162
/* Skip this many records of 'input_blocksize' bytes before input. */
157
163
static uintmax_t skip_records = 0;
158
164
 
159
 
/* Skip this many records of `output_blocksize' bytes before output. */
 
165
/* Skip this many bytes before input in addition of 'skip_records'
 
166
   records.  */
 
167
static size_t skip_bytes = 0;
 
168
 
 
169
/* Skip this many records of 'output_blocksize' bytes before output. */
160
170
static uintmax_t seek_records = 0;
161
171
 
 
172
/* Skip this many bytes in addition to 'seek_records' records before
 
173
   output.  */
 
174
static uintmax_t seek_bytes = 0;
 
175
 
 
176
/* Whether the final output was done with a seek (rather than a write).  */
 
177
static bool final_op_was_seek;
 
178
 
162
179
/* Copy only this many records.  The default is effectively infinity.  */
163
180
static uintmax_t max_records = (uintmax_t) -1;
164
181
 
 
182
/* Copy this many bytes in addition to 'max_records' records.  */
 
183
static size_t max_bytes = 0;
 
184
 
165
185
/* Bit vector of conversions to apply. */
166
186
static int conversions_mask = 0;
167
187
 
219
239
/* Output buffer. */
220
240
static char *obuf;
221
241
 
222
 
/* Current index into `obuf'. */
 
242
/* Current index into 'obuf'. */
223
243
static size_t oc = 0;
224
244
 
225
 
/* Index into current line, for `conv=block' and `conv=unblock'.  */
 
245
/* Index into current line, for 'conv=block' and 'conv=unblock'.  */
226
246
static size_t col = 0;
227
247
 
228
248
/* The set of signals that are caught.  */
241
261
static ssize_t (*iread_fnc) (int fd, char *buf, size_t size);
242
262
 
243
263
/* A longest symbol in the struct symbol_values tables below.  */
244
 
#define LONGEST_SYMBOL "fdatasync"
 
264
#define LONGEST_SYMBOL "count_bytes"
245
265
 
246
266
/* A symbol and the corresponding integer value.  */
247
267
struct symbol_value
260
280
  {"unblock", C_UNBLOCK | C_TWOBUFS},   /* Fixed to variable length records. */
261
281
  {"lcase", C_LCASE | C_TWOBUFS},       /* Translate upper to lower case. */
262
282
  {"ucase", C_UCASE | C_TWOBUFS},       /* Translate lower to upper case. */
 
283
  {"sparse", C_SPARSE},         /* Try to sparsely write output. */
263
284
  {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
264
285
  {"noerror", C_NOERROR},       /* Ignore i/o errors. */
265
286
  {"nocreat", C_NOCREAT},       /* Do not create output file.  */
296
317
    O_FULLBLOCK = FFS_MASK (v),
297
318
    v2 = v ^ O_FULLBLOCK,
298
319
 
299
 
    O_NOCACHE = FFS_MASK (v2)
 
320
    O_NOCACHE = FFS_MASK (v2),
 
321
    v3 = v2 ^ O_NOCACHE,
 
322
 
 
323
    O_COUNT_BYTES = FFS_MASK (v3),
 
324
    v4 = v3 ^ O_COUNT_BYTES,
 
325
 
 
326
    O_SKIP_BYTES = FFS_MASK (v4),
 
327
    v5 = v4 ^ O_SKIP_BYTES,
 
328
 
 
329
    O_SEEK_BYTES = FFS_MASK (v5)
300
330
  };
301
331
 
302
332
/* Ensure that we got something.  */
303
333
verify (O_FULLBLOCK != 0);
304
334
verify (O_NOCACHE != 0);
 
335
verify (O_COUNT_BYTES != 0);
 
336
verify (O_SKIP_BYTES != 0);
 
337
verify (O_SEEK_BYTES != 0);
305
338
 
306
339
#define MULTIPLE_BITS_SET(i) (((i) & ((i) - 1)) != 0)
307
340
 
308
341
/* Ensure that this is a single-bit value.  */
309
342
verify ( ! MULTIPLE_BITS_SET (O_FULLBLOCK));
310
343
verify ( ! MULTIPLE_BITS_SET (O_NOCACHE));
 
344
verify ( ! MULTIPLE_BITS_SET (O_COUNT_BYTES));
 
345
verify ( ! MULTIPLE_BITS_SET (O_SKIP_BYTES));
 
346
verify ( ! MULTIPLE_BITS_SET (O_SEEK_BYTES));
311
347
 
312
348
/* Flags, for iflag="..." and oflag="...".  */
313
349
static struct symbol_value const flags[] =
314
350
{
315
 
  {"append",    O_APPEND},
316
 
  {"binary",    O_BINARY},
317
 
  {"cio",       O_CIO},
318
 
  {"direct",    O_DIRECT},
319
 
  {"directory", O_DIRECTORY},
320
 
  {"dsync",     O_DSYNC},
321
 
  {"noatime",   O_NOATIME},
322
 
  {"nocache",   O_NOCACHE},   /* Discard cache.  */
323
 
  {"noctty",    O_NOCTTY},
324
 
  {"nofollow",  HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0},
325
 
  {"nolinks",   O_NOLINKS},
326
 
  {"nonblock",  O_NONBLOCK},
327
 
  {"sync",      O_SYNC},
328
 
  {"text",      O_TEXT},
329
 
  {"fullblock", O_FULLBLOCK}, /* Accumulate full blocks from input.  */
 
351
  {"append",      O_APPEND},
 
352
  {"binary",      O_BINARY},
 
353
  {"cio",         O_CIO},
 
354
  {"direct",      O_DIRECT},
 
355
  {"directory",   O_DIRECTORY},
 
356
  {"dsync",       O_DSYNC},
 
357
  {"noatime",     O_NOATIME},
 
358
  {"nocache",     O_NOCACHE},   /* Discard cache.  */
 
359
  {"noctty",      O_NOCTTY},
 
360
  {"nofollow",    HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0},
 
361
  {"nolinks",     O_NOLINKS},
 
362
  {"nonblock",    O_NONBLOCK},
 
363
  {"sync",        O_SYNC},
 
364
  {"text",        O_TEXT},
 
365
  {"fullblock",   O_FULLBLOCK}, /* Accumulate full blocks from input.  */
 
366
  {"count_bytes", O_COUNT_BYTES},
 
367
  {"skip_bytes",  O_SKIP_BYTES},
 
368
  {"seek_bytes",  O_SEEK_BYTES},
330
369
  {"",          0}
331
370
};
332
371
 
334
373
static struct symbol_value const statuses[] =
335
374
{
336
375
  {"noxfer",    STATUS_NOXFER},
 
376
  {"none",      STATUS_NONE},
337
377
  {"",          0}
338
378
};
339
379
 
475
515
usage (int status)
476
516
{
477
517
  if (status != EXIT_SUCCESS)
478
 
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
479
 
             program_name);
 
518
    emit_try_help ();
480
519
  else
481
520
    {
482
521
      printf (_("\
490
529
  bs=BYTES        read and write up to BYTES bytes at a time\n\
491
530
  cbs=BYTES       convert BYTES bytes at a time\n\
492
531
  conv=CONVS      convert the file as per the comma separated symbol list\n\
493
 
  count=BLOCKS    copy only BLOCKS input blocks\n\
 
532
  count=N         copy only N input blocks\n\
494
533
  ibs=BYTES       read up to BYTES bytes at a time (default: 512)\n\
495
534
"), stdout);
496
535
      fputs (_("\
499
538
  obs=BYTES       write BYTES bytes at a time (default: 512)\n\
500
539
  of=FILE         write to FILE instead of stdout\n\
501
540
  oflag=FLAGS     write as per the comma separated symbol list\n\
502
 
  seek=BLOCKS     skip BLOCKS obs-sized blocks at start of output\n\
503
 
  skip=BLOCKS     skip BLOCKS ibs-sized blocks at start of input\n\
504
 
  status=noxfer   suppress transfer statistics\n\
 
541
  seek=N          skip N obs-sized blocks at start of output\n\
 
542
  skip=N          skip N ibs-sized blocks at start of input\n\
 
543
  status=WHICH    WHICH info to suppress outputting to stderr;\n\
 
544
                  'noxfer' suppresses transfer stats, 'none' suppresses all\n\
505
545
"), stdout);
506
546
      fputs (_("\
507
547
\n\
508
 
BLOCKS and BYTES may be followed by the following multiplicative suffixes:\n\
 
548
N and BYTES may be followed by the following multiplicative suffixes:\n\
509
549
c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M\n\
510
550
GB =1000*1000*1000, G =1024*1024*1024, and so on for T, P, E, Z, Y.\n\
511
551
\n\
520
560
  unblock   replace trailing spaces in cbs-size records with newline\n\
521
561
  lcase     change upper case to lower case\n\
522
562
  ucase     change lower case to upper case\n\
 
563
  sparse    try to seek rather than write the output for NUL input blocks\n\
523
564
  swab      swap every pair of input bytes\n\
524
565
  sync      pad every input block with NULs to ibs-size; when used\n\
525
566
            with block or unblock, pad with spaces rather than NULs\n\
569
610
        fputs (_("  binary    use binary I/O for data\n"), stdout);
570
611
      if (O_TEXT)
571
612
        fputs (_("  text      use text I/O for data\n"), stdout);
 
613
      if (O_COUNT_BYTES)
 
614
        fputs (_("  count_bytes  treat 'count=N' as a byte count (iflag only)\n\
 
615
"), stdout);
 
616
      if (O_SKIP_BYTES)
 
617
        fputs (_("  skip_bytes  treat 'skip=N' as a byte count (iflag only)\n\
 
618
"), stdout);
 
619
      if (O_SEEK_BYTES)
 
620
        fputs (_("  seek_bytes  treat 'seek=N' as a byte count (oflag only)\n\
 
621
"), stdout);
572
622
 
573
623
      {
574
624
        char const *siginfo_name = (SIGINFO == SIGUSR1 ? "USR1" : "INFO");
575
625
        printf (_("\
576
626
\n\
577
 
Sending a %s signal to a running `dd' process makes it\n\
 
627
Sending a %s signal to a running 'dd' process makes it\n\
578
628
print I/O statistics to standard error and then resume copying.\n\
579
629
\n\
580
630
  $ dd if=/dev/zero of=/dev/null& pid=$!\n\
619
669
static void
620
670
print_stats (void)
621
671
{
622
 
  xtime_t now = gethrxtime ();
623
672
  char hbuf[LONGEST_HUMAN_READABLE + 1];
624
673
  int human_opts =
625
674
    (human_autoscale | human_round_to_nearest
627
676
  double delta_s;
628
677
  char const *bytes_per_second;
629
678
 
 
679
  if ((status_flags & STATUS_NONE) == STATUS_NONE)
 
680
    return;
 
681
 
630
682
  fprintf (stderr,
631
683
           _("%"PRIuMAX"+%"PRIuMAX" records in\n"
632
684
             "%"PRIuMAX"+%"PRIuMAX" records out\n"),
652
704
           w_bytes,
653
705
           human_readable (w_bytes, hbuf, human_opts, 1, 1));
654
706
 
 
707
  xtime_t now = gethrxtime ();
655
708
  if (start_time < now)
656
709
    {
657
710
      double XTIME_PRECISIONe0 = XTIME_PRECISION;
983
1036
 
984
1037
  while (total_written < size)
985
1038
    {
986
 
      ssize_t nwritten;
 
1039
      ssize_t nwritten = 0;
987
1040
      process_signals ();
988
 
      nwritten = write (fd, buf + total_written, size - total_written);
 
1041
 
 
1042
      /* Perform a seek for a NUL block if sparse output is enabled.  */
 
1043
      final_op_was_seek = false;
 
1044
      if ((conversions_mask & C_SPARSE) && is_nul (buf, size))
 
1045
        {
 
1046
          if (lseek (fd, size, SEEK_CUR) < 0)
 
1047
            {
 
1048
              conversions_mask &= ~C_SPARSE;
 
1049
              /* Don't warn about the advisory sparse request.  */
 
1050
            }
 
1051
          else
 
1052
            {
 
1053
              final_op_was_seek = true;
 
1054
              nwritten = size;
 
1055
            }
 
1056
        }
 
1057
 
 
1058
      if (!nwritten)
 
1059
        nwritten = write (fd, buf + total_written, size - total_written);
 
1060
 
989
1061
      if (nwritten < 0)
990
1062
        {
991
1063
          if (errno != EINTR)
1009
1081
  return total_written;
1010
1082
}
1011
1083
 
1012
 
/* Write, then empty, the output buffer `obuf'. */
 
1084
/* Write, then empty, the output buffer 'obuf'. */
1013
1085
 
1014
1086
static void
1015
1087
write_output (void)
1121
1193
{
1122
1194
  int i;
1123
1195
  size_t blocksize = 0;
 
1196
  uintmax_t count = (uintmax_t) -1;
 
1197
  uintmax_t skip = 0;
 
1198
  uintmax_t seek = 0;
1124
1199
 
1125
1200
  for (i = optind; i < argc; i++)
1126
1201
    {
1176
1251
              conversion_blocksize = n;
1177
1252
            }
1178
1253
          else if (operand_is (name, "skip"))
1179
 
            skip_records = n;
 
1254
            skip = n;
1180
1255
          else if (operand_is (name, "seek"))
1181
 
            seek_records = n;
 
1256
            seek = n;
1182
1257
          else if (operand_is (name, "count"))
1183
 
            max_records = n;
 
1258
            count = n;
1184
1259
          else
1185
1260
            {
1186
1261
              error (0, 0, _("unrecognized operand %s"), quote (name));
1217
1292
      usage (EXIT_FAILURE);
1218
1293
    }
1219
1294
 
 
1295
  if (input_flags & O_SEEK_BYTES)
 
1296
    {
 
1297
      error (0, 0, "%s: %s", _("invalid input flag"), "'seek_bytes'");
 
1298
      usage (EXIT_FAILURE);
 
1299
    }
 
1300
 
 
1301
  if (output_flags & (O_COUNT_BYTES | O_SKIP_BYTES))
 
1302
    {
 
1303
      error (0, 0, "%s: %s", _("invalid output flag"),
 
1304
             output_flags & O_COUNT_BYTES ? "'count_bytes'" : "'skip_bytes'");
 
1305
      usage (EXIT_FAILURE);
 
1306
    }
 
1307
 
 
1308
  if (input_flags & O_SKIP_BYTES && skip != 0)
 
1309
    {
 
1310
      skip_records = skip / input_blocksize;
 
1311
      skip_bytes = skip % input_blocksize;
 
1312
    }
 
1313
  else if (skip != 0)
 
1314
    skip_records = skip;
 
1315
 
 
1316
  if (input_flags & O_COUNT_BYTES && count != (uintmax_t) -1)
 
1317
    {
 
1318
      max_records = count / input_blocksize;
 
1319
      max_bytes = count % input_blocksize;
 
1320
    }
 
1321
  else if (count != (uintmax_t) -1)
 
1322
    max_records = count;
 
1323
 
 
1324
  if (output_flags & O_SEEK_BYTES && seek != 0)
 
1325
    {
 
1326
      seek_records = seek / output_blocksize;
 
1327
      seek_bytes = seek % output_blocksize;
 
1328
    }
 
1329
  else if (seek != 0)
 
1330
    seek_records = seek;
 
1331
 
1220
1332
  /* Warn about partial reads if bs=SIZE is given and iflag=fullblock
1221
1333
     is not, and if counting or skipping bytes or using direct I/O.
1222
1334
     This helps to avoid confusion with miscounts, and to avoid issues
1306
1418
    *cp = trans_table[to_uchar (*cp)];
1307
1419
}
1308
1420
 
1309
 
/* If true, the last char from the previous call to `swab_buffer'
1310
 
   is saved in `saved_char'.  */
 
1421
/* If true, the last char from the previous call to 'swab_buffer'
 
1422
   is saved in 'saved_char'.  */
1311
1423
static bool char_is_saved = false;
1312
1424
 
1313
1425
/* Odd char from previous call.  */
1412
1524
# define skip_via_lseek(Filename, Fd, Offset, Whence) lseek (Fd, Offset, Whence)
1413
1525
#endif
1414
1526
 
1415
 
/* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
1416
 
   which is open with read permission for FILE.  Store up to BLOCKSIZE
1417
 
   bytes of the data at a time in BUF, if necessary.  RECORDS must be
1418
 
   nonzero.  If fdesc is STDIN_FILENO, advance the input offset.
1419
 
   Return the number of records remaining, i.e., that were not skipped
1420
 
   because EOF was reached.  */
 
1527
/* Throw away RECORDS blocks of BLOCKSIZE bytes plus BYTES bytes on
 
1528
   file descriptor FDESC, which is open with read permission for FILE.
 
1529
   Store up to BLOCKSIZE bytes of the data at a time in BUF, if
 
1530
   necessary. RECORDS or BYTES must be nonzero. If FDESC is
 
1531
   STDIN_FILENO, advance the input offset. Return the number of
 
1532
   records remaining, i.e., that were not skipped because EOF was
 
1533
   reached.  If FDESC is STDOUT_FILENO, on return, BYTES is the
 
1534
   remaining bytes in addition to the remaining records.  */
1421
1535
 
1422
1536
static uintmax_t
1423
1537
skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
1424
 
      char *buf)
 
1538
      size_t *bytes, char *buf)
1425
1539
{
1426
 
  uintmax_t offset = records * blocksize;
 
1540
  uintmax_t offset = records * blocksize + *bytes;
1427
1541
 
1428
1542
  /* Try lseek and if an error indicates it was an inappropriate operation --
1429
1543
     or if the file offset is not representable as an off_t --
1438
1552
           struct stat st;
1439
1553
           if (fstat (STDIN_FILENO, &st) != 0)
1440
1554
             error (EXIT_FAILURE, errno, _("cannot fstat %s"), quote (file));
1441
 
           if (S_ISREG (st.st_mode) && st.st_size < (input_offset + offset))
 
1555
           if (usable_st_size (&st) && st.st_size < input_offset + offset)
1442
1556
             {
1443
1557
               /* When skipping past EOF, return the number of _full_ blocks
1444
1558
                * that are not skipped, and set offset to EOF, so the caller
1451
1565
           advance_input_offset (offset);
1452
1566
        }
1453
1567
      else
1454
 
        records = 0;
 
1568
        {
 
1569
          records = 0;
 
1570
          *bytes = 0;
 
1571
        }
1455
1572
      return records;
1456
1573
    }
1457
1574
  else
1492
1609
 
1493
1610
      do
1494
1611
        {
1495
 
          ssize_t nread = iread_fnc (fdesc, buf, blocksize);
 
1612
          ssize_t nread = iread_fnc (fdesc, buf, records ? blocksize : *bytes);
1496
1613
          if (nread < 0)
1497
1614
            {
1498
1615
              if (fdesc == STDIN_FILENO)
1499
1616
                {
1500
1617
                  error (0, errno, _("reading %s"), quote (file));
1501
1618
                  if (conversions_mask & C_NOERROR)
1502
 
                    {
1503
 
                      print_stats ();
1504
 
                      continue;
1505
 
                    }
 
1619
                    print_stats ();
1506
1620
                }
1507
1621
              else
1508
1622
                error (0, lseek_errno, _("%s: cannot seek"), quote (file));
1509
1623
              quit (EXIT_FAILURE);
1510
1624
            }
1511
 
 
1512
 
          if (nread == 0)
 
1625
          else if (nread == 0)
1513
1626
            break;
1514
 
          if (fdesc == STDIN_FILENO)
 
1627
          else if (fdesc == STDIN_FILENO)
1515
1628
            advance_input_offset (nread);
 
1629
 
 
1630
          if (records != 0)
 
1631
            records--;
 
1632
          else
 
1633
            *bytes = 0;
1516
1634
        }
1517
 
      while (--records != 0);
 
1635
      while (records || *bytes);
1518
1636
 
1519
1637
      return records;
1520
1638
    }
1589
1707
}
1590
1708
 
1591
1709
/* Copy NREAD bytes of BUF, doing conv=block
1592
 
   (pad newline-terminated records to `conversion_blocksize',
 
1710
   (pad newline-terminated records to 'conversion_blocksize',
1593
1711
   replacing the newline with trailing spaces).  */
1594
1712
 
1595
1713
static void
1621
1739
}
1622
1740
 
1623
1741
/* Copy NREAD bytes of BUF, doing conv=unblock
1624
 
   (replace trailing spaces in `conversion_blocksize'-sized records
 
1742
   (replace trailing spaces in 'conversion_blocksize'-sized records
1625
1743
   with a newline).  */
1626
1744
 
1627
1745
static void
1645
1763
        pending_spaces++;
1646
1764
      else
1647
1765
        {
1648
 
          /* `c' is the character after a run of spaces that were not
 
1766
          /* 'c' is the character after a run of spaces that were not
1649
1767
             at the end of the conversion buffer.  Output them.  */
1650
1768
          while (pending_spaces)
1651
1769
            {
1734
1852
  int exit_status = EXIT_SUCCESS;
1735
1853
  size_t n_bytes_read;
1736
1854
 
1737
 
  /* Leave at least one extra byte at the beginning and end of `ibuf'
 
1855
  /* Leave at least one extra byte at the beginning and end of 'ibuf'
1738
1856
     for conv=swab, but keep the buffer address even.  But some peculiar
1739
1857
     device drivers work only with word-aligned buffers, so leave an
1740
1858
     extra two bytes.  */
1778
1896
      obuf = ibuf;
1779
1897
    }
1780
1898
 
1781
 
  if (skip_records != 0)
 
1899
  /* Write a sentinel to the slop after the buffer,
 
1900
     to allow efficient checking for NUL blocks.  */
 
1901
  assert (sizeof (uintptr_t) <= OUTPUT_BLOCK_SLOP);
 
1902
  memset (obuf + output_blocksize, 1, sizeof (uintptr_t));
 
1903
 
 
1904
  if (skip_records != 0 || skip_bytes != 0)
1782
1905
    {
1783
 
      uintmax_t us_bytes = input_offset + (skip_records * input_blocksize);
 
1906
      uintmax_t us_bytes = input_offset + (skip_records * input_blocksize)
 
1907
                           + skip_bytes;
1784
1908
      uintmax_t us_blocks = skip (STDIN_FILENO, input_file,
1785
 
                                  skip_records, input_blocksize, ibuf);
 
1909
                                  skip_records, input_blocksize, &skip_bytes,
 
1910
                                  ibuf);
1786
1911
      us_bytes -= input_offset;
1787
1912
 
1788
1913
      /* POSIX doesn't say what to do when dd detects it has been
1798
1923
        }
1799
1924
    }
1800
1925
 
1801
 
  if (seek_records != 0)
 
1926
  if (seek_records != 0 || seek_bytes != 0)
1802
1927
    {
 
1928
      size_t bytes = seek_bytes;
1803
1929
      uintmax_t write_records = skip (STDOUT_FILENO, output_file,
1804
 
                                      seek_records, output_blocksize, obuf);
 
1930
                                      seek_records, output_blocksize, &bytes,
 
1931
                                      obuf);
1805
1932
 
1806
 
      if (write_records != 0)
 
1933
      if (write_records != 0 || bytes != 0)
1807
1934
        {
1808
 
          memset (obuf, 0, output_blocksize);
 
1935
          memset (obuf, 0, write_records ? output_blocksize : bytes);
1809
1936
 
1810
1937
          do
1811
 
            if (iwrite (STDOUT_FILENO, obuf, output_blocksize)
1812
 
                != output_blocksize)
1813
 
              {
1814
 
                error (0, errno, _("writing to %s"), quote (output_file));
1815
 
                quit (EXIT_FAILURE);
1816
 
              }
1817
 
          while (--write_records != 0);
 
1938
            {
 
1939
              size_t size = write_records ? output_blocksize : bytes;
 
1940
              if (iwrite (STDOUT_FILENO, obuf, size) != size)
 
1941
                {
 
1942
                  error (0, errno, _("writing to %s"), quote (output_file));
 
1943
                  quit (EXIT_FAILURE);
 
1944
                }
 
1945
 
 
1946
              if (write_records != 0)
 
1947
                write_records--;
 
1948
              else
 
1949
                bytes = 0;
 
1950
            }
 
1951
          while (write_records || bytes);
1818
1952
        }
1819
1953
    }
1820
1954
 
1821
 
  if (max_records == 0)
 
1955
  if (max_records == 0 && max_bytes == 0)
1822
1956
    return exit_status;
1823
1957
 
1824
1958
  while (1)
1825
1959
    {
1826
 
      if (r_partial + r_full >= max_records)
 
1960
      if (r_partial + r_full >= max_records + !!max_bytes)
1827
1961
        break;
1828
1962
 
1829
1963
      /* Zero the buffer before reading, so that if we get a read error,
1834
1968
                (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',
1835
1969
                input_blocksize);
1836
1970
 
1837
 
      nread = iread_fnc (STDIN_FILENO, ibuf, input_blocksize);
 
1971
      if (r_partial + r_full >= max_records)
 
1972
        nread = iread_fnc (STDIN_FILENO, ibuf, max_bytes);
 
1973
      else
 
1974
        nread = iread_fnc (STDIN_FILENO, ibuf, input_blocksize);
1838
1975
 
1839
1976
      if (nread >= 0 && i_nocache)
1840
1977
        invalidate_cache (STDIN_FILENO, nread);
1949
2086
  if ((conversions_mask & C_BLOCK) && col > 0)
1950
2087
    {
1951
2088
      /* If the final input line didn't end with a '\n', pad
1952
 
         the output block to `conversion_blocksize' chars.  */
 
2089
         the output block to 'conversion_blocksize' chars.  */
1953
2090
      size_t i;
1954
2091
      for (i = col; i < conversion_blocksize; i++)
1955
2092
        output_char (space_character);
1975
2112
        }
1976
2113
    }
1977
2114
 
 
2115
  /* If the last write was converted to a seek, then for a regular file
 
2116
     or shared memory object, ftruncate to extend the size.  */
 
2117
  if (final_op_was_seek)
 
2118
    {
 
2119
      struct stat stdout_stat;
 
2120
      if (fstat (STDOUT_FILENO, &stdout_stat) != 0)
 
2121
        {
 
2122
          error (0, errno, _("cannot fstat %s"), quote (output_file));
 
2123
          return EXIT_FAILURE;
 
2124
        }
 
2125
      if (S_ISREG (stdout_stat.st_mode) || S_TYPEISSHM (&stdout_stat))
 
2126
        {
 
2127
          off_t output_offset = lseek (STDOUT_FILENO, 0, SEEK_CUR);
 
2128
          if (output_offset > stdout_stat.st_size)
 
2129
            {
 
2130
              if (ftruncate (STDOUT_FILENO, output_offset) != 0)
 
2131
                {
 
2132
                  error (0, errno,
 
2133
                         _("failed to truncate to %"PRIuMAX" bytes"
 
2134
                           " in output file %s"),
 
2135
                         output_offset, quote (output_file));
 
2136
                  return EXIT_FAILURE;
 
2137
                }
 
2138
            }
 
2139
        }
 
2140
    }
 
2141
 
1978
2142
  if ((conversions_mask & C_FDATASYNC) && fdatasync (STDOUT_FILENO) != 0)
1979
2143
    {
1980
2144
      if (errno != ENOSYS && errno != EINVAL)
2055
2219
    }
2056
2220
  else
2057
2221
    {
2058
 
      mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
 
2222
      mode_t perms = MODE_RW_UGO;
2059
2223
      int opts
2060
2224
        = (output_flags
2061
2225
           | (conversions_mask & C_NOCREAT ? 0 : O_CREAT)
2063
2227
           | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
2064
2228
 
2065
2229
      /* Open the output file with *read* access only if we might
2066
 
         need to read to satisfy a `seek=' request.  If we can't read
 
2230
         need to read to satisfy a 'seek=' request.  If we can't read
2067
2231
         the file, go ahead with write-only access; it might work.  */
2068
2232
      if ((! seek_records
2069
2233
           || fd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
2073
2237
 
2074
2238
      if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
2075
2239
        {
2076
 
          uintmax_t size = seek_records * output_blocksize;
 
2240
          uintmax_t size = seek_records * output_blocksize + seek_bytes;
2077
2241
          unsigned long int obs = output_blocksize;
2078
2242
 
2079
2243
          if (OFF_T_MAX / output_blocksize < seek_records)
2110
2274
 
2111
2275
  exit_status = dd_copy ();
2112
2276
 
2113
 
  if (max_records == 0)
 
2277
  if (max_records == 0 && max_bytes == 0)
2114
2278
    {
2115
2279
      /* Special case to invalidate cache to end of file.  */
2116
2280
      if (i_nocache && !invalidate_cache (STDIN_FILENO, 0))
2128
2292
    }
2129
2293
  else if (max_records != (uintmax_t) -1)
2130
2294
    {
2131
 
      /* Invalidate any pending region less that page size,
 
2295
      /* Invalidate any pending region less than page size,
2132
2296
         in case the kernel might round up.  */
2133
2297
      if (i_nocache)
2134
2298
        invalidate_cache (STDIN_FILENO, 0);