Module Name: src
Committed By: martin
Date: Thu Mar 26 11:08:43 UTC 2015
Modified Files:
src/bin/dd [netbsd-7]: Makefile args.c dd.1 dd.c dd.h extern.h
Log Message:
Pull up following revision(s) (requested by manu in ticket #640):
bin/dd/extern.h: revision 1.23
bin/dd/dd.1: revision 1.26
bin/dd/dd.1: revision 1.27
bin/dd/dd.h: revision 1.16
bin/dd/dd.c: revision 1.50
bin/dd/Makefile: revision 1.18
bin/dd/args.c: revision 1.39
Add iflag and oflag operands to dd(1)
Like GNU dd(1) similar operands, iflag and oflag allow specifying the
O_* flags given to open(2) for the input and the output file. The values
are comma-sepratated, lower-case, O_ prefix-stripped constants documented
in open(2).
Since iflag and oflag override default values, specifying oflag means
O_CREATE is not set by default and must be specified explicitely.
Some values do not make sense (e.g.: iflag=directory) but are still used
and will raise a warning. For oflag, values rdonly, rdwr and wronly are
filtered out with a warning (dd(1) attempts open(2) with O_RDWR and
then O_WRONLY on failure).
Specifying oflag=trunc along with (seek, oseek or conv=notrunc) is
contradictory and will raise an error.
iflag and oflag are disabled if building with -DMALLPROG
New sentence, new line. Fix typos. Bump date for previous.
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.17.12.1 src/bin/dd/Makefile
cvs rdiff -u -r1.38 -r1.38.6.1 src/bin/dd/args.c
cvs rdiff -u -r1.25 -r1.25.12.1 src/bin/dd/dd.1
cvs rdiff -u -r1.49 -r1.49.12.1 src/bin/dd/dd.c
cvs rdiff -u -r1.15 -r1.15.24.1 src/bin/dd/dd.h
cvs rdiff -u -r1.22 -r1.22.20.1 src/bin/dd/extern.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/dd/Makefile
diff -u src/bin/dd/Makefile:1.17 src/bin/dd/Makefile:1.17.12.1
--- src/bin/dd/Makefile:1.17 Wed Aug 8 14:09:14 2012
+++ src/bin/dd/Makefile Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.17 2012/08/08 14:09:14 christos Exp $
+# $NetBSD: Makefile,v 1.17.12.1 2015/03/26 11:08:43 martin Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
.include <bsd.own.mk>
@@ -10,8 +10,9 @@ DPADD+= ${LIBUTIL}
LDADD+= -lutil
.ifdef SMALLPROG
-CPPFLAGS+= -DNO_CONV -DNO_MSGFMT -DSMALL
+CPPFLAGS+= -DNO_CONV -DNO_MSGFMT -DNO_IOFLAG -DSMALL
.else
+CPPFLAGS+= -D_NETBSD_SOURCE -D_INCOMPLETE_XOPEN_C063
SRCS+= conv_tab.c
.ifdef CRUNCHEDPROG
CPPFLAGS+= -DSMALL
Index: src/bin/dd/args.c
diff -u src/bin/dd/args.c:1.38 src/bin/dd/args.c:1.38.6.1
--- src/bin/dd/args.c:1.38 Wed Jul 17 12:55:48 2013
+++ src/bin/dd/args.c Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $ */
+/* $NetBSD: args.c,v 1.38.6.1 2015/03/26 11:08:43 martin Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -38,13 +38,16 @@
#if 0
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
#else
-__RCSID("$NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $");
+__RCSID("$NetBSD: args.c,v 1.38.6.1 2015/03/26 11:08:43 martin Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/time.h>
+#ifndef NO_IOFLAG
+#include <fcntl.h>
+#endif /* NO_IOFLAG */
#include <err.h>
#include <errno.h>
#include <limits.h>
@@ -70,6 +73,16 @@ static void f_conv(char *);
static int c_conv(const void *, const void *);
#endif /* NO_CONV */
+#ifdef NO_IOFLAG
+static void f_iflag(char *) __dead;
+static void f_oflag(char *) __dead;
+#else
+static void f_iflag(char *);
+static void f_oflag(char *);
+static u_int f_ioflag(char *, u_int);
+static int c_ioflag(const void *, const void *);
+#endif /* NO_IOFLAG */
+
static void f_bs(char *);
static void f_cbs(char *);
static void f_count(char *);
@@ -96,10 +109,12 @@ static const struct arg {
{ "files", f_files, C_FILES, C_FILES },
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
{ "if", f_if, C_IF, C_IF },
+ { "iflag", f_iflag, C_IFLAG, C_IFLAG },
{ "iseek", f_skip, C_SKIP, C_SKIP },
{ "msgfmt", f_msgfmt, 0, 0 },
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
{ "of", f_of, C_OF, C_OF },
+ { "oflag", f_oflag, C_OFLAG, C_OFLAG },
{ "oseek", f_seek, C_SEEK, C_SEEK },
{ "progress", f_progress, 0, 0 },
{ "seek", f_seek, C_SEEK, C_SEEK },
@@ -389,3 +404,102 @@ c_conv(const void *a, const void *b)
}
#endif /* NO_CONV */
+
+static void
+f_iflag(char *arg)
+{
+/* Build a small version (i.e. for a ramdisk root) */
+#ifdef NO_IOFLAG
+ errx(EXIT_FAILURE, "iflag option disabled");
+ /* NOTREACHED */
+#else
+ iflag = f_ioflag(arg, C_IFLAG);
+ return;
+#endif
+}
+
+static void
+f_oflag(char *arg)
+{
+/* Build a small version (i.e. for a ramdisk root) */
+#ifdef NO_IOFLAG
+ errx(EXIT_FAILURE, "oflag option disabled");
+ /* NOTREACHED */
+#else
+ oflag = f_ioflag(arg, C_OFLAG);
+ return;
+#endif
+}
+
+#ifndef NO_IOFLAG
+static const struct ioflag {
+ const char *name;
+ u_int set;
+ u_int allowed;
+} olist[] = {
+ /* the array needs to be sorted by the first column so
+ bsearch() can be used to find commands quickly */
+ { "alt_io", O_ALT_IO, C_IFLAG|C_OFLAG },
+ { "append", O_APPEND, C_OFLAG },
+ { "async", O_ASYNC, C_IFLAG|C_OFLAG },
+ { "cloexec", O_CLOEXEC, C_IFLAG|C_OFLAG },
+ { "creat", O_CREAT, C_OFLAG },
+ { "direct", O_DIRECT, C_IFLAG|C_OFLAG },
+ { "directory", O_DIRECTORY, C_NONE },
+ { "dsync", O_DSYNC, C_OFLAG },
+ { "excl", O_EXCL, C_IFLAG|C_OFLAG },
+ { "exlock", O_EXLOCK, C_IFLAG|C_OFLAG },
+ { "noctty", O_NOCTTY, C_IFLAG|C_OFLAG },
+ { "nofollow", O_NOFOLLOW, C_IFLAG|C_OFLAG },
+ { "nonblock", O_NONBLOCK, C_IFLAG|C_OFLAG },
+ { "nosigpipe", O_NOSIGPIPE, C_IFLAG|C_OFLAG },
+ { "rdonly", O_RDONLY, C_IFLAG },
+ { "rdwr", O_RDWR, C_IFLAG },
+ { "rsync", O_RSYNC, C_IFLAG },
+ { "search", O_SEARCH, C_IFLAG|C_OFLAG },
+ { "shlock", O_SHLOCK, C_IFLAG|C_OFLAG },
+ { "sync", O_SYNC, C_IFLAG|C_OFLAG },
+ { "trunc", O_TRUNC, C_IFLAG|C_OFLAG },
+ { "wronly", O_WRONLY, C_NONE },
+};
+
+static u_int
+f_ioflag(char *arg, u_int flagtype)
+{
+ u_int ioflag = 0;
+ struct ioflag *cp, tmp;
+ const char *flagstr = (flagtype == C_IFLAG) ? "iflag" : "oflag";
+
+ while (arg != NULL) {
+ tmp.name = strsep(&arg, ",");
+ if (!(cp = bsearch(&tmp, olist,
+ __arraycount(olist), sizeof(*olist), c_ioflag))) {
+ errx(EXIT_FAILURE, "unknown %s %s", flagstr, tmp.name);
+ /* NOTREACHED */
+ }
+
+ if ((cp->set & O_ACCMODE) && (flagtype == C_OFLAG)) {
+ warnx("rdonly, rdwr and wronly are ignored for oflag");
+ continue;
+ }
+
+ if ((cp->allowed & flagtype) == 0) {
+ warnx("%s set for %s but makes no sense",
+ cp->name, flagstr);
+ }
+
+ ioflag |= cp->set;
+ }
+
+
+ return ioflag;
+}
+
+static int
+c_ioflag(const void *a, const void *b)
+{
+
+ return (strcmp(((const struct ioflag *)a)->name,
+ ((const struct ioflag *)b)->name));
+}
+#endif /* NO_IOFLAG */
Index: src/bin/dd/dd.1
diff -u src/bin/dd/dd.1:1.25 src/bin/dd/dd.1:1.25.12.1
--- src/bin/dd/dd.1:1.25 Wed Jun 20 17:54:16 2012
+++ src/bin/dd/dd.1 Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: dd.1,v 1.25 2012/06/20 17:54:16 wiz Exp $
+.\" $NetBSD: dd.1,v 1.25.12.1 2015/03/26 11:08:43 martin Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -32,7 +32,7 @@
.\"
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\"
-.Dd November 6, 2011
+.Dd March 18, 2015
.Dt DD 1
.Os
.Sh NAME
@@ -91,6 +91,21 @@ bytes instead of the default 512.
Read input from
.Ar file
instead of the standard input.
+.It Cm iflag= Ns Ar flags
+Use comma-separated
+.Ar flags
+when calling
+.Xr open 2
+for the input file.
+The possible values are
+.Va O_
+flags documented in
+.Xr open 2 ,
+specified as lowercase and with the leading
+.Va O_
+removed.
+Default value is
+.Va rdonly .
.It Cm iseek= Ns Ar n
Seek on the input file
.Ar n
@@ -180,6 +195,32 @@ If an initial portion of the output file
.Cm seek
operand)
the output file is truncated at that point.
+.It Cm oflag= Ns Ar flags
+Same as
+.Cm iflag
+but for the call to
+.Xr open 2
+on the output file.
+The default value is
+.Va creat ,
+which should be explicitly added in
+.Cm oflag
+in order to output to a nonexistent file.
+The default or specified value is or'ed with
+.Va rdwr
+for a first
+.Xt open 2
+attempt, then on failure with
+.Va wronly
+on a second attempt.
+In both cases,
+.Va trunc
+is automatically added if none of
+.Cm oseek ,
+.Cm seek ,
+or
+.Cm conv=notrunc
+operands are used,
.It Cm oseek= Ns Ar n
Seek on the output file
.Ar n
Index: src/bin/dd/dd.c
diff -u src/bin/dd/dd.c:1.49 src/bin/dd/dd.c:1.49.12.1
--- src/bin/dd/dd.c:1.49 Tue Feb 21 01:49:01 2012
+++ src/bin/dd/dd.c Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $ */
+/* $NetBSD: dd.c,v 1.49.12.1 2015/03/26 11:08:43 martin Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 19
#if 0
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
#else
-__RCSID("$NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $");
+__RCSID("$NetBSD: dd.c,v 1.49.12.1 2015/03/26 11:08:43 martin Exp $");
#endif
#endif /* not lint */
@@ -81,6 +81,13 @@ void (*cfunc)(void); /* conversion fun
uint64_t cpy_cnt; /* # of blocks to copy */
static off_t pending = 0; /* pending seek if sparse */
u_int ddflags; /* conversion options */
+#ifdef NO_IOFLAG
+#define iflag O_RDONLY
+#define oflag O_CREAT
+#else
+u_int iflag = O_RDONLY; /* open(2) flags for input file */
+u_int oflag = O_CREAT; /* open(2) flags for output file */
+#endif /* NO_IOFLAG */
uint64_t cbsz; /* conversion block size */
u_int files_cnt = 1; /* # of files to copy */
uint64_t progress = 0; /* display sign of life */
@@ -160,7 +167,7 @@ setup(void)
in.ops = &ddfops_stdfd;
} else {
in.ops = prog_ops;
- in.fd = ddop_open(in, in.name, O_RDONLY, 0);
+ in.fd = ddop_open(in, in.name, iflag, 0);
if (in.fd < 0)
err(EXIT_FAILURE, "%s", in.name);
/* NOTREACHED */
@@ -183,8 +190,21 @@ setup(void)
out.ops = &ddfops_stdfd;
} else {
out.ops = prog_ops;
+
+#ifndef NO_IOFLAG
+ if ((oflag & O_TRUNC) && (ddflags & C_SEEK)) {
+ errx(EXIT_FAILURE, "oflag=trunc is incompatible "
+ "with seek or oseek operands, giving up.");
+ /* NOTREACHED */
+ }
+ if ((oflag & O_TRUNC) && (ddflags & C_NOTRUNC)) {
+ errx(EXIT_FAILURE, "oflag=trunc is incompatible "
+ "with conv=notrunc operand, giving up.");
+ /* NOTREACHED */
+ }
+#endif /* NO_IOFLAG */
#define OFLAGS \
- (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
+ (oflag | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE);
/*
* May not have read access, so try again with write only.
Index: src/bin/dd/dd.h
diff -u src/bin/dd/dd.h:1.15 src/bin/dd/dd.h:1.15.24.1
--- src/bin/dd/dd.h:1.15 Fri Feb 4 19:42:12 2011
+++ src/bin/dd/dd.h Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dd.h,v 1.15 2011/02/04 19:42:12 pooka Exp $ */
+/* $NetBSD: dd.h,v 1.15.24.1 2015/03/26 11:08:43 martin Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -98,7 +98,8 @@ typedef struct {
struct timeval start; /* start time of dd */
} STAT;
-/* Flags (in ddflags). */
+/* Flags (in ddflags, iflag and oflag). */
+#define C_NONE 0x00000
#define C_ASCII 0x00001
#define C_BLOCK 0x00002
#define C_BS 0x00004
@@ -121,3 +122,5 @@ typedef struct {
#define C_UNBLOCK 0x80000
#define C_OSYNC 0x100000
#define C_SPARSE 0x200000
+#define C_IFLAG 0x400000
+#define C_OFLAG 0x800000
Index: src/bin/dd/extern.h
diff -u src/bin/dd/extern.h:1.22 src/bin/dd/extern.h:1.22.20.1
--- src/bin/dd/extern.h:1.22 Mon Nov 7 22:24:23 2011
+++ src/bin/dd/extern.h Thu Mar 26 11:08:43 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.22 2011/11/07 22:24:23 jym Exp $ */
+/* $NetBSD: extern.h,v 1.22.20.1 2015/03/26 11:08:43 martin Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -72,6 +72,10 @@ extern void (*cfunc)(void);
extern uint64_t cpy_cnt;
extern uint64_t cbsz;
extern u_int ddflags;
+#ifndef NO_IOFLAG
+extern u_int iflag;
+extern u_int oflag;
+#endif /* NO_IOFLAG */
extern u_int files_cnt;
extern uint64_t progress;
extern const u_char *ctab;