From 957903785aff716990a61c16b6531334c7019e97 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 4 Jun 2025 14:08:22 +0000 Subject: [PATCH] dd: implement oflag=append and oflag=direct. --- lib/portability.h | 7 ++++++- tests/dd.test | 3 +++ toys/pending/strace.c | 2 +- toys/posix/dd.c | 16 +++++++++++----- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/portability.h b/lib/portability.h index 29d5469f..e87b919f 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -54,7 +54,8 @@ // will transitively include it, and ones that don't (macOS) won't break. #include -// 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 diff --git a/tests/dd.test b/tests/dd.test index 11e869c9..b7bf5d4a 100644 --- a/tests/dd.test +++ b/tests/dd.test @@ -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" diff --git a/toys/pending/strace.c b/toys/pending/strace.c index b5047851..f612f07c 100644 --- a/toys/pending/strace.c +++ b/toys/pending/strace.c @@ -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) diff --git a/toys/posix/dd.c b/toys/posix/dd.c index ebd55f10..7f392965 100644 --- a/toys/posix/dd.c +++ b/toys/posix/dd.c @@ -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