Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/dd Add iflag and oflag operands to dd(1)
details: https://anonhg.NetBSD.org/src/rev/973369fc2a63
branches: trunk
changeset: 806911:973369fc2a63
user: manu <manu%NetBSD.org@localhost>
date: Wed Mar 18 13:23:49 2015 +0000
description:
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
diffstat:
bin/dd/Makefile | 5 +-
bin/dd/args.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
bin/dd/dd.1 | 41 ++++++++++++++++++-
bin/dd/dd.c | 28 +++++++++++-
bin/dd/dd.h | 7 ++-
bin/dd/extern.h | 6 ++-
6 files changed, 193 insertions(+), 12 deletions(-)
diffs (truncated from 351 to 300 lines):
diff -r a516f8869ef4 -r 973369fc2a63 bin/dd/Makefile
--- a/bin/dd/Makefile Wed Mar 18 13:20:20 2015 +0000
+++ b/bin/dd/Makefile Wed Mar 18 13:23:49 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.17 2012/08/08 14:09:14 christos Exp $
+# $NetBSD: Makefile,v 1.18 2015/03/18 13:23:49 manu Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
.include <bsd.own.mk>
@@ -10,8 +10,9 @@
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
diff -r a516f8869ef4 -r 973369fc2a63 bin/dd/args.c
--- a/bin/dd/args.c Wed Mar 18 13:20:20 2015 +0000
+++ b/bin/dd/args.c Wed Mar 18 13:23:49 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $ */
+/* $NetBSD: args.c,v 1.39 2015/03/18 13:23:49 manu 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.39 2015/03/18 13:23:49 manu 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 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 @@
{ "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 @@
}
#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 */
diff -r a516f8869ef4 -r 973369fc2a63 bin/dd/dd.1
--- a/bin/dd/dd.1 Wed Mar 18 13:20:20 2015 +0000
+++ b/bin/dd/dd.1 Wed Mar 18 13:23:49 2015 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: dd.1,v 1.25 2012/06/20 17:54:16 wiz Exp $
+.\" $NetBSD: dd.1,v 1.26 2015/03/18 13:23:49 manu Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -91,6 +91,21 @@
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,30 @@
.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 explictely added in
+.Cm oflag
+in order to output to a nonexistant 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
diff -r a516f8869ef4 -r 973369fc2a63 bin/dd/dd.c
--- a/bin/dd/dd.c Wed Mar 18 13:20:20 2015 +0000
+++ b/bin/dd/dd.c Wed Mar 18 13:23:49 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $ */
+/* $NetBSD: dd.c,v 1.50 2015/03/18 13:23:49 manu Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -43,7 +43,7 @@
#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.50 2015/03/18 13:23:49 manu Exp $");
#endif
#endif /* not lint */
@@ -81,6 +81,13 @@
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 @@
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 @@
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 */
Home |
Main Index |
Thread Index |
Old Index