Index: bin/dd/args.c =================================================================== --- bin/dd/args.c +++ bin/dd/args.c @@ -315,6 +315,7 @@ { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, { "block", C_BLOCK, C_UNBLOCK, NULL }, { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, + { "erase", C_ERASE, 0, NULL }, { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, { "lcase", C_LCASE, C_UCASE, NULL }, { "noerror", C_NOERROR, 0, NULL }, Index: bin/dd/dd.h =================================================================== --- bin/dd/dd.h +++ bin/dd/dd.h @@ -101,5 +101,6 @@ #define C_STATUS 0x08000000 #define C_NOXFER 0x10000000 #define C_NOINFO 0x20000000 +#define C_ERASE 0x40000000 #define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET) Index: bin/dd/dd.1 =================================================================== --- bin/dd/dd.1 +++ bin/dd/dd.1 @@ -306,6 +306,14 @@ filling them with .Dv NUL Ns s , resulting in a sparse file. +.It Cm erase +If one or more output blocks would consist solely of +.Dv NUL +bytes, erase corresponding block(s) of the output media by issuing +approprite +.Xr ioctl 2 +instead of filling them with +.Dv NUL Ns s . .It Cm swab Swap every pair of input bytes. If an input buffer has an odd number of bytes, the last byte will be Index: bin/dd/dd.c =================================================================== --- bin/dd/dd.c +++ bin/dd/dd.c @@ -471,6 +471,25 @@ } } +static ssize_t +dsk_erase(int d_fd, size_t size) +{ + off_t ioarg[2], npos; + int eval; + + ioarg[0] = lseek(d_fd, (off_t)0, SEEK_CUR); + if (ioarg[0] < 0) + return (ioarg[0]); + ioarg[1] = size; + eval = ioctl(d_fd, DIOCGDELETE, ioarg); + if (eval != 0) + return (-1); + npos = lseek(d_fd, size, SEEK_CUR); + if (npos < 0) + return (npos); + return (npos - ioarg[0]); +} + void dd_out(int force) { @@ -507,7 +526,7 @@ cnt = n; do { sparse = 0; - if (ddflags & C_SPARSE) { + if (ddflags & (C_SPARSE | C_ERASE)) { sparse = 1; /* Is buffer sparse? */ for (i = 0; i < cnt; i++) if (outp[i] != 0) { @@ -515,7 +534,7 @@ break; } } - if (sparse && !force) { + if (sparse && !force && !(ddflags & C_ERASE)) { pending += cnt; if ((out.flags & ISFIXSIZE) && (pending > out.mediasize)) { nw = 0; @@ -537,8 +556,11 @@ pending = 0; } if (cnt) { - nw = write(out.fd, outp, cnt); - out.seek_offset = 0; + if (!(ddflags & C_ERASE) || sparse == 0) { + nw = write(out.fd, outp, cnt); + } else { + nw = dsk_erase(out.fd, cnt); + } } else { return; }