Pádraig Brady wrote:
> There are actually 3 cases to consider with large skip values.
> Currently dd does the following for various values of skip:
> 
>     if skip > file_size && skip < max_file_size
>       lseek returns new offset, and read() returns 0
> 
>     if skip > file_size && skip > max file size
>       lseek returns error and read() used to advance input
> 
>     if skip would overflow off_t
>       read() used to advance input

4 cases actually:

     if skip > device_size
       read() used to advance input

Hopefully the attached patch makes dd more efficient/correct
in these cases. It passes the tests at least.

cheers,
Pádraig.
>From ccac25668b04d1c62f93dcec5419adb564db3ddd Mon Sep 17 00:00:00 2001
From: =?utf-8?q?P=C3=A1draig=20Brady?= <[EMAIL PROTECTED]>
Date: Fri, 18 Apr 2008 21:15:59 +0100
Subject: [PATCH] Stop dd doing redundant reading with erroneous skip offsets

* src/dd.c: Try to seek to the end of the file to stop
redundant reads when for example skip > max_file_size,
offset > dev_size, offset > OFF_T_MAX

Signed-off-by: Pádraig Brady <[EMAIL PROTECTED]>
---
 src/dd.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/dd.c b/src/dd.c
index 0a7b154..711bab7 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1178,6 +1178,7 @@ skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
       char *buf)
 {
   uintmax_t offset = records * blocksize;
+  off_t soffset;
 
   /* Try lseek and if an error indicates it was an inappropriate operation --
      or if the file offset is not representable as an off_t --
@@ -1194,6 +1195,17 @@ skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
   else
     {
       int lseek_errno = errno;
+      if (fdesc == STDIN_FILENO && input_seekable)
+	{
+	  /* We probably were asked to skip past the end of device.
+	   * Therefore try to seek to the end of the file,
+	   * so that subsequent reads will return immediately.  */
+	  if ((soffset = lseek (fdesc, 0, SEEK_END)) >= 0)
+	    {
+	      advance_input_offset (soffset);
+	      return 0;
+	    }
+	}
 
       do
 	{
-- 
1.5.3.6

_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to