summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-11-25 08:54:58 +0000
committerJim Meyering <jim@meyering.net>2000-11-25 08:54:58 +0000
commit019bdadfc9fd0a8608b8ae812aa1a6e651f4c709 (patch)
treeaac2c5c98cbfa54978632932b06f2f8e5f0cd21c /src
parent7d57b3419605e20c8b206c1f5902e54a2611ac75 (diff)
downloadcoreutils-019bdadfc9fd0a8608b8ae812aa1a6e651f4c709.tar.xz
remove bskip
adapt skip to skip either by bytes or by blocks
Diffstat (limited to 'src')
-rw-r--r--src/dd.c128
1 files changed, 51 insertions, 77 deletions
diff --git a/src/dd.c b/src/dd.c
index 01447e50a..658b45579 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -784,100 +784,71 @@ buggy_lseek_support (int fdesc)
&& (S_ISCHR (stats.st_mode)));
}
-/* 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. */
+enum Unit
+{
+ U_BYTES,
+ U_BLOCKS
+};
+typedef enum Unit Unit;
+
+/* Discard N bytes or blocks (determined by UNITS) of the data 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. */
static void
-skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
+skip (int fdesc, char const *file, uintmax_t n, Unit units, size_t blocksize,
unsigned char *buf)
{
- off_t o;
+ off_t o = (units == U_BYTES ? n : n * blocksize);
/* Try lseek and if an error indicates it was an inappropriate
operation, fall back on using read. Some broken versions of
lseek may return zero, so count that as an error too as a valid
zero return is not possible here. */
- o = records * blocksize;
- if (o / blocksize != records
- || buggy_lseek_support (fdesc)
- || lseek (fdesc, o, SEEK_CUR) <= 0)
- {
- while (records-- > 0)
- {
- int nread;
-
- nread = safe_read (fdesc, buf, blocksize);
- if (nread < 0)
- {
- error (0, errno, _("reading %s"), quote (file));
- quit (1);
- }
- /* 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;
- }
- }
-}
-/* Throw away BYTES on file descriptor FDESC,
- which is open with read permission for FILE.
- Store up to BYTES of the data (one BLOCKSIZE at a time) in BUF,
- if necessary. */
-
-static void
-bskip (int fdesc, char *file, uintmax_t bytes, size_t blocksize,
- unsigned char *buf)
-{
- struct stat stats;
+ if ((units == U_BYTES || o / blocksize == n)
+ && !buggy_lseek_support (fdesc)
+ && lseek (fdesc, o, SEEK_CUR) > 0)
+ return;
- /* Use fstat instead of checking for errno == ESPIPE because
- lseek doesn't work on some special files but doesn't return an
- error, either. */
- /* FIXME: can this really happen? What system? */
- if (fstat (fdesc, &stats))
- {
- error (0, errno, "%s", file);
- quit (1);
- }
-
- /* Try lseek and if an error indicates it was an inappropriate
- operation, fall back on using read. */
- if (lseek (fdesc, bytes, SEEK_SET) == -1)
+ do
{
int nread;
- while ((bytes-=blocksize) >= 0)
+ /* Decrement N according to UNITS: if we're counting bytes, then
+ decrement N by BLOCKSIZE (the last read may be smaller than BLOCKSIZE),
+ otherwise, simply decrement N by 1. */
+ if (units == U_BYTES)
{
- nread = safe_read (fdesc, buf, blocksize);
- if (nread < 0)
+ if (n < blocksize)
{
- error (0, errno, "%s", file);
- quit (1);
+ n = 0;
+ blocksize = n;
+ }
+ else
+ {
+ n -= blocksize;
}
- /* 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;
}
-
- /* sop up any residue .. */
- if (bytes < 0)
+ else
{
- bytes += blocksize;
+ --n;
+ }
- nread = safe_read (fdesc, buf, bytes);
- if (nread < 0)
- {
- error (0, errno, "%s", file);
- quit (1);
- }
+ nread = safe_read (fdesc, buf, blocksize);
+ if (nread < 0)
+ {
+ error (0, errno, _("reading %s"), quote (file));
+ quit (1);
}
+ /* 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;
}
+ while (n > 0);
}
/* Copy NREAD bytes of BUF, with no conversions. */
@@ -1025,10 +996,12 @@ dd_copy (void)
}
if (skip_records != 0)
- skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
+ skip (STDIN_FILENO, input_file, skip_records, U_BLOCKS,
+ input_blocksize, ibuf);
if (skip_bytes != 0)
- bskip (STDIN_FILENO, input_file, skip_bytes, input_blocksize, ibuf);
+ skip (STDIN_FILENO, input_file, skip_bytes, U_BYTES,
+ input_blocksize, ibuf);
if (seek_record != 0)
{
@@ -1039,12 +1012,13 @@ dd_copy (void)
0+0 records out
*/
- skip (STDOUT_FILENO, output_file, seek_record, output_blocksize,
- obuf);
+ skip (STDOUT_FILENO, output_file, seek_record, U_BLOCKS,
+ output_blocksize, obuf);
}
if (seek_bytes != 0)
- bskip (STDOUT_FILENO, output_file, seek_bytes, output_blocksize, obuf);
+ skip (STDOUT_FILENO, output_file, seek_bytes, U_BYTES,
+ output_blocksize, obuf);
if (max_records == 0)
quit (exit_status);