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)
This commit is contained in:
Joerg Wunsch 1997-10-11 20:09:05 +00:00
parent 964a4c2866
commit 4ddfeabd8f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=30312
4 changed files with 45 additions and 7 deletions

View File

@ -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 },

View File

@ -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

View File

@ -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);

View File

@ -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