Rob Sullivan cleaned up the longstanding patch from Hideki IWAMOTO to add
authorRob Landley <rob@landley.net>
Tue, 16 May 2006 16:52:12 +0000 (16:52 -0000)
committerRob Landley <rob@landley.net>
Tue, 16 May 2006 16:52:12 +0000 (16:52 -0000)
ibs and obs support to dd, and made it configurable.  I cleaned it up a bit
further and moved conv= into the same config option.

coreutils/Config.in
coreutils/dd.c
include/usage.h
patches/dd_ibs_and_obs.diff [deleted file]

index d0ac000d39f9bdcb406a6f02a3c63cdbbde9263f..d7e31e868a9ba4c90851b2d5f6f9753ae0281bb2 100644 (file)
@@ -127,6 +127,14 @@ config CONFIG_FEATURE_DD_SIGNAL_HANDLING
          $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid 
          10899206+0 records in 10899206+0 records out
 
+config CONFIG_FEATURE_DD_IBS_OBS
+       bool "Enable ibs, obs and conv options"
+       default n
+       depends on CONFIG_DD
+       help
+         Enables support for writing a certain number of bytes in and out,
+         at a time, and performing conversions on the data stream.
+
 config CONFIG_DF
        bool "df"
        default n
index 378e212dedcd3d863e22f1fb21ca35fc1fcfa0a0..53aa085ed79f041bfc5d2e445ad72fd7282eb34b 100644 (file)
@@ -45,21 +45,13 @@ static void dd_output_status(int cur_signal)
 
 int dd_main(int argc, char **argv)
 {
-       size_t count = -1;
-       size_t bs = 512;
+       size_t count = -1, oc = 0, ibs = 512, obs = 512;
        ssize_t n;
-       off_t seek = 0;
-       off_t skip = 0;
-       int sync_flag = FALSE;
-       int noerror = FALSE;
-       int trunc_flag = TRUE;
-       int oflag;
-       int ifd;
-       int ofd;
-       int i;
-       const char *infile = NULL;
-       const char *outfile = NULL;
-       char *buf;
+       off_t seek = 0, skip = 0;
+       int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0,
+               oflag, ifd, ofd, i;
+       const char *infile = NULL, *outfile = NULL;
+       char *ibuf, *obuf;
 
        if (ENABLE_FEATURE_DD_SIGNAL_HANDLING)
        {
@@ -73,43 +65,49 @@ int dd_main(int argc, char **argv)
        }
 
        for (i = 1; i < argc; i++) {
-               if (strncmp("bs=", argv[i], 3) == 0)
-                       bs = bb_xparse_number(argv[i]+3, dd_suffixes);
-               else if (strncmp("count=", argv[i], 6) == 0)
+               if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) {
+                       ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
+                       twobufs_flag++;
+               } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) {
+                       obs = bb_xparse_number(argv[i]+4, dd_suffixes);
+                       twobufs_flag++;
+               } else if (!strncmp("bs=", argv[i], 3)) {
+                       ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
+               } else if (!strncmp("count=", argv[i], 6))
                        count = bb_xparse_number(argv[i]+6, dd_suffixes);
-               else if (strncmp("seek=", argv[i], 5) == 0)
+               else if (!strncmp("seek=", argv[i], 5))
                        seek = bb_xparse_number(argv[i]+5, dd_suffixes);
-               else if (strncmp("skip=", argv[i], 5) == 0)
+               else if (!strncmp("skip=", argv[i], 5))
                        skip = bb_xparse_number(argv[i]+5, dd_suffixes);
-               else if (strncmp("if=", argv[i], 3) == 0)
+               else if (!strncmp("if=", argv[i], 3))
                        infile = argv[i]+3;
-               else if (strncmp("of=", argv[i], 3) == 0)
+               else if (!strncmp("of=", argv[i], 3))
                        outfile = argv[i]+3;
-               else if (strncmp("conv=", argv[i], 5) == 0) {
-                       buf = argv[i]+5;
+               else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) {
+                       ibuf = argv[i]+5;
                        while (1) {
-                               if (strncmp("notrunc", buf, 7) == 0) {
+                               if (!strncmp("notrunc", ibuf, 7)) {
                                        trunc_flag = FALSE;
-                                       buf += 7;
-                               } else if (strncmp("sync", buf, 4) == 0) {
+                                       ibuf += 7;
+                               } else if (!strncmp("sync", ibuf, 4)) {
                                        sync_flag = TRUE;
-                                       buf += 4;
-                               } else if (strncmp("noerror", buf, 7) == 0) {
+                                       ibuf += 4;
+                               } else if (!strncmp("noerror", ibuf, 7)) {
                                        noerror = TRUE;
-                                       buf += 7;
+                                       ibuf += 7;
                                } else {
                                        bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5);
                                }
-                               if (buf[0] == '\0')
-                                       break;
-                               if (buf[0] == ',')
-                                       buf++;
+                               if (ibuf[0] == '\0') break;
+                               if (ibuf[0] == ',') ibuf++;
                        }
                } else
                        bb_show_usage();
        }
+       ibuf = xmalloc(ibs);
 
-       buf = xmalloc(bs);
+       if (twobufs_flag) obuf = xmalloc(obs);
+       else obuf = ibuf;
 
        if (infile != NULL) {
                ifd = bb_xopen(infile, O_RDONLY);
@@ -128,7 +126,7 @@ int dd_main(int argc, char **argv)
                ofd = bb_xopen3(outfile, oflag, 0666);
 
                if (seek && trunc_flag) {
-                       if (ftruncate(ofd, seek * bs) < 0) {
+                       if (ftruncate(ofd, seek * obs) < 0) {
                                struct stat st;
 
                                if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
@@ -143,13 +141,19 @@ int dd_main(int argc, char **argv)
        }
 
        if (skip) {
-               if (lseek(ifd, skip * bs, SEEK_CUR) < 0) {
-                       bb_perror_msg_and_die("%s", infile);
+               if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
+                       while (skip-- > 0) {
+                               n = safe_read(ifd, ibuf, ibs);
+                               if (n < 0)
+                                       bb_perror_msg_and_die("%s", infile);
+                               if (n == 0)
+                                       break;
+                       }
                }
        }
 
        if (seek) {
-               if (lseek(ofd, seek * bs, SEEK_CUR) < 0) {
+               if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
                        bb_perror_msg_and_die("%s", outfile);
                }
        }
@@ -157,40 +161,63 @@ int dd_main(int argc, char **argv)
        while (in_full + in_part != count) {
                if (noerror) {
                        /* Pre-zero the buffer when doing the noerror thing */
-                       memset(buf, '\0', bs);
+                       memset(ibuf, '\0', ibs);
+               }
+
+               n = safe_read(ifd, ibuf, ibs);
+               if (n == 0) {
+                       break;
                }
-               n = safe_read(ifd, buf, bs);
                if (n < 0) {
                        if (noerror) {
-                               n = bs;
+                               n = ibs;
                                bb_perror_msg("%s", infile);
                        } else {
                                bb_perror_msg_and_die("%s", infile);
                        }
                }
-               if (n == 0) {
-                       break;
-               }
-               if ((size_t)n == bs) {
+               if ((size_t)n == ibs) {
                        in_full++;
                } else {
                        in_part++;
+                       if (sync_flag) {
+                               memset(ibuf + n, '\0', ibs - n);
+                               n = ibs;
+                       }
                }
-               if (sync_flag) {
-                       memset(buf + n, '\0', bs - n);
-                       n = bs;
+               if (twobufs_flag) {
+                       char *tmp = ibuf;
+                       while (n) {
+                               size_t d = obs - oc;
+
+                               if (d > n) d = n;
+                               memcpy(obuf + oc, tmp, d);
+                               n -= d;
+                               tmp += d;
+                               oc += d;
+                               if (oc == obs) {
+                                       if (bb_full_write(ofd, obuf, obs) < 0) {
+                                               bb_perror_msg_and_die("%s", outfile);
+                                       }
+                                       out_full++;
+                                       oc = 0;
+                               }
+                       }
+               } else {
+                       if ((n = bb_full_write(ofd, ibuf, n)) < 0) {
+                               bb_perror_msg_and_die("%s", outfile);
+                       }
+                       if (n == ibs) out_full++;
+                       else out_part++;
                }
-               n = bb_full_write(ofd, buf, n);
-               if (n < 0) {
+       }
+       
+       if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
+               if (bb_full_write(ofd, obuf, oc) < 0) {
                        bb_perror_msg_and_die("%s", outfile);
                }
-               if ((size_t)n == bs) {
-                       out_full++;
-               } else {
-                       out_part++;
-               }
+               out_part++;
        }
-
        if (close (ifd) < 0) {
                bb_perror_msg_and_die("%s", infile);
        }
index 0e3ecae054abb16a5b53649813143a383d080e29..9ec25c49fa12e0ca46bcf5dbde20436b1082ffef 100644 (file)
@@ -370,19 +370,23 @@ USE_FEATURE_DATE_ISOFMT( \
        "64\n"
 
 #define dd_trivial_usage \
-       "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \
-       "\t  [seek=N] [conv=notrunc|noerror|sync]"
+       "[if=FILE] [of=FILE] " USE_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \
+       "\t  [seek=N]" USE_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync]")
 #define dd_full_usage \
        "Copy a file, converting and formatting according to options\n\n" \
        "\tif=FILE\t\tread from FILE instead of stdin\n" \
        "\tof=FILE\t\twrite to FILE instead of stdout\n" \
        "\tbs=N\t\tread and write N bytes at a time\n" \
+       USE_FEATURE_DD_IBS_OBS("\tibs=N\t\tread N bytes at a time\n") \
+       USE_FEATURE_DD_IBS_OBS("\tobs=N\t\twrite N bytes at a time\n") \
        "\tcount=N\t\tcopy only N input blocks\n" \
        "\tskip=N\t\tskip N input blocks\n" \
        "\tseek=N\t\tskip N output blocks\n" \
-       "\tconv=notrunc\tdon't truncate output file\n" \
-       "\tconv=noerror\tcontinue after read errors\n" \
-       "\tconv=sync\tpad blocks with zeros\n" \
+       USE_FEATURE_DD_IBS_OBS( \
+               "\tconv=notrunc\tdon't truncate output file\n" \
+               "\tconv=noerror\tcontinue after read errors\n" \
+               "\tconv=sync\tpad blocks with zeros\n" \
+       ) \
        "\n" \
        "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \
        "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
diff --git a/patches/dd_ibs_and_obs.diff b/patches/dd_ibs_and_obs.diff
deleted file mode 100644 (file)
index 3bbf4b9..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-This patch adds support of ibs= and obs= to dd.
-----
-Hideki IWAMOTO  h-iwamoto@kit.hi-ho.ne.jp
-
-
---- a/include/usage.h  29 Mar 2004 08:20:08 -0000      1.198
-+++ b/include/usage.h  4 Apr 2004 07:15:21 -0000
-@@ -309,13 +309,15 @@
-       "64\n"
- #define dd_trivial_usage \
--      "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \
--      "\t  [seek=N] [conv=notrunc|noerror|sync]"
-+      "[if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N]\n" \
-+      "\t  [skip=N] [seek=N] [conv=notrunc|noerror|sync]"
- #define dd_full_usage \
-       "Copy a file, converting and formatting according to options\n\n" \
-       "\tif=FILE\t\tread from FILE instead of stdin\n" \
-       "\tof=FILE\t\twrite to FILE instead of stdout\n" \
--      "\tbs=N\t\tread and write N bytes at a time\n" \
-+      "\tibs=N\t\tread N bytes at a time\n" \
-+      "\tobs=N\t\twrite N bytes at a time\n" \
-+      "\tbs=N\t\tforce ibs=N and obs=N\n" \
-       "\tcount=N\t\tcopy only N input blocks\n" \
-       "\tskip=N\t\tskip N input blocks\n" \
-       "\tseek=N\t\tskip N output blocks\n" \
-@@ -323,6 +325,8 @@
-       "\tconv=noerror\tcontinue after read errors\n" \
-       "\tconv=sync\tpad blocks with zeros\n" \
-       "\n" \
-+      "If the bs= expr operand is not specified, the input is processed and collected\n" \
-+      "into full-sized output blocks until the end of the input is reached.\n" \
-       "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \
-       "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)."
- #define dd_example_usage \
---- a/coreutils/dd.c   30 Jan 2004 22:24:32 -0000      1.55
-+++ b/coreutils/dd.c   4 Apr 2004 07:15:21 -0000
-@@ -30,6 +30,10 @@
- #include <fcntl.h>
- #include "busybox.h"
-+#define C_NOERROR     0x0001
-+#define C_TRUNC               0x0002
-+#define C_SYNC                0x0004
-+#define C_TWOBUFS     0x0008
- static const struct suffix_mult dd_suffixes[] = {
-       { "c", 1 },
-@@ -51,13 +55,13 @@
-       size_t in_full = 0;
-       size_t in_part = 0;
-       size_t count = -1;
--      size_t bs = 512;
-+      size_t ibs = 512;
-+      size_t obs = 512;
-+      size_t oc = 0;
-       ssize_t n;
-       off_t seek = 0;
-       off_t skip = 0;
--      int sync_flag = FALSE;
--      int noerror = FALSE;
--      int trunc_flag = TRUE;
-+      unsigned int dd_flags = C_TWOBUFS | C_TRUNC;
-       int oflag;
-       int ifd;
-       int ofd;
-@@ -65,11 +69,18 @@
-       const char *infile = NULL;
-       const char *outfile = NULL;
-       char *buf;
-+      char *ibuf;
-+      char *obuf;
-       for (i = 1; i < argc; i++) {
--              if (strncmp("bs=", argv[i], 3) == 0)
--                      bs = bb_xparse_number(argv[i]+3, dd_suffixes);
--              else if (strncmp("count=", argv[i], 6) == 0)
-+              if (strncmp("ibs=", argv[i], 4) == 0)
-+                      ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
-+              else if (strncmp("obs=", argv[i], 4) == 0)
-+                      obs = bb_xparse_number(argv[i]+4, dd_suffixes);
-+              else if (strncmp("bs=", argv[i], 3) == 0) {
-+                      ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
-+                      dd_flags &= ~C_TWOBUFS;
-+              } else if (strncmp("count=", argv[i], 6) == 0)
-                       count = bb_xparse_number(argv[i]+6, dd_suffixes);
-               else if (strncmp("seek=", argv[i], 5) == 0)
-                       seek = bb_xparse_number(argv[i]+5, dd_suffixes);
-@@ -83,13 +94,13 @@
-                       buf = argv[i]+5;
-                       while (1) {
-                               if (strncmp("notrunc", buf, 7) == 0) {
--                                      trunc_flag = FALSE;
-+                                      dd_flags &= ~C_TRUNC;
-                                       buf += 7;
-                               } else if (strncmp("sync", buf, 4) == 0) {
--                                      sync_flag = TRUE;
-+                                      dd_flags |= C_SYNC;
-                                       buf += 4;
-                               } else if (strncmp("noerror", buf, 7) == 0) {
--                                      noerror = TRUE;
-+                                      dd_flags |= C_NOERROR;
-                                       buf += 7;
-                               } else {
-                                       bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5);
-@@ -103,7 +114,12 @@
-                       bb_show_usage();
-       }
--      buf = xmalloc(bs);
-+      ibuf = xmalloc(ibs);
-+
-+      if (dd_flags & C_TWOBUFS)
-+              obuf = xmalloc(obs);
-+      else
-+              obuf = ibuf;
-       if (infile != NULL) {
-               ifd = bb_xopen(infile, O_RDONLY);
-@@ -115,7 +131,7 @@
-       if (outfile != NULL) {
-               oflag = O_WRONLY | O_CREAT;
--              if (!seek && trunc_flag) {
-+              if (!seek && (dd_flags & C_TRUNC)) {
-                       oflag |= O_TRUNC;
-               }
-@@ -123,8 +139,8 @@
-                       bb_perror_msg_and_die("%s", outfile);
-               }
--              if (seek && trunc_flag) {
--                      if (ftruncate(ofd, seek * bs) < 0) {
-+              if (seek && (dd_flags & C_TRUNC)) {
-+                      if (ftruncate(ofd, seek * obs) < 0) {
-                               struct stat st;
-                               if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
-@@ -139,52 +155,88 @@
-       }
-       if (skip) {
--              if (lseek(ifd, skip * bs, SEEK_CUR) < 0) {
--                      bb_perror_msg_and_die("%s", infile);
-+              if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
-+                      while (skip-- > 0) {
-+                              n = safe_read(ifd, ibuf, ibs);
-+                              if (n < 0)
-+                                      bb_perror_msg_and_die("%s", infile);
-+                              if (n == 0)
-+                                      break;
-+                      }
-               }
-       }
-       if (seek) {
--              if (lseek(ofd, seek * bs, SEEK_CUR) < 0) {
-+              if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
-                       bb_perror_msg_and_die("%s", outfile);
-               }
-       }
-       while (in_full + in_part != count) {
--              if (noerror) {
-+              if (dd_flags & C_NOERROR) {
-                       /* Pre-zero the buffer when doing the noerror thing */
--                      memset(buf, '\0', bs);
-+                      memset(ibuf, '\0', ibs);
-+              }
-+
-+              n = safe_read(ifd, ibuf, ibs);
-+              if (n == 0) {
-+                      break;
-               }
--              n = safe_read(ifd, buf, bs);
-               if (n < 0) {
--                      if (noerror) {
--                              n = bs;
-+                      if (dd_flags & C_NOERROR) {
-+                              n = ibs;
-                               bb_perror_msg("%s", infile);
-                       } else {
-                               bb_perror_msg_and_die("%s", infile);
-                       }
-               }
--              if (n == 0) {
--                      break;
--              }
--              if (n == bs) {
-+              if (n == ibs) {
-                       in_full++;
-               } else {
-                       in_part++;
-+                      if (dd_flags & C_SYNC) {
-+                              memset(ibuf + n, '\0', ibs - n);
-+                              n = ibs;
-+                      }
-               }
--              if (sync_flag) {
--                      memset(buf + n, '\0', bs - n);
--                      n = bs;
-+
-+              if (dd_flags & C_TWOBUFS) {
-+                      size_t d;
-+                      char *tmp = ibuf;
-+
-+                      while (n) {
-+                              d = obs - oc;
-+                              if (d > n)
-+                                      d = n;
-+                              memcpy(obuf + oc, tmp, d);
-+                              n -= d;
-+                              tmp += d;
-+                              oc += d;
-+                              if (oc == obs) {
-+                                      if (bb_full_write(ofd, obuf, obs) < 0) {
-+                                              bb_perror_msg_and_die("%s", outfile);
-+                                      }
-+                                      out_full++;
-+                                      oc = 0;
-+                              }
-+                      }
-+              } else {
-+                      if (bb_full_write(ofd, ibuf, n) < 0) {
-+                              bb_perror_msg_and_die("%s", outfile);
-+                      }
-+                      if (n == ibs) {
-+                              out_full++;
-+                      } else {
-+                              out_part++;
-+                      }
-               }
--              n = bb_full_write(ofd, buf, n);
--              if (n < 0) {
-+      }
-+
-+      if (oc) {
-+              if (bb_full_write(ofd, obuf, oc) < 0) {
-                       bb_perror_msg_and_die("%s", outfile);
-               }
--              if (n == bs) {
--                      out_full++;
--              } else {
--                      out_part++;
--              }
-+              out_part++;
-       }
-       if (close (ifd) < 0) {
-
-