summaryrefslogtreecommitdiffstats
path: root/bin/dd/dd.c
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/dd.c
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/dd.c')
-rw-r--r--bin/dd/dd.c37
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);
OpenPOWER on IntegriCloud