Index: bin/dd/args.c =================================================================== --- bin/dd/args.c +++ bin/dd/args.c @@ -317,6 +317,7 @@ } clist[] = { { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, { "block", C_BLOCK, C_UNBLOCK, NULL }, + { "direct", C_DIRECT, 0, NULL }, { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, { "lcase", C_LCASE, C_UCASE, NULL }, Index: bin/dd/dd.h =================================================================== --- bin/dd/dd.h +++ bin/dd/dd.h @@ -100,5 +100,6 @@ #define C_STATUS 0x08000000 #define C_NOXFER 0x10000000 #define C_NOINFO 0x20000000 +#define C_DIRECT 0x40000000 #define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET) Index: bin/dd/dd.1 =================================================================== --- bin/dd/dd.1 +++ bin/dd/dd.1 @@ -215,6 +215,8 @@ Input records longer than the conversion record size are truncated. The number of truncated input records, if any, are reported to the standard error output at the completion of the copy. +.It Cm direct +Open all files O_DIRECT to eliminate or reduce VM cache effects. .It Cm ebcdic , ibm , oldebcdic , oldibm The same as the .Cm block Index: bin/dd/dd.c =================================================================== --- bin/dd/dd.c +++ bin/dd/dd.c @@ -136,12 +136,15 @@ u_int cnt; cap_rights_t rights; unsigned long cmds[] = { FIODTYPE, MTIOCTOP }; + int oflags = 0; + if (ddflags & C_DIRECT) + oflags |= O_DIRECT; if (in.name == NULL) { in.name = "stdin"; in.fd = STDIN_FILENO; } else { - in.fd = open(in.name, O_RDONLY, 0); + in.fd = open(in.name, O_RDONLY | oflags, 0); if (in.fd == -1) err(1, "%s", in.name); } @@ -161,16 +164,15 @@ out.fd = STDOUT_FILENO; out.name = "stdout"; } else { -#define OFLAGS \ - (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC)) - out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE); + oflags |= O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC); + out.fd = open(out.name, O_RDWR | oflags, DEFFILEMODE); /* * May not have read access, so try again with write only. * Without read we may have a problem if output also does * not support seeks. */ if (out.fd == -1) { - out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE); + out.fd = open(out.name, O_WRONLY | oflags, DEFFILEMODE); out.flags |= NOREAD; cap_rights_clear(&rights, CAP_READ); }