(skip): Assume lseek failed if it returned zero, since a zero return is
authorJim Meyering <jim@meyering.net>
Thu, 24 Aug 2000 08:34:33 +0000 (08:34 +0000)
committerJim Meyering <jim@meyering.net>
Thu, 24 Aug 2000 08:34:33 +0000 (08:34 +0000)
impossible and some buggy drivers return zero.

Use SEEK_CUR rather than SEEK_SET; this fixes a bug when the
file descriptor is not currently rewound.

src/dd.c

index 2a89b6b..9291a1a 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -720,7 +720,8 @@ swab_buffer (unsigned char *buf, size_t *nread)
 
 /* 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. */
+   bytes of the data at a time in BUF, if necessary.  RECORDS must be
+   nonzero.  */
 
 static void
 skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
@@ -729,10 +730,12 @@ skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
   off_t o;
 
   /* Try lseek and if an error indicates it was an inappropriate
-     operation, fall back on using read.  */
+     operation, fall back on using read.  Some broken versions of
+     lseek 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
-      || lseek (fdesc, o, SEEK_SET) == -1)
+      || lseek (fdesc, o, SEEK_CUR) <= 0)
     {
       while (records-- > 0)
        {