[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
"dd skip=N of=unseekable" patch for POSIX conformance
From: |
Paul Eggert |
Subject: |
"dd skip=N of=unseekable" patch for POSIX conformance |
Date: |
Fri, 27 May 2005 22:57:22 -0700 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux) |
I installed this patch after a question came up about it on the Open
Group reflector. Unfortunately I don't have any unseekable devices to
test it on.
2005-05-27 Paul Eggert <address@hidden>
* NEWS: dd seek=N now conforms to POSIX if the output isn't seekable.
* src/dd.c (skip): Return the number of records that were not
skipped due to encountering EOF.
(dd_copy): If the file wasn't seekable and EOF was encountered,
write zeros past EOF until the desired offset is reached.
Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.291
diff -p -u -r1.291 NEWS
--- NEWS 27 May 2005 20:31:59 -0000 1.291
+++ NEWS 28 May 2005 04:22:07 -0000
@@ -63,6 +63,10 @@ GNU coreutils NEWS
On hosts lacking the INFO signal, dd no longer treats the USR1
signal as if it were INFO when POSIXLY_CORRECT is set.
+ If the file F is non-seekable and contains fewer than N blocks,
+ then before copying "dd seek=N of=F" now extends F with zeroed
+ blocks until F contains N blocks.
+
fold changes:
When POSIXLY_CORRECT is set, "fold file -3" is now equivalent to
Index: src/dd.c
===================================================================
RCS file: /fetish/cu/src/dd.c,v
retrieving revision 1.182
diff -p -u -r1.182 dd.c
--- src/dd.c 14 May 2005 07:58:37 -0000 1.182
+++ src/dd.c 28 May 2005 04:22:07 -0000
@@ -1130,9 +1130,11 @@ skip_via_lseek (char const *filename, in
/* Throw away RECORDS blocks of BLOCKSIZE 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 BUF, if necessary. RECORDS must be
- nonzero. If fdesc is STDIN_FILENO, advance the input offset. */
+ 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. */
-static void
+static uintmax_t
skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
char *buf)
{
@@ -1148,11 +1150,13 @@ skip (int fdesc, char const *file, uintm
{
if (fdesc == STDIN_FILENO)
advance_input_offset (offset);
+ return 0;
}
else
{
int lseek_errno = errno;
- while (records--)
+
+ do
{
ssize_t nread = iread (fdesc, buf, blocksize);
if (nread < 0)
@@ -1170,14 +1174,15 @@ skip (int fdesc, char const *file, uintm
error (0, lseek_errno, _("%s: cannot seek"), quote (file));
quit (EXIT_FAILURE);
}
- /* 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.
- FIXME: maybe give a warning. */
+
if (nread == 0)
break;
if (fdesc == STDIN_FILENO)
advance_input_offset (nread);
}
+ while (records-- != 0);
+
+ return records;
}
}
@@ -1390,10 +1395,32 @@ dd_copy (void)
}
if (skip_records != 0)
- skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
+ {
+ skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
+ /* 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 if the
+ call to 'skip' returns nonzero. FIXME: maybe give a warning. */
+ }
if (seek_records != 0)
- skip (STDOUT_FILENO, output_file, seek_records, output_blocksize, obuf);
+ {
+ uintmax_t write_records = skip (STDOUT_FILENO, output_file,
+ seek_records, output_blocksize, obuf);
+
+ if (write_records != 0)
+ {
+ memset (obuf, 0, output_blocksize);
+
+ do
+ if (iwrite (STDOUT_FILENO, obuf, output_blocksize)
+ != output_blocksize)
+ {
+ error (0, errno, _("writing to %s"), quote (output_file));
+ quit (EXIT_FAILURE);
+ }
+ while (--write_records != 0);
+ }
+ }
if (max_records == 0)
return exit_status;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- "dd skip=N of=unseekable" patch for POSIX conformance,
Paul Eggert <=