aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2020-10-13 20:27:48 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2020-10-13 20:27:48 +0000
commit4ca8449c2826be469bc9558f2a037236c6703d64 (patch)
treef4822e70e3a382a651636a46271bd4e4407f7f6a /testing
parent050aa4385fef1eb0ef515bdc97c47dc24858354a (diff)
downloadsg3_utils-4ca8449c2826be469bc9558f2a037236c6703d64.tar.gz
sg_dd: add oflag=nocreat and conv=nocreat : OFILE must exist; similar in testing sgh_dd+sg_mrq_dd
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@865 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/sg_mrq_dd.cpp82
-rw-r--r--testing/sgh_dd.cpp72
2 files changed, 131 insertions, 23 deletions
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 5cd9da49..f304eb51 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.14 20201008";
+static const char * version_str = "1.15 20201012";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -180,6 +180,7 @@ struct flags_t {
bool fua;
bool masync; /* more async sg v4 driver fd flag */
bool no_dur;
+ bool nocreat;
bool order;
bool qhead;
bool qtail;
@@ -816,11 +817,11 @@ usage(int pg_num)
else if (pg_num > 1)
goto page2;
- pr2serr("Usage: sg_mrq_dd [bs=BS] [count=COUNT] [ibs=BS] [if=IFILE]"
- " [iflag=FLAGS]\n"
- " [obs=BS] [of=OFILE] [oflag=FLAGS] "
- "[seek=SEEK]\n"
- " [skip=SKIP] [--help] [--verify] "
+ pr2serr("Usage: sg_mrq_dd [bs=BS] [conv=CONV] [count=COUNT] [ibs=BS] "
+ "[if=IFILE]\n"
+ " [iflag=FLAGS] [obs=BS] [of=OFILE] "
+ "[oflag=FLAGS]\n"
+ " [seek=SEEK] [skip=SKIP] [--help] [--verify] "
"[--version]\n\n");
pr2serr(" [bpt=BPT] [cdbsz=6|10|12|16] [dio=0|1] "
"[elemsz_kb=EKB]\n"
@@ -838,6 +839,9 @@ usage(int pg_num)
"above) are:\n"
" bs must be device logical block size (default "
"512)\n"
+ " conv comma separated list from: [nocreat,noerror,"
+ "notrunc,\n"
+ " null,sync]\n"
" count number of blocks to copy (def: device size)\n"
" if file or device to read from (def: stdin)\n"
" iflag comma separated list from: [coe,dio,"
@@ -848,8 +852,8 @@ usage(int pg_num)
"N.B. different\n"
" from dd it defaults to stdout). If 'of=.' "
"uses /dev/null\n"
- " oflag comma separated list from: [append,<<list from "
- "iflag>>]\n"
+ " oflag comma separated list from: [append,nocreat,\n"
+ " <<list from iflag>>]\n"
" seek block position to start writing to OFILE\n"
" skip block position to start reading from IFILE\n"
" --help|-h output this usage message then exit\n"
@@ -928,6 +932,7 @@ page3:
" masync set 'more async' flag on this sg device\n"
" mmap setup mmap IO on IFILE or OFILE\n"
" mmap,mmap when used twice, doesn't call munmap()\n"
+ " nocreat will fail rather than create OFILE\n"
" nodur turns off command duration calculations\n"
" order require write ordering on sg->sg copy; only "
"for oflag\n"
@@ -3032,6 +3037,46 @@ sg_out_open(struct global_collection *clp, const char *outf, uint8_t **mmpp,
return fd;
}
+/* Process arguments given to 'conv=" option. Returns 0 on success,
+ * 1 on error. */
+static int
+process_conv(const char * arg, struct flags_t * ifp, struct flags_t * ofp)
+{
+ char buff[256];
+ char * cp;
+ char * np;
+
+ strncpy(buff, arg, sizeof(buff));
+ buff[sizeof(buff) - 1] = '\0';
+ if ('\0' == buff[0]) {
+ pr2serr("no conversions found\n");
+ return 1;
+ }
+ cp = buff;
+ do {
+ np = strchr(cp, ',');
+ if (np)
+ *np++ = '\0';
+ if (0 == strcmp(cp, "nocreat"))
+ ofp->nocreat = true;
+ else if (0 == strcmp(cp, "noerror"))
+ ifp->coe = true; /* will still fail on write error */
+ else if (0 == strcmp(cp, "notrunc"))
+ ; /* this is the default action of sg_dd so ignore */
+ else if (0 == strcmp(cp, "null"))
+ ;
+ else if (0 == strcmp(cp, "sync"))
+ ; /* dd(susv4): pad errored block(s) with zeros but sg_dd does
+ * that by default. Typical dd use: 'conv=noerror,sync' */
+ else {
+ pr2serr("unrecognised flag: %s\n", cp);
+ return 1;
+ }
+ cp = np;
+ } while (cp);
+ return 0;
+}
+
#define STR_SZ 1024
#define INOUTF_SZ 512
@@ -3087,6 +3132,11 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
/* not documented, for compat with sgh_dd */
clp->in_flags.coe = !! sg_get_num(buf);
clp->out_flags.coe = clp->in_flags.coe;
+ } else if (0 == strcmp(key, "conv")) {
+ if (process_conv(buf, &clp->in_flags, &clp->out_flags)) {
+ pr2serr("%s: bad argument to 'conv='\n", my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
} else if (0 == strcmp(key, "count")) {
if (clp->count_given) {
pr2serr("second 'count=' argument detected, only one "
@@ -3664,14 +3714,14 @@ main(int argc, char * argv[])
clp->infd = STDIN_FILENO;
clp->outfd = STDOUT_FILENO;
if (clp->in_flags.ff) {
- ccp = "<0xff bytes>";
- cc2p = "ff";
+ ccp = "<0xff bytes>";
+ cc2p = "ff";
} else if (clp->in_flags.random) {
- ccp = "<random>";
- cc2p = "random";
+ ccp = "<random>";
+ cc2p = "random";
} else if (clp->in_flags.zero) {
- ccp = "<zero bytes>";
- cc2p = "00";
+ ccp = "<zero bytes>";
+ cc2p = "00";
}
if (ccp) {
if (inf[0]) {
@@ -3737,7 +3787,9 @@ main(int argc, char * argv[])
clp->outfd = -1; /* don't bother opening */
else {
if (FT_RAW != clp->out_type) {
- flags = O_WRONLY | O_CREAT;
+ flags = O_WRONLY;
+ if (! clp->out_flags.nocreat)
+ flags |= O_CREAT;
if (clp->out_flags.direct)
flags |= O_DIRECT;
if (clp->out_flags.excl)
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index 82d9869d..b7381f44 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.94 20200927";
+static const char * version_str = "1.95 20201012";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -177,6 +177,7 @@ struct flags_t {
bool mrq_immed; /* mrq submit non-blocking */
bool mrq_svb; /* mrq shared_variable_block, for sg->sg copy */
bool no_dur;
+ bool nocreat;
bool noshare;
bool no_unshare; /* leave it for driver close/release */
bool no_waitq;
@@ -889,11 +890,11 @@ usage(int pg_num)
else if (pg_num > 1)
goto page2;
- pr2serr("Usage: sgh_dd [bs=BS] [count=COUNT] [ibs=BS] [if=IFILE]"
- " [iflag=FLAGS]\n"
- " [obs=BS] [of=OFILE] [oflag=FLAGS] "
- "[seek=SEEK] [skip=SKIP]\n"
- " [--help] [--version]\n\n");
+ pr2serr("Usage: sgh_dd [bs=BS] [conv=CONVS] [count=COUNT] [ibs=BS] "
+ "[if=IFILE]\n"
+ " [iflag=FLAGS] [obs=BS] [of=OFILE] [oflag=FLAGS] "
+ "[seek=SEEK]\n"
+ " [skip=SKIP] [--help] [--version]\n\n");
pr2serr(" [ae=AEN[,MAEN]] [bpt=BPT] [cdbsz=6|10|12|16] "
"[coe=0|1]\n"
" [dio=0|1] [elemsz_kb=EKB] [fail_mask=FM] "
@@ -908,6 +909,9 @@ usage(int pg_num)
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
"512)\n"
+ " conv comma separated list from: [nocreat,noerror,"
+ "notrunc,\n"
+ " null,sync]\n"
" count number of blocks to copy (def: device size)\n"
" if file or device to read from (def: stdin)\n"
" iflag comma separated list from: [coe,defres,dio,"
@@ -1021,6 +1025,7 @@ page3:
" blocking)\n"
" mrq_svb if mrq and sg->sg copy, do shared_variable_"
"blocking\n"
+ " nocreat will fail rather than create OFILE\n"
" nodur turns off command duration calculations\n"
" no_waitq when non-blocking (async) don't use wait "
"queue\n"
@@ -3660,6 +3665,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->no_dur = true;
else if (0 == strcmp(cp, "no_dur"))
fp->no_dur = true;
+ else if (0 == strcmp(cp, "nocreat"))
+ fp->nocreat = true;
else if (0 == strcmp(cp, "noshare"))
fp->noshare = true;
else if (0 == strcmp(cp, "no_share"))
@@ -3784,6 +3791,46 @@ sg_out_open(struct global_collection *clp, const char *outf, uint8_t **mmpp,
return fd;
}
+/* Process arguments given to 'conv=" option. Returns 0 on success,
+ * 1 on error. */
+static int
+process_conv(const char * arg, struct flags_t * ifp, struct flags_t * ofp)
+{
+ char buff[256];
+ char * cp;
+ char * np;
+
+ strncpy(buff, arg, sizeof(buff));
+ buff[sizeof(buff) - 1] = '\0';
+ if ('\0' == buff[0]) {
+ pr2serr("no conversions found\n");
+ return 1;
+ }
+ cp = buff;
+ do {
+ np = strchr(cp, ',');
+ if (np)
+ *np++ = '\0';
+ if (0 == strcmp(cp, "nocreat"))
+ ofp->nocreat = true;
+ else if (0 == strcmp(cp, "noerror"))
+ ifp->coe = true; /* will still fail on write error */
+ else if (0 == strcmp(cp, "notrunc"))
+ ; /* this is the default action of sg_dd so ignore */
+ else if (0 == strcmp(cp, "null"))
+ ;
+ else if (0 == strcmp(cp, "sync"))
+ ; /* dd(susv4): pad errored block(s) with zeros but sg_dd does
+ * that by default. Typical dd use: 'conv=noerror,sync' */
+ else {
+ pr2serr("unrecognised flag: %s\n", cp);
+ return 1;
+ }
+ cp = np;
+ } while (cp);
+ return 0;
+}
+
#define STR_SZ 1024
#define INOUTF_SZ 512
@@ -3853,6 +3900,11 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
} else if (0 == strcmp(key, "coe")) {
clp->in_flags.coe = !! sg_get_num(buf);
clp->out_flags.coe = clp->in_flags.coe;
+ } else if (0 == strcmp(key, "conv")) {
+ if (process_conv(buf, &clp->in_flags, &clp->out_flags)) {
+ pr2serr("%s: bad argument to 'conv='\n", my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
} else if (0 == strcmp(key, "count")) {
if (0 != strcmp("-1", buf)) {
dd_count = sg_get_llnum(buf);
@@ -4327,7 +4379,9 @@ main(int argc, char * argv[])
clp->outfd = -1; /* don't bother opening */
else {
if (FT_RAW != clp->out_type) {
- flags = O_WRONLY | O_CREAT;
+ flags = O_WRONLY;
+ if (! clp->out_flags.nocreat)
+ flags |= O_CREAT;
if (clp->out_flags.direct)
flags |= O_DIRECT;
if (clp->out_flags.excl)
@@ -4395,7 +4449,9 @@ main(int argc, char * argv[])
clp->out2fd = -1; /* don't bother opening */
else {
if (FT_RAW != clp->out2_type) {
- flags = O_WRONLY | O_CREAT;
+ flags = O_WRONLY;
+ if (! clp->out_flags.nocreat)
+ flags |= O_CREAT;
if (clp->out_flags.direct)
flags |= O_DIRECT;
if (clp->out_flags.excl)