dj(1) - disk jockey #15
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is a proposal for a Bonsai analogue to dd(1p)'s input/output redirection and control functionality, or disk jockeying, and pertains to #23.
Much like how a deejay / DJ / disc jockey queues up certain parts of records and plays them at certain times during their performance, dj(1) queues up certain parts of files and outputs them to certain parts of other files.
For example, to copy 4 blocks of size 64B, starting at 0x80, from in, to out at 0x80, with a 512B write buffer:
The syntax seems intuitive to me except
-b
,-B
,-s
, and-S
, which may be confused.-
as input or output would refer to/dev/stdin
and/dev/stdout
respectively. Input and output files have to be specifiable because neither standard input nor standard output can be seeked. Standard input when used with a nonzero-s
would have [input seek] bytes read and discarded. Standard output when used with a nonzero-S
would write [output seek] nul bytes before writing from the input. It may be better to error out if either standard input and-s
or standard output and-S
are combined so as to avoid unintended behavior.Invoked without arguments the following sane defaults would be assumed:
A count of 0 would copy the entirety of the input file.
Pseudocode for the program would be something like this:
dj(1) would be as useful as dd(1) for this purpose but not an improvement per se. However the invocation syntax would make sense as opposed to dd(1), which would be nice.
thoughts on removing
-i
and-o
?dj [-b input_size] [-B output_size] [-s input_start] [-S output_start] file1 [file2]
if
file2
is not specified, use stdout.The amount of scenarios where one would want an input file and standard output, and the amount where one would want standard input and an output file, seem to be roughly equal to me. Requiring an input argument even if standard input would favor the former scenario ergonomically (
dj in
versusdj - out
).please rephrase this, i have no idea what this is saying
For example, using your proposed argument format.
Using dj(1) to write a file directly to a block device (this is a weird use case but a friend and I did this yesterday):
(Perhaps dj(1) should output to standard error a summary of operations, like dd(1p).)
Using dj(1) to read a file directly from a block device:
There's an asymmetry. dj(1) needs
argc == 5
to write, butargc == 4
to read, both each with one option and option argument specified. It might be a little silly but I really don't like the imbalance.you get free reign on how this works :)
Some thoughts about dj(1) I have today.
Some dd(1p) behavior I find interesting:
read(fd, buf, ibs) < ibs
) dd(1p) operates on that block in particular. This meansdd if=/dev/zero bs=10 count=10 | wc -c
can output0
or any unsigned value less thanbs * count
. Many would assume this could only output100
.conv=sync
dd(1p) will fill the unused bytes of the input buffer with nuls (or spaces ifconv=block
orconv=ublock
).Character conversion including the
ascii
,ebcdic
,ibm
,block
,ublock
,lcase
,ucase
, andswab
aren't relevant to dj(1) butnoerror
,notrunc
, andsync
probably are and should be implemented as well.Actually - not truncating the output file should be the default. Truncation can be achieved easily:
trinity referenced this issue2023-12-30 08:36:22 -07:00
There are some nuances I'm trying to figure out.
One is specifically at the last dd(1p) invocation here:
POSIX says the following:
Because 100 bytes will be written to the pipe from which 1000 bytes are trying to be skipped, Busybox dd(1) exits with 0+0 records read. In strace and ltrace it seems its dd(1) gives read(2) a second try if it initially exits 0 (due to an unavailable device or something) so I implemented this:
Busybox dd(1) exits saying 0+0 because the reading for the purpose of skipping failed. This behavior is the same whether or not
conv=noerror
is specified.I find the
conv=noerror
description to be a little confusing:The end of a file apparently doesn't count as an ignorable error which makes sense. I wonder how to simulate an ignorable error though.
I just noticed dd(1p) specifies that
seek=100
andskip=100
seek/skip 100 blocks, not bytes. I'm not replicating that behavior because it sucks.Busybox dd(1) fails to seek on streams because lseek(3) returns
-1
and setserrno
to29
, "Invalid seek". I don't think this follows POSIX, which says the following:I'll be following POSIX for this behavior of dj(1) (though with bytes, not blocks).
Busybox dd(1) doesn't count skipped records written as nuls in its statistics output. Given the use of the phrasing "before copying" I think this is fine.
POSIX dd(1p) does this:
dj(1) will have a
-a
option ("Align") to follow this behavior.-A
will sync using nuls as the padding,-a
will take a single-byte argument and use that.Make sure to close issues when you’re done with them!