On Thursday 17 July 2008 15:17:48 you wrote:
> I'm not sure I like the conv=fullblk syntax though.
> Here are alternatives in my order of preference:

> iflag=block
There has been already conv=block parameter, so I think this similarity may 
confuse user.

> conv=fill
Ok, let the parameter be conv=fill -- new patch in attachment.

Kamil
From 150811acaac2ff4e9ae55f045ecc0e2c03bdc651 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <[EMAIL PROTECTED]>
Date: Thu, 17 Jul 2008 15:31:54 +0200
Subject: [PATCH] Added support for reading of full blocks to dd.

NEWS: mentioned new parameter conv=fill of dd
doc/coretuils.texi: mentioned new parameter conv=fill of dd
src/dd.c(iread_fill): warapper around iread for reading full blocks
src/dd.c(scanargs): check for parameter conv=fill
src/dd.c(skip): using iread_fnc pointer instead of iread function
src/dd.c(dd_copy): using iread_fnc pointer instead of iread function
---
 NEWS               |    4 ++++
 doc/coreutils.texi |    5 +++++
 src/dd.c           |   34 +++++++++++++++++++++++++++++++---
 3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index d6ed89e..3c42e6b 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   represents the maximum number of inputs that will be merged at once.
   When processing more than NMERGE inputs, sort uses temporary files.
 
+  dd accepts a new parameter conv=fill which turn on reading of full blocks
+  where possible. If this parameter is used and 'read' call is terminated
+  during read, it will be called again for remainder input.
+
 ** Bug fixes
 
   chcon --verbose now prints a newline after each message
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 44df6b3..9510df9 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -7615,6 +7615,11 @@ write of output data.
 Synchronize output data and metadata just before finishing.  This
 forces a physical write of output data and metadata.
 
[EMAIL PROTECTED] fill
[EMAIL PROTECTED] fill
+Read full blocks from input if possible. If 'read' call is terminated
+during read of input block, it will be called again for the remainder input.
+
 @end table
 
 @item [EMAIL PROTECTED],@[EMAIL PROTECTED]
diff --git a/src/dd.c b/src/dd.c
index ead9574..11e2432 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -119,7 +119,8 @@ enum
     C_NOCREAT = 010000,
     C_EXCL = 020000,
     C_FDATASYNC = 040000,
-    C_FSYNC = 0100000
+    C_FSYNC = 0100000,
+    C_FILL = 0200000
   };
 
 /* Status bit masks.  */
@@ -225,6 +226,9 @@ static sig_atomic_t volatile interrupt_signal;
 /* A count of the number of pending info signals that have been received.  */
 static sig_atomic_t volatile info_signal_count;
 
+/* Function used for read (to handle conv=fullbulk parameter) */
+static ssize_t (*iread_fnc) (int fd, char *buf, size_t size);
+
 /* A longest symbol in the struct symbol_values tables below.  */
 #define LONGEST_SYMBOL "fdatasync"
 
@@ -253,6 +257,7 @@ static struct symbol_value const conversions[] =
   {"sync", C_SYNC},		/* Pad input records to ibs with NULs. */
   {"fdatasync", C_FDATASYNC},	/* Synchronize output data before finishing.  */
   {"fsync", C_FSYNC},		/* Also synchronize output metadata.  */
+  {"fill", C_FILL}, /* Read only full blocks from input */
   {"", 0}
 };
 
@@ -762,6 +767,25 @@ iread (int fd, char *buf, size_t size)
     }
 }
 
+/* Wrapper around iread function which reads full blocks if possible */
+static ssize_t
+iread_fill (int fd, char *buf, size_t size)
+{
+  ssize_t nread = 0;
+
+  while (0 < size)
+    {
+      ssize_t ncurr = iread(fd, buf, size);
+      if (ncurr <= 0)
+  return ncurr;
+      nread += ncurr;
+      buf   += ncurr;
+      size  -= ncurr;
+    }
+
+  return nread;
+}
+
 /* Write to FD the buffer BUF of size SIZE, processing any signals
    that arrive.  Return the number of bytes written, setting errno if
    this is less than SIZE.  Keep trying if there are partial
@@ -1000,6 +1024,10 @@ scanargs (int argc, char *const *argv)
   if (input_flags & (O_DSYNC | O_SYNC))
     input_flags |= O_RSYNC;
 
+  iread_fnc = (conversions_mask &= C_FILL)?
+    iread_fill:
+    iread;
+
   if (multiple_bits_set (conversions_mask & (C_ASCII | C_EBCDIC | C_IBM)))
     error (EXIT_FAILURE, 0, _("cannot combine any two of {ascii,ebcdic,ibm}"));
   if (multiple_bits_set (conversions_mask & (C_BLOCK | C_UNBLOCK)))
@@ -1197,7 +1225,7 @@ skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
 
       do
 	{
-	  ssize_t nread = iread (fdesc, buf, blocksize);
+	  ssize_t nread = iread_fnc (fdesc, buf, blocksize);
 	  if (nread < 0)
 	    {
 	      if (fdesc == STDIN_FILENO)
@@ -1508,7 +1536,7 @@ dd_copy (void)
 		(conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',
 		input_blocksize);
 
-      nread = iread (STDIN_FILENO, ibuf, input_blocksize);
+      nread = iread_fnc (STDIN_FILENO, ibuf, input_blocksize);
 
       if (nread == 0)
 	break;			/* EOF.  */
-- 
1.5.4.1

_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to