Even more dd(1) cleanups! Thanks to Bruce for staying on my case until
we're done (not yet!) :)
This commit is contained in:
parent
980bb531d7
commit
7599187e0d
@ -142,14 +142,14 @@ jcl(argv)
|
||||
* Ascii/ebcdic and cbs implies block/unblock.
|
||||
* Block/unblock requires cbs and vice-versa.
|
||||
*/
|
||||
if (ddflags & (C_BLOCK|C_UNBLOCK)) {
|
||||
if (ddflags & (C_BLOCK | C_UNBLOCK)) {
|
||||
if (!(ddflags & C_CBS))
|
||||
errx(1, "record operations require cbs");
|
||||
if (cbsz == 0)
|
||||
errx(1, "cbs cannot be zero");
|
||||
cfunc = ddflags & C_BLOCK ? block : unblock;
|
||||
} else if (ddflags & C_CBS) {
|
||||
if (ddflags & (C_ASCII|C_EBCDIC)) {
|
||||
if (ddflags & (C_ASCII | C_EBCDIC)) {
|
||||
if (ddflags & C_ASCII) {
|
||||
ddflags |= C_UNBLOCK;
|
||||
cfunc = unblock;
|
||||
@ -161,6 +161,7 @@ jcl(argv)
|
||||
errx(1, "cbs meaningless if not doing record operations");
|
||||
} else
|
||||
cfunc = def;
|
||||
|
||||
/*
|
||||
* Bail out if the calculation of a file offset would overflow.
|
||||
*/
|
||||
@ -206,7 +207,6 @@ f_count(arg)
|
||||
{
|
||||
|
||||
cpy_cnt = get_num(arg);
|
||||
|
||||
if (!cpy_cnt)
|
||||
terminate(0);
|
||||
}
|
||||
@ -217,6 +217,8 @@ f_files(arg)
|
||||
{
|
||||
|
||||
files_cnt = get_num(arg);
|
||||
if (files_cnt < 1)
|
||||
errx(1, "files must be between 1 and %qd", QUAD_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -228,8 +230,8 @@ f_ibs(arg)
|
||||
if (!(ddflags & C_BS)) {
|
||||
res = get_num(arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(1, "ibs must be between 1 and %d", INT_MAX);
|
||||
in.dbsz = (int)res;
|
||||
errx(1, "ibs must be between 1 and %d", SSIZE_MAX);
|
||||
in.dbsz = (size_t)res;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ block()
|
||||
const u_char *t;
|
||||
size_t cnt, maxlen;
|
||||
static int intrunc;
|
||||
int ch = -1;
|
||||
int ch;
|
||||
|
||||
/*
|
||||
* Record truncation can cross block boundaries. If currently in a
|
||||
|
29
bin/dd/dd.c
29
bin/dd/dd.c
@ -52,9 +52,7 @@ static const char rcsid[] =
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/mtio.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
@ -82,7 +80,7 @@ off_t pending = 0; /* pending seek if sparse */
|
||||
u_int ddflags; /* conversion options */
|
||||
size_t cbsz; /* conversion block size */
|
||||
quad_t files_cnt = 1; /* # of files to copy */
|
||||
const u_char *ctab; /* conversion table */
|
||||
const u_char *ctab; /* conversion table */
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -152,7 +150,7 @@ setup()
|
||||
* Allocate space for the input and output buffers. If not doing
|
||||
* record oriented I/O, only need a single buffer.
|
||||
*/
|
||||
if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
|
||||
if (!(ddflags & (C_BLOCK | C_UNBLOCK))) {
|
||||
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
|
||||
err(1, "input buffer");
|
||||
out.db = in.db;
|
||||
@ -180,8 +178,8 @@ setup()
|
||||
* table that does both at once. If just converting case, use the
|
||||
* built-in tables.
|
||||
*/
|
||||
if (ddflags & (C_LCASE|C_UCASE)) {
|
||||
if (ddflags & (C_ASCII|C_EBCDIC)) {
|
||||
if (ddflags & (C_LCASE | C_UCASE)) {
|
||||
if (ddflags & (C_ASCII | C_EBCDIC)) {
|
||||
if (ddflags & C_LCASE) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = tolower(ctab[cnt]);
|
||||
@ -227,7 +225,9 @@ getfdtype(io)
|
||||
if (S_ISCHR(sb.st_mode) && (type & D_TAPE) == 0)
|
||||
io->flags |= ISCHR;
|
||||
}
|
||||
} else if (!S_ISREG(sb.st_mode))
|
||||
} else if (lseek(io->fd, (off_t)0, SEEK_CUR) == 0)
|
||||
io->flags |= ISSEEK;
|
||||
else if (errno == ESPIPE)
|
||||
io->flags |= ISPIPE;
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ dd_in()
|
||||
* use spaces.
|
||||
*/
|
||||
if (ddflags & C_SYNC) {
|
||||
if (ddflags & (C_BLOCK|C_UNBLOCK))
|
||||
if (ddflags & (C_BLOCK | C_UNBLOCK))
|
||||
memset(in.dbp, ' ', in.dbsz);
|
||||
else
|
||||
memset(in.dbp, 0, in.dbsz);
|
||||
@ -269,12 +269,12 @@ dd_in()
|
||||
summary();
|
||||
|
||||
/*
|
||||
* If it's not a tape drive or a pipe, seek past the
|
||||
* If it's a seekable file descriptor, seek past the
|
||||
* error. If your OS doesn't do the right thing for
|
||||
* raw disks this section should be modified to re-read
|
||||
* in sector size chunks.
|
||||
*/
|
||||
if (!(in.flags & (ISPIPE|ISTAPE)) &&
|
||||
if (in.flags & ISSEEK &&
|
||||
lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
|
||||
warn("%s", in.name);
|
||||
|
||||
@ -327,7 +327,7 @@ dd_in()
|
||||
}
|
||||
|
||||
/*
|
||||
* Clea nup any remaining I/O and flush output. If necessary, the output file
|
||||
* Clean up any remaining I/O and flush output. If necessary, the output file
|
||||
* is truncated.
|
||||
*/
|
||||
static void
|
||||
@ -340,7 +340,7 @@ dd_close()
|
||||
else if (cfunc == unblock)
|
||||
unblock_close();
|
||||
if (ddflags & C_OSYNC && out.dbcnt && out.dbcnt < out.dbsz) {
|
||||
if (ddflags & (C_BLOCK|C_UNBLOCK))
|
||||
if (ddflags & (C_BLOCK | C_UNBLOCK))
|
||||
memset(out.dbp, ' ', out.dbsz - out.dbcnt);
|
||||
else
|
||||
memset(out.dbp, 0, out.dbsz - out.dbcnt);
|
||||
@ -428,13 +428,14 @@ dd_out(force)
|
||||
++st.out_part;
|
||||
if (nw == cnt)
|
||||
break;
|
||||
if (out.flags & ISTAPE)
|
||||
errx(1, "%s: short write on tape device",
|
||||
out.name);
|
||||
if (out.flags & ISCHR && !warned) {
|
||||
warned = 1;
|
||||
warnx("%s: short write on character device",
|
||||
out.name);
|
||||
}
|
||||
if (out.flags & ISTAPE)
|
||||
errx(1, "%s: short write on tape device", out.name);
|
||||
}
|
||||
if ((out.dbcnt -= n) < out.dbsz)
|
||||
break;
|
||||
|
25
bin/dd/dd.h
25
bin/dd/dd.h
@ -40,22 +40,23 @@
|
||||
|
||||
/* Input/output stream state. */
|
||||
typedef struct {
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
size_t dbcnt; /* current buffer byte count */
|
||||
size_t dbrcnt; /* last read byte count */
|
||||
size_t dbsz; /* buffer size */
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
/* XXX ssize_t? */
|
||||
size_t dbcnt; /* current buffer byte count */
|
||||
size_t dbrcnt; /* last read byte count */
|
||||
size_t dbsz; /* buffer size */
|
||||
|
||||
#define ISCHR 0x01 /* character device (warn on short) */
|
||||
#define ISPIPE 0x02 /* pipe (not truncatable) */
|
||||
#define ISTAPE 0x04 /* tape (not seekable) */
|
||||
#define ISPIPE 0x02 /* pipe-like (not truncatable) */
|
||||
#define ISTAPE 0x04 /* tape */
|
||||
#define ISSEEK 0x08 /* valid to seek on */
|
||||
#define NOREAD 0x10 /* not readable */
|
||||
u_int flags;
|
||||
u_int flags;
|
||||
|
||||
char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
off_t offset; /* # of blocks to skip */
|
||||
char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
off_t offset; /* # of blocks to skip */
|
||||
|
||||
u_quad_t f_stats; /* # of full blocks processed */
|
||||
u_quad_t p_stats; /* # of partial blocks processed */
|
||||
@ -71,7 +72,7 @@ typedef struct {
|
||||
u_quad_t trunc; /* # of truncated records */
|
||||
u_quad_t swab; /* # of odd-length swab blocks */
|
||||
u_quad_t bytes; /* # of bytes written */
|
||||
double start; /* start time of dd */
|
||||
double start; /* start time of dd */
|
||||
} STAT;
|
||||
|
||||
/* Flags (in ddflags). */
|
||||
|
@ -64,5 +64,5 @@ extern quad_t files_cnt;
|
||||
extern const u_char *ctab;
|
||||
extern const u_char a2e_32V[], a2e_POSIX[];
|
||||
extern const u_char e2a_32V[], e2a_POSIX[];
|
||||
static const u_char a2ibm_32V[], a2ibm_POSIX[];
|
||||
extern const u_char a2ibm_32V[], a2ibm_POSIX[];
|
||||
extern u_char casetab[];
|
||||
|
@ -67,8 +67,8 @@ pos_in()
|
||||
ssize_t nr;
|
||||
size_t bcnt;
|
||||
|
||||
/* If not a character, pipe or tape device, try to seek on it. */
|
||||
if (!(in.flags & (ISCHR|ISPIPE|ISTAPE)) || in.flags & ISSEEK) {
|
||||
/* If known to be seekable, try to seek on it. */
|
||||
if (in.flags & ISSEEK) {
|
||||
errno = 0;
|
||||
if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 &&
|
||||
errno != 0)
|
||||
@ -125,8 +125,12 @@ pos_out()
|
||||
off_t cnt;
|
||||
ssize_t n;
|
||||
|
||||
/* If not a character, pipe or tape device, try to seek on it. */
|
||||
if (!(out.flags & (ISCHR|ISPIPE|ISTAPE)) || out.flags & ISSEEK) {
|
||||
/*
|
||||
* If not a tape, try seeking on the file. Seeking on a pipe is
|
||||
* going to fail, but don't protect the user -- they shouldn't
|
||||
* have specified the seek operand.
|
||||
*/
|
||||
if (!(out.flags & ISTAPE)) {
|
||||
errno = 0;
|
||||
if (lseek(out.fd, out.offset * out.dbsz, SEEK_SET) == -1 &&
|
||||
errno != 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user