summaryrefslogtreecommitdiffstats
path: root/bin/dd
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1997-10-11 20:09:05 +0000
committerjoerg <joerg@FreeBSD.org>1997-10-11 20:09:05 +0000
commit4841b45bbe197e54bb7732317930e8591d51362c (patch)
tree2bbaeb532cca6a0c260f5fc674f9d1d0ce9b10cb /bin/dd
parent11466e2a6f0898af142d8fbff4ead6b7078c6e04 (diff)
downloadFreeBSD-src-4841b45bbe197e54bb7732317930e8591d51362c.zip
FreeBSD-src-4841b45bbe197e54bb7732317930e8591d51362c.tar.gz
Teach dd(1) about an option to write sparse files. Can be useful for
things like diskless clients' swap files etc. Submitted by: pascal@zuo.dec.com (Pascal Pederiva) (ages ago, with many stylistic changes by me)
Diffstat (limited to 'bin/dd')
-rw-r--r--bin/dd/args.c3
-rw-r--r--bin/dd/dd.19
-rw-r--r--bin/dd/dd.c37
-rw-r--r--bin/dd/dd.h3
4 files changed, 45 insertions, 7 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c
index c5a14f7..f1e556a 100644
--- a/bin/dd/args.c
+++ b/bin/dd/args.c
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: args.c,v 1.8 1997/02/22 14:02:41 peter Exp $
+ * $Id: args.c,v 1.9 1997/10/08 12:10:33 eivind Exp $
*/
#ifndef lint
@@ -283,6 +283,7 @@ static struct conv {
{ "oldascii", C_ASCII, C_EBCDIC, e2a_32V },
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
+ { "sparse", C_SPARSE, 0, NULL },
{ "osync", C_OSYNC, C_BS, NULL },
{ "swab", C_SWAB, 0, NULL },
{ "sync", C_SYNC, 0, NULL },
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
index 157e52e..85aca7b 100644
--- a/bin/dd/dd.1
+++ b/bin/dd/dd.1
@@ -33,7 +33,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
-.\" $Id: dd.1,v 1.4 1997/02/22 14:02:43 peter Exp $
+.\" $Id: dd.1,v 1.5 1997/04/28 04:07:29 steve Exp $
.\"
.Dd January 13, 1994
.Dt DD 1
@@ -250,6 +250,13 @@ regularly sized blocks to be written.
This option is incompatible with use of the
.Cm bs= Ns Ar n
block size specification.
+.It Cm sparse
+If one or more output blocks would consist solely of
+.Tn NUL
+bytes, try to seek the output file by the required space instead of
+filling them with
+.Tn NULs ,
+resulting in a sparse file.
.It Cm swab
Swap every pair of input bytes.
If an input buffer has an odd number of bytes, the last byte will be
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index 60d7e67..bf14e16 100644
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: dd.c,v 1.10 1997/02/22 14:02:44 peter Exp $
+ * $Id: dd.c,v 1.11 1997/08/19 19:46:18 jlemon Exp $
*/
#ifndef lint
@@ -75,6 +75,7 @@ IO in, out; /* input/output state */
STAT st; /* statistics */
void (*cfunc) __P((void)); /* conversion function */
u_long cpy_cnt; /* # of blocks to copy */
+u_long pending = 0; /* pending seek if sparse */
u_int ddflags; /* conversion options */
u_int cbsz; /* conversion block size */
u_int files_cnt = 1; /* # of files to copy */
@@ -347,7 +348,7 @@ dd_close()
memset(out.dbp, 0, out.dbsz - out.dbcnt);
out.dbcnt = out.dbsz;
}
- if (out.dbcnt)
+ if (out.dbcnt || pending)
dd_out(1);
}
@@ -356,7 +357,7 @@ dd_out(force)
int force;
{
static int warned;
- int cnt, n, nw;
+ int cnt, n, nw, i, sparse;
u_char *outp;
/*
@@ -378,7 +379,35 @@ dd_out(force)
outp = out.db;
for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
for (cnt = n;; cnt -= nw) {
- nw = write(out.fd, outp, cnt);
+ sparse = 0;
+ if (ddflags & C_SPARSE) {
+ sparse = 1; /* Is buffer sparse? */
+ for (i = 0; i < cnt; i++)
+ if (outp[i] != 0) {
+ sparse = 0;
+ break;
+ }
+ }
+ if (sparse && !force) {
+ pending += cnt;
+ nw = cnt;
+ } else {
+ if (pending != 0) {
+ if (force)
+ pending--;
+ if (lseek (out.fd, pending, SEEK_CUR) == -1)
+ err(2, "%s: seek error creating sparse file",
+ out.name);
+ if (force)
+ write(out.fd, outp, 1);
+ pending = 0;
+ }
+ if (cnt)
+ nw = write(out.fd, outp, cnt);
+ else
+ return;
+ }
+
if (nw <= 0) {
if (nw == 0)
errx(1, "%s: end of device", out.name);
diff --git a/bin/dd/dd.h b/bin/dd/dd.h
index 30904d9..477f444 100644
--- a/bin/dd/dd.h
+++ b/bin/dd/dd.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)dd.h 8.3 (Berkeley) 4/2/94
- * $Id$
+ * $Id: dd.h,v 1.6 1997/02/22 14:02:45 peter Exp $
*/
/* Input/output stream state. */
@@ -95,3 +95,4 @@ typedef struct {
#define C_UCASE 0x40000
#define C_UNBLOCK 0x80000
#define C_OSYNC 0x100000
+#define C_SPARSE 0x200000
OpenPOWER on IntegriCloud