Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dd: parse operands manually via positional args #3938

Merged
merged 1 commit into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions src/uu/dd/dd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<!-- spell-checker:ignore convs iseek oseek -->
# dd

## About
Copy, and optionally convert, a file system resource

## After Help

OPERANDS:

bs=BYTES read and write up to BYTES bytes at a time (default: 512);
overwrites ibs and obs.
cbs=BYTES the 'conversion block size' in bytes. Applies to
the conv=block, and conv=unblock operations.
conv=CONVS a comma-separated list of conversion options or
(for legacy reasons) file flags.
count=N stop reading input after N ibs-sized read operations rather
than proceeding until EOF. See iflag=count_bytes if stopping
after N bytes is preferred
ibs=N the size of buffer used for reads (default: 512)
if=FILE the file used for input. When not specified, stdin is used instead
iflag=FLAGS a comma-separated list of input flags which specify how the input
source is treated. FLAGS may be any of the input-flags or
general-flags specified below.
skip=N (or iseek=N) skip N ibs-sized records into input before beginning
copy/convert operations. See iflag=seek_bytes if seeking N bytes
is preferred.
obs=N the size of buffer used for writes (default: 512)
of=FILE the file used for output. When not specified, stdout is used
instead
oflag=FLAGS comma separated list of output flags which specify how the output
source is treated. FLAGS may be any of the output flags or
general flags specified below
seek=N (or oseek=N) seeks N obs-sized records into output before
beginning copy/convert operations. See oflag=seek_bytes if
seeking N bytes is preferred
status=LEVEL controls whether volume and performance stats are written to
stderr.

When unspecified, dd will print stats upon completion. An example is below.
6+0 records in
16+0 records out
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.00057009 s, 14.4 MB/s
The first two lines are the 'volume' stats and the final line is
the 'performance' stats.
The volume stats indicate the number of complete and partial
ibs-sized reads, or obs-sized writes that took place during the
copy. The format of the volume stats is
<complete>+<partial>. If records have been truncated (see
conv=block), the volume stats will contain the number of
truncated records.

Possible LEVEL values are:
progress: Print periodic performance stats as the copy
proceeds.
noxfer: Print final volume stats, but not performance stats.
none: Do not print any stats.

Printing performance stats is also triggered by the INFO signal
(where supported), or the USR1 signal. Setting the
POSIXLY_CORRECT environment variable to any value (including an
empty value) will cause the USR1 signal to be ignored.

CONVERSION OPTIONS:

ascii convert from EBCDIC to ASCII. This is the inverse of the 'ebcdic'
option. Implies conv=unblock.
ebcdic convert from ASCII to EBCDIC. This is the inverse of the 'ascii'
option. Implies conv=block.
ibm convert from ASCII to EBCDIC, applying the conventions for '[', ']'
and '~' specified in POSIX. Implies conv=block.

ucase convert from lower-case to upper-case
lcase converts from upper-case to lower-case.

block for each newline less than the size indicated by cbs=BYTES, remove
the newline and pad with spaces up to cbs. Lines longer than cbs are
truncated.
unblock for each block of input of the size indicated by cbs=BYTES, remove
right-trailing spaces and replace with a newline character.

sparse attempts to seek the output when an obs-sized block consists of only
zeros.
swab swaps each adjacent pair of bytes. If an odd number of bytes is
present, the final byte is omitted.
sync pad each ibs-sided block with zeros. If 'block' or 'unblock' is
specified, pad with spaces instead.
excl the output file must be created. Fail if the output file is already
present.
nocreat the output file will not be created. Fail if the output file in not
already present.
notrunc the output file will not be truncated. If this option is not
present, output will be truncated when opened.
noerror all read errors will be ignored. If this option is not present, dd
will only ignore Error::Interrupted.
fdatasync data will be written before finishing.
fsync data and metadata will be written before finishing.

INPUT FLAGS:

count_bytes a value to count=N will be interpreted as bytes.
skip_bytes a value to skip=N will be interpreted as bytes.
fullblock wait for ibs bytes from each read. zero-length reads are still
considered EOF.

OUTPUT FLAGS:

append open file in append mode. Consider setting conv=notrunc as well.
seek_bytes a value to seek=N will be interpreted as bytes.

GENERAL FLAGS:

direct use direct I/O for data.
directory fail unless the given input (if used as an iflag) or output (if used
as an oflag) is a directory.
dsync use synchronized I/O for data.
sync use synchronized I/O for data and metadata.
nonblock use non-blocking I/O.
noatime do not update access time.
nocache request that OS drop cache.
noctty do not assign a controlling tty.
nofollow do not follow system links.
40 changes: 8 additions & 32 deletions src/uu/dd/src/datastructures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ type Cbs = usize;
/// certain order. The variants of this enumeration give the different
/// ways of combining those three operations.
#[derive(Debug, PartialEq)]
pub(crate) enum ConversionMode<'a> {
ConvertOnly(&'a ConversionTable),
pub(crate) enum ConversionMode {
ConvertOnly(&'static ConversionTable),
BlockOnly(Cbs, bool),
UnblockOnly(Cbs),
BlockThenConvert(&'a ConversionTable, Cbs, bool),
ConvertThenBlock(&'a ConversionTable, Cbs, bool),
UnblockThenConvert(&'a ConversionTable, Cbs),
ConvertThenUnblock(&'a ConversionTable, Cbs),
BlockThenConvert(&'static ConversionTable, Cbs, bool),
ConvertThenBlock(&'static ConversionTable, Cbs, bool),
UnblockThenConvert(&'static ConversionTable, Cbs),
ConvertThenUnblock(&'static ConversionTable, Cbs),
}

/// Stores all Conv Flags that apply to the input
#[derive(Debug, Default, PartialEq)]
pub(crate) struct IConvFlags {
pub mode: Option<ConversionMode<'static>>,
pub mode: Option<ConversionMode>,
pub swab: bool,
pub sync: Option<u8>,
pub noerror: bool,
Expand Down Expand Up @@ -88,30 +88,6 @@ pub struct OFlags {
pub seek_bytes: bool,
}

/// The value of count=N
/// Defaults to Reads(N)
/// if iflag=count_bytes
/// then becomes Bytes(N)
#[derive(Debug, PartialEq, Eq)]
pub enum CountType {
Reads(u64),
Bytes(u64),
}

pub mod options {
pub const INFILE: &str = "if";
pub const OUTFILE: &str = "of";
pub const IBS: &str = "ibs";
pub const OBS: &str = "obs";
pub const BS: &str = "bs";
pub const CBS: &str = "cbs";
pub const COUNT: &str = "count";
pub const SKIP: &str = "skip";
pub const SEEK: &str = "seek";
pub const ISEEK: &str = "iseek";
pub const OSEEK: &str = "oseek";
pub const STATUS: &str = "status";
pub const CONV: &str = "conv";
pub const IFLAG: &str = "iflag";
pub const OFLAG: &str = "oflag";
pub const OPERANDS: &str = "operands";
}
Loading