diff options
author | joerg <joerg@FreeBSD.org> | 1997-10-11 20:09:05 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1997-10-11 20:09:05 +0000 |
commit | 4841b45bbe197e54bb7732317930e8591d51362c (patch) | |
tree | 2bbaeb532cca6a0c260f5fc674f9d1d0ce9b10cb /bin/dd/dd.c | |
parent | 11466e2a6f0898af142d8fbff4ead6b7078c6e04 (diff) | |
download | FreeBSD-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/dd.c')
-rw-r--r-- | bin/dd/dd.c | 37 |
1 files changed, 33 insertions, 4 deletions
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); |