dd: implement oflag=append and oflag=direct.

This commit is contained in:
Elliott Hughes 2025-06-04 14:08:22 +00:00 committed by Rob Landley
parent f712314272
commit 957903785a
4 changed files with 21 additions and 7 deletions

View File

@ -54,7 +54,8 @@
// will transitively include it, and ones that don't (macOS) won't break.
#include <sys/types.h>
// Various constants old build environments might not have even if kernel does
// Various constants old build environments (or glibc, hiding behind
// _GNU_SOURCE) might not have even if kernel does.
#ifndef AT_FDCWD // Kernel commit 5590ff0d5528 2006
#define AT_FDCWD -100
@ -68,6 +69,10 @@
#define AT_REMOVEDIR 0x200
#endif
#ifndef O_DIRECT
#define O_DIRECT 0x4000
#endif
#ifndef RLIMIT_RTTIME // Commit 78f2c7db6068f 2008
#define RLIMIT_RTTIME 15
#endif

View File

@ -131,3 +131,6 @@ testing 'sync padding ticks down count' \
'for i in one two three four five "$(seq 1 100)"
do echo "$i"; sleep .1; done | dd bs=1024 count=5 conv=sync | sha1sum' \
'02dcf1f497ccbe940f57818dfc34f2d0def8b3f9 -\n' '' ''
echo -n "hello " > file
testcmd "oflag=append" "of=file oflag=append conv=notrunc && cat file" "hello world\n" "" "world\n"

View File

@ -374,7 +374,7 @@ static void print_flags(long v)
C(O_CREAT), C(O_DIRECTORY), C(O_EXCL), C(O_NOCTTY), C(O_NOFOLLOW),
C(O_TRUNC), C(O_ASYNC), C(O_APPEND), C(O_DSYNC), C(O_EXCL),
C(O_NOATIME), C(O_NONBLOCK), C(O_PATH), C(O_SYNC),
0x4000, "O_DIRECT", 0x8000, "O_LARGEFILE", 0x410000, "O_TMPFILE", 0);
C(O_DIRECT), 0x8000, "O_LARGEFILE", 0x410000, "O_TMPFILE", 0);
} else if (strstart(&TT.fmt, "prot|")) {
print_bits(1,v,"PROT_NONE",C(PROT_READ),C(PROT_WRITE),C(PROT_EXEC),
#if defined(PROT_BTI)

View File

@ -29,7 +29,9 @@ config DD
These modifiers take a comma separated list of potential options:
iflag=count_bytes,skip_bytes count=N or skip=N is in bytes not blocks
oflag=seek_bytes,append seek=N is in bytes, append output to file
oflag=
append Append to file direct Skip caches
seek_bytes seek=N is in bytes
status=noxfer,none don't show transfer rate, no summary info
conv=
notrunc Don't truncate output noerror Continue after read errors
@ -60,7 +62,7 @@ static const struct dd_flag dd_iflag[] = TAGGED_ARRAY(DD_iflag,
);
static const struct dd_flag dd_oflag[] = TAGGED_ARRAY(DD_oflag,
{"seek_bytes"},
{"append"}, {"direct"}, {"seek_bytes"},
);
static void status()
@ -149,7 +151,7 @@ void dd_main()
count = ULLONG_MAX, buflen;
long long len;
struct iovec iov[2];
int opos, olen, ifd = 0, ofd = 1, trunc = O_TRUNC, creat = O_CREAT, ii;
int opos, olen, ifd = 0, ofd = 1, trunc = O_TRUNC, oflags, ii;
unsigned conv = 0, iflag = 0, oflag = 0;
TT.show_xfer = TT.show_records = 1;
@ -186,11 +188,15 @@ void dd_main()
buf = xmalloc(buflen = ibs+obs*!bs);
if (buflen<ibs || buflen<obs) error_exit("tilt");
if (conv & _DD_conv_nocreat) creat = 0;
oflags = O_CREAT|O_WRONLY;
if (conv & _DD_conv_nocreat) oflags &= ~O_CREAT;
if (conv & _DD_conv_notrunc) trunc = 0;
if (oflag & _DD_oflag_append) oflags |= O_APPEND;
if (oflag & _DD_oflag_direct) oflags |= O_DIRECT;
if (iname) ifd = xopenro(iname);
else iname = "stdin";
if (oname) ofd = xcreate(oname, O_WRONLY|creat|(trunc*!seek),0666);
if (oname) ofd = xcreate(oname, oflags|(trunc*!seek), 0666);
else oname = "stdout";
// Implement skip=