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;

Reply via email to