1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-08-12 20:09:14 +02:00

remove bskip

adapt skip to skip either by bytes or by blocks
This commit is contained in:
Jim Meyering
2000-11-25 08:54:58 +00:00
parent 7d57b34196
commit 019bdadfc9
+52 -78
View File
@@ -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;
}
}
}
if ((units == U_BYTES || o / blocksize == n)
&& !buggy_lseek_support (fdesc)
&& lseek (fdesc, o, SEEK_CUR) > 0)
return;
/* 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;
/* 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;
}
/* 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)
{
bytes += blocksize;
nread = safe_read (fdesc, buf, bytes);
if (nread < 0)
else
{
error (0, errno, "%s", file);
quit (1);
n -= blocksize;
}
}
else
{
--n;
}
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);