summaryrefslogtreecommitdiffstats
path: root/bin/dd
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>1999-09-13 21:47:10 +0000
committergreen <green@FreeBSD.org>1999-09-13 21:47:10 +0000
commit996b2b913e8dd8f5ecb4b791313fc73854fe47f9 (patch)
tree5a6e0a8cdbccc055d27764c695287ded89d56c6a /bin/dd
parent167f52768b0c86277d20f1b46457a6859e342221 (diff)
downloadFreeBSD-src-996b2b913e8dd8f5ecb4b791313fc73854fe47f9.zip
FreeBSD-src-996b2b913e8dd8f5ecb4b791313fc73854fe47f9.tar.gz
Even more dd(1) cleanups! Thanks to Bruce for staying on my case until
we're done (not yet!) :)
Diffstat (limited to 'bin/dd')
-rw-r--r--bin/dd/args.c12
-rw-r--r--bin/dd/conv.c2
-rw-r--r--bin/dd/dd.c29
-rw-r--r--bin/dd/dd.h25
-rw-r--r--bin/dd/extern.h2
-rw-r--r--bin/dd/position.c12
6 files changed, 45 insertions, 37 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c
index 606da90..48b2063 100644
--- a/bin/dd/args.c
+++ b/bin/dd/args.c
@@ -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;
}
}
diff --git a/bin/dd/conv.c b/bin/dd/conv.c
index 57741aa..0987a67 100644
--- a/bin/dd/conv.c
+++ b/bin/dd/conv.c
@@ -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
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index ebfa792..da70ca7 100644
--- a/bin/dd/dd.c
+++ b/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;
diff --git a/bin/dd/dd.h b/bin/dd/dd.h
index 4e2419b..ae27a0e 100644
--- a/bin/dd/dd.h
+++ b/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). */
diff --git a/bin/dd/extern.h b/bin/dd/extern.h
index c588b76..e5c982c 100644
--- a/bin/dd/extern.h
+++ b/bin/dd/extern.h
@@ -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[];
diff --git a/bin/dd/position.c b/bin/dd/position.c
index 09b69a8..e6774a5 100644
--- a/bin/dd/position.c
+++ b/bin/dd/position.c
@@ -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)
OpenPOWER on IntegriCloud