From 47e61f064c0468e2e8d875b5aa24b1b23dc7126a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 20 Apr 2023 21:42:46 +0200 Subject: [PATCH 01/34] Fix a comment in the rustdoc --- tests/common/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 5d72a7abf..0898a4ad7 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -2016,7 +2016,7 @@ impl UChild { /// Read, consume and return the output as [`String`] from [`Child`]'s stdout. /// - /// See also [`UChild::stdout_bytes] for side effects. + /// See also [`UChild::stdout_bytes`] for side effects. pub fn stdout(&mut self) -> String { String::from_utf8(self.stdout_bytes()).unwrap() } From efa361dd7c2d39fb6f3eef702fe7f39d889f62d4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 20 Apr 2023 23:00:46 +0200 Subject: [PATCH 02/34] Fix some trivial clippy warnings --- tests/by-util/test_cp.rs | 3 +-- tests/by-util/test_ls.rs | 4 ++-- tests/by-util/test_pwd.rs | 2 +- tests/by-util/test_tee.rs | 7 ++++--- tests/by-util/test_yes.rs | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index dfbbc1473..12dd625c8 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1392,15 +1392,14 @@ fn test_cp_target_file_dev_null() { fn test_cp_one_file_system() { use crate::common::util::AtPath; use walkdir::WalkDir; - let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; // Test must be run as root (or with `sudo -E`) if scene.cmd("whoami").run().stdout_str() != "root\n" { return; } - let at = scene.fixtures.clone(); let at_src = AtPath::new(&at.plus(TEST_MOUNT_COPY_FROM_FOLDER)); let at_dst = AtPath::new(&at.plus(TEST_COPY_TO_FOLDER_NEW)); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 1a189a25a..f3f9c74cf 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1239,7 +1239,7 @@ fn test_ls_long_total_size() { ("long_si", "total 8.2k"), ] .iter() - .cloned() + .copied() .collect() } else { [ @@ -1248,7 +1248,7 @@ fn test_ls_long_total_size() { ("long_si", "total 2"), ] .iter() - .cloned() + .copied() .collect() }; diff --git a/tests/by-util/test_pwd.rs b/tests/by-util/test_pwd.rs index 5719e87d2..076e72089 100644 --- a/tests/by-util/test_pwd.rs +++ b/tests/by-util/test_pwd.rs @@ -27,7 +27,7 @@ fn test_deleted_dir() { use std::process::Command; let ts = TestScenario::new(util_name!()); - let at = ts.fixtures.clone(); + let at = ts.fixtures; let output = Command::new("sh") .arg("-c") .arg(format!( diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 946c60d0a..41751f266 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -118,9 +118,10 @@ mod linux_only { use std::os::unix::io::FromRawFd; let mut fds: [c_int; 2] = [0, 0]; - if unsafe { libc::pipe(&mut fds as *mut c_int) } != 0 { - panic!("Failed to create pipe"); - } + assert!( + !(unsafe { libc::pipe(&mut fds as *mut c_int) } != 0), + "Failed to create pipe" + ); // Drop the read end of the pipe let _ = unsafe { File::from_raw_fd(fds[0]) }; diff --git a/tests/by-util/test_yes.rs b/tests/by-util/test_yes.rs index 9f03780b7..c054a6e5f 100644 --- a/tests/by-util/test_yes.rs +++ b/tests/by-util/test_yes.rs @@ -6,12 +6,12 @@ use std::os::unix::process::ExitStatusExt; use crate::common::util::TestScenario; #[cfg(unix)] -fn check_termination(result: &ExitStatus) { +fn check_termination(result: ExitStatus) { assert_eq!(result.signal(), Some(libc::SIGPIPE)); } #[cfg(not(unix))] -fn check_termination(result: &ExitStatus) { +fn check_termination(result: ExitStatus) { assert!(result.success(), "yes did not exit successfully"); } @@ -23,7 +23,7 @@ fn run(args: &[&str], expected: &[u8]) { child.close_stdout(); #[allow(deprecated)] - check_termination(&child.wait_with_output().unwrap().status); + check_termination(child.wait_with_output().unwrap().status); assert_eq!(buf.as_slice(), expected); } From 12e4acaec3740a19cef2c804b25f8a92725ef8a5 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:03:36 -0500 Subject: [PATCH 03/34] dd: add bytes_total to ReadStat Add the `bytes_total` field to the `ReadStat` struct. This lets the main loop of `dd` keep track of the total number of bytes read. --- src/uu/dd/src/dd.rs | 8 ++++++-- src/uu/dd/src/progress.rs | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 836456635..ea353d625 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -317,13 +317,13 @@ impl<'a> Input<'a> { _ => break, } } - buf.truncate(bytes_total); Ok(ReadStat { reads_complete, reads_partial, // Records are not truncated when filling. records_truncated: 0, + bytes_total: bytes_total.try_into().unwrap(), }) } @@ -334,6 +334,7 @@ impl<'a> Input<'a> { let mut reads_complete = 0; let mut reads_partial = 0; let mut base_idx = 0; + let mut bytes_total = 0; while base_idx < buf.len() { let next_blk = cmp::min(base_idx + self.settings.ibs, buf.len()); @@ -342,11 +343,13 @@ impl<'a> Input<'a> { match self.read(&mut buf[base_idx..next_blk])? { 0 => break, rlen if rlen < target_len => { + bytes_total += rlen; reads_partial += 1; let padding = vec![pad; target_len - rlen]; buf.splice(base_idx + rlen..next_blk, padding.into_iter()); } - _ => { + rlen => { + bytes_total += rlen; reads_complete += 1; } } @@ -359,6 +362,7 @@ impl<'a> Input<'a> { reads_complete, reads_partial, records_truncated: 0, + bytes_total: bytes_total.try_into().unwrap(), }) } } diff --git a/src/uu/dd/src/progress.rs b/src/uu/dd/src/progress.rs index 51cfa92ef..65af053b8 100644 --- a/src/uu/dd/src/progress.rs +++ b/src/uu/dd/src/progress.rs @@ -79,9 +79,9 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::{ProgUpdate, ReadStat, WriteStat}; /// - /// let read_stat = ReadStat::new(1, 2, 3); + /// let read_stat = ReadStat::new(1, 2, 3, 999); /// let write_stat = WriteStat::new(4, 5, 6); /// let duration = Duration::new(789, 0); /// let prog_update = ProgUpdate { @@ -121,7 +121,7 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::ProgUpdate; /// /// let prog_update = ProgUpdate { /// read_stat: Default::default(), @@ -191,7 +191,7 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::ProgUpdate; /// /// let prog_update = ProgUpdate { /// read_stat: Default::default(), @@ -276,16 +276,20 @@ pub(crate) struct ReadStat { /// /// A truncated record can only occur in `conv=block` mode. pub(crate) records_truncated: u32, + + /// The total number of bytes read. + pub(crate) bytes_total: u64, } impl ReadStat { /// Create a new instance. #[allow(dead_code)] - fn new(complete: u64, partial: u64, truncated: u32) -> Self { + fn new(complete: u64, partial: u64, truncated: u32, bytes_total: u64) -> Self { Self { reads_complete: complete, reads_partial: partial, records_truncated: truncated, + bytes_total, } } @@ -315,6 +319,7 @@ impl std::ops::AddAssign for ReadStat { reads_complete: self.reads_complete + other.reads_complete, reads_partial: self.reads_partial + other.reads_partial, records_truncated: self.records_truncated + other.records_truncated, + bytes_total: self.bytes_total + other.bytes_total, } } } @@ -514,7 +519,7 @@ mod tests { #[test] fn test_read_stat_report() { - let read_stat = ReadStat::new(1, 2, 3); + let read_stat = ReadStat::new(1, 2, 3, 4); let mut cursor = Cursor::new(vec![]); read_stat.report(&mut cursor).unwrap(); assert_eq!(cursor.get_ref(), b"1+2 records in\n"); @@ -530,7 +535,7 @@ mod tests { #[test] fn test_prog_update_write_io_lines() { - let read_stat = ReadStat::new(1, 2, 3); + let read_stat = ReadStat::new(1, 2, 3, 4); let write_stat = WriteStat::new(4, 5, 6); let duration = Duration::new(789, 0); let complete = false; From cc2f97ba0dc61aa4cc3119f55c38e89e5808cb56 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:05:16 -0500 Subject: [PATCH 04/34] dd: add discard_cache() funcs for Input, Output Add the `Input::discard_cache()` and `Output::discard_cache()` functions. These allow discarding the filesystem cache when `dd` no longer needs to access a specified portion of the input or output file, respectively. --- Cargo.lock | 1 + src/uu/dd/Cargo.toml | 3 ++ src/uu/dd/src/dd.rs | 109 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9827a7893..caf494625 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2552,6 +2552,7 @@ dependencies = [ "clap", "gcd", "libc", + "nix", "signal-hook", "uucore", ] diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index b81ef1a8e..04b60dc31 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -20,6 +20,9 @@ gcd = { workspace=true } libc = { workspace=true } uucore = { workspace=true, features=["memo"] } +[target.'cfg(any(target_os = "linux"))'.dependencies] +nix = { workspace=true, features = ["fs"] } + [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] signal-hook = { workspace=true } diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index ea353d625..43f0da5df 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -5,7 +5,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable oconv canonicalized +// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable oconv canonicalized fadvise Fadvise FADV DONTNEED ESPIPE mod datastructures; use datastructures::*; @@ -42,9 +42,16 @@ use std::time; use clap::{crate_version, Arg, Command}; use gcd::Gcd; +#[cfg(target_os = "linux")] +use nix::{ + errno::Errno, + fcntl::{posix_fadvise, PosixFadviseAdvice}, +}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +#[cfg(target_os = "linux")] +use uucore::{show, show_if_err}; const ABOUT: &str = help_about!("dd.md"); const AFTER_HELP: &str = help_section!("after help", "dd.md"); @@ -131,6 +138,16 @@ impl Source { Self::StdinFile(f) } + /// The length of the data source in number of bytes. + /// + /// If it cannot be determined, then this function returns 0. + fn len(&self) -> std::io::Result { + match self { + Self::File(f) => Ok(f.metadata()?.len().try_into().unwrap_or(i64::MAX)), + _ => Ok(0), + } + } + fn skip(&mut self, n: u64) -> io::Result { match self { #[cfg(not(unix))] @@ -156,6 +173,23 @@ impl Source { Self::Fifo(f) => io::copy(&mut f.take(n), &mut io::sink()), } } + + /// Discard the system file cache for the given portion of the data source. + /// + /// `offset` and `len` specify a contiguous portion of the data + /// source. This function informs the kernel that the specified + /// portion of the source is no longer needed. If not possible, + /// then this function returns an error. + #[cfg(target_os = "linux")] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) -> nix::Result<()> { + match self { + Self::File(f) => { + let advice = PosixFadviseAdvice::POSIX_FADV_DONTNEED; + posix_fadvise(f.as_raw_fd(), offset, len, advice) + } + _ => Err(Errno::ESPIPE), // "Illegal seek" + } + } } impl Read for Source { @@ -296,6 +330,29 @@ impl<'a> Read for Input<'a> { } impl<'a> Input<'a> { + /// Discard the system file cache for the given portion of the input. + /// + /// `offset` and `len` specify a contiguous portion of the input. + /// This function informs the kernel that the specified portion of + /// the input file is no longer needed. If not possible, then this + /// function prints an error message to stderr and sets the exit + /// status code to 1. + #[allow(unused_variables)] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) { + #[cfg(target_os = "linux")] + { + show_if_err!(self + .src + .discard_cache(offset, len) + .map_err_context(|| "failed to discard cache for: 'standard input'".to_string())); + } + #[cfg(not(target_os = "linux"))] + { + // TODO Is there a way to discard filesystem cache on + // these other operating systems? + } + } + /// Fills a given buffer. /// Reads in increments of 'self.ibs'. /// The start of each ibs-sized read follows the previous one. @@ -451,6 +508,33 @@ impl Dest { _ => Ok(()), } } + + /// Discard the system file cache for the given portion of the destination. + /// + /// `offset` and `len` specify a contiguous portion of the + /// destination. This function informs the kernel that the + /// specified portion of the destination is no longer needed. If + /// not possible, then this function returns an error. + #[cfg(target_os = "linux")] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) -> nix::Result<()> { + match self { + Self::File(f, _) => { + let advice = PosixFadviseAdvice::POSIX_FADV_DONTNEED; + posix_fadvise(f.as_raw_fd(), offset, len, advice) + } + _ => Err(Errno::ESPIPE), // "Illegal seek" + } + } + + /// The length of the data destination in number of bytes. + /// + /// If it cannot be determined, then this function returns 0. + fn len(&self) -> std::io::Result { + match self { + Self::File(f, _) => Ok(f.metadata()?.len().try_into().unwrap_or(i64::MAX)), + _ => Ok(0), + } + } } /// Decide whether the given buffer is all zeros. @@ -584,6 +668,29 @@ impl<'a> Output<'a> { Ok(Self { dst, settings }) } + /// Discard the system file cache for the given portion of the output. + /// + /// `offset` and `len` specify a contiguous portion of the output. + /// This function informs the kernel that the specified portion of + /// the output file is no longer needed. If not possible, then + /// this function prints an error message to stderr and sets the + /// exit status code to 1. + #[allow(unused_variables)] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) { + #[cfg(target_os = "linux")] + { + show_if_err!(self + .dst + .discard_cache(offset, len) + .map_err_context(|| "failed to discard cache for: 'standard output'".to_string())); + } + #[cfg(target_os = "linux")] + { + // TODO Is there a way to discard filesystem cache on + // these other operating systems? + } + } + /// Write the given bytes one block at a time. /// /// This may write partial blocks (for example, if the underlying From bd18a2a344d67a8b63746cdfa0c9eeba929ada32 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:05:47 -0500 Subject: [PATCH 05/34] dd: support the [io]flag=nocache option Add support for the `iflag=nocache` and `oflag=nocache` to make `dd` discard the filesystem cache for the processed portion of the input or output file. --- src/uu/dd/src/dd.rs | 50 +++++++++++++++++++++++++++ src/uu/dd/src/parseargs.rs | 4 +-- src/uu/dd/src/parseargs/unit_tests.rs | 2 +- tests/by-util/test_dd.rs | 22 ++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 43f0da5df..3b8b3addb 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -785,6 +785,25 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // Optimization: if no blocks are to be written, then don't // bother allocating any buffers. if let Some(Num::Blocks(0) | Num::Bytes(0)) = i.settings.count { + // Even though we are not reading anything from the input + // file, we still need to honor the `nocache` flag, which + // requests that we inform the system that we no longer + // need the contents of the input file in a system cache. + // + // TODO Better error handling for overflowing `len`. + if i.settings.iflags.nocache { + let offset = 0; + let len = i.src.len()?.try_into().unwrap(); + i.discard_cache(offset, len); + } + // Similarly, discard the system cache for the output file. + // + // TODO Better error handling for overflowing `len`. + if i.settings.oflags.nocache { + let offset = 0; + let len = o.dst.len()?.try_into().unwrap(); + o.discard_cache(offset, len); + } return finalize(&mut o, rstat, wstat, start, &prog_tx, output_thread); }; @@ -792,6 +811,13 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // This is the max size needed. let mut buf = vec![BUF_INIT_BYTE; bsize]; + // Index in the input file where we are reading bytes and in + // the output file where we are writing bytes. + // + // These are updated on each iteration of the main loop. + let mut read_offset = 0; + let mut write_offset = 0; + // The main read/write loop. // // Each iteration reads blocks from the input and writes @@ -811,6 +837,30 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { } let wstat_update = o.write_blocks(&buf)?; + // Discard the system file cache for the read portion of + // the input file. + // + // TODO Better error handling for overflowing `offset` and `len`. + let read_len = rstat_update.bytes_total; + if i.settings.iflags.nocache { + let offset = read_offset.try_into().unwrap(); + let len = read_len.try_into().unwrap(); + i.discard_cache(offset, len); + } + read_offset += read_len; + + // Discard the system file cache for the written portion + // of the output file. + // + // TODO Better error handling for overflowing `offset` and `len`. + let write_len = wstat_update.bytes_total; + if o.settings.oflags.nocache { + let offset = write_offset.try_into().unwrap(); + let len = write_len.try_into().unwrap(); + o.discard_cache(offset, len); + } + write_offset += write_len; + // Update the read/write stats and inform the progress thread once per second. // // If the receiver is disconnected, `send()` returns an diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index b9a3baf09..781934a83 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -304,7 +304,7 @@ impl Parser { "directory" => linux_only!(f, i.directory = true), "dsync" => linux_only!(f, i.dsync = true), "sync" => linux_only!(f, i.sync = true), - "nocache" => return Err(ParseError::Unimplemented(f.to_string())), + "nocache" => linux_only!(f, i.nocache = true), "nonblock" => linux_only!(f, i.nonblock = true), "noatime" => linux_only!(f, i.noatime = true), "noctty" => linux_only!(f, i.noctty = true), @@ -336,7 +336,7 @@ impl Parser { "directory" => linux_only!(f, o.directory = true), "dsync" => linux_only!(f, o.dsync = true), "sync" => linux_only!(f, o.sync = true), - "nocache" => return Err(ParseError::Unimplemented(f.to_string())), + "nocache" => linux_only!(f, o.nocache = true), "nonblock" => linux_only!(f, o.nonblock = true), "noatime" => linux_only!(f, o.noatime = true), "noctty" => linux_only!(f, o.noctty = true), diff --git a/src/uu/dd/src/parseargs/unit_tests.rs b/src/uu/dd/src/parseargs/unit_tests.rs index a135c3572..54e17b882 100644 --- a/src/uu/dd/src/parseargs/unit_tests.rs +++ b/src/uu/dd/src/parseargs/unit_tests.rs @@ -55,7 +55,7 @@ fn unimplemented_flags_should_error() { let mut succeeded = Vec::new(); // The following flags are not implemented - for flag in ["cio", "nocache", "nolinks", "text", "binary"] { + for flag in ["cio", "nolinks", "text", "binary"] { let args = vec![format!("iflag={flag}")]; if Parser::new() diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 99eae4809..a54c473ef 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1536,3 +1536,25 @@ fn test_multiple_processes_reading_stdin() { .succeeds() .stdout_only("def\n"); } + +/// Test that discarding system file cache fails for stdin. +#[test] +#[cfg(target_os = "linux")] +fn test_nocache_stdin_error() { + new_ucmd!() + .args(&["iflag=nocache", "count=0", "status=noxfer"]) + .fails() + .code_is(1) + .stderr_only("dd: failed to discard cache for: 'standard input': Illegal seek\n0+0 records in\n0+0 records out\n"); +} + +/// Test for discarding system file cache. +#[test] +#[cfg(target_os = "linux")] +fn test_nocache_file() { + let (at, mut ucmd) = at_and_ucmd!(); + at.write_bytes("f", b"a".repeat(1 << 20).as_slice()); + ucmd.args(&["if=f", "of=/dev/null", "iflag=nocache", "status=noxfer"]) + .succeeds() + .stderr_only("2048+0 records in\n2048+0 records out\n"); +} From 4ff318aee1c28a4a959a35917ca1fa7cec703669 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 7 May 2023 16:33:21 -0400 Subject: [PATCH 06/34] fixup! dd: support the [io]flag=nocache option --- src/uu/dd/src/dd.rs | 2 ++ tests/by-util/test_dd.rs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 3b8b3addb..6727f4bb0 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -793,6 +793,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // TODO Better error handling for overflowing `len`. if i.settings.iflags.nocache { let offset = 0; + #[allow(clippy::useless_conversion)] let len = i.src.len()?.try_into().unwrap(); i.discard_cache(offset, len); } @@ -801,6 +802,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // TODO Better error handling for overflowing `len`. if i.settings.oflags.nocache { let offset = 0; + #[allow(clippy::useless_conversion)] let len = o.dst.len()?.try_into().unwrap(); o.discard_cache(offset, len); } diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index a54c473ef..79b139602 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1541,11 +1541,15 @@ fn test_multiple_processes_reading_stdin() { #[test] #[cfg(target_os = "linux")] fn test_nocache_stdin_error() { + #[cfg(not(target_env = "musl"))] + let detail = "Illegal seek"; + #[cfg(target_env = "musl")] + let detail = "Invalid seek"; new_ucmd!() .args(&["iflag=nocache", "count=0", "status=noxfer"]) .fails() .code_is(1) - .stderr_only("dd: failed to discard cache for: 'standard input': Illegal seek\n0+0 records in\n0+0 records out\n"); + .stderr_only(format!("dd: failed to discard cache for: 'standard input': {detail}\n0+0 records in\n0+0 records out\n")); } /// Test for discarding system file cache. From caf9bfcadc2e2fdfb10a270d9a846c48d545eb8e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 8 May 2023 15:49:56 +0200 Subject: [PATCH 07/34] doc: show a warning when no tldr example --- src/bin/uudoc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 02dafc98a..b7a2ce581 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -216,6 +216,10 @@ impl<'a, 'b> MDWriter<'a, 'b> { } else if let Some(f) = get_zip_content(zip, &format!("pages/linux/{}.md", self.name)) { f } else { + println!( + "Warning: Could not find tldr examples for page '{}'", + self.name + ); return Ok(()); }; From 30c166ad405acd83856b816daf8bf3c3c5bc4e3a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 16:28:38 +0000 Subject: [PATCH 08/34] fix(deps): update rust crate libc to 0.2.144 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9827a7893..aa9cfef09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1318,9 +1318,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.143" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 0623f9e6a..9e87b7a06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,7 +290,7 @@ humantime_to_duration = "0.1.3" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" -libc = "0.2.143" +libc = "0.2.144" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 2df32b614..8693fbfc4 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.143", optional=true } +libc = { version="0.2.144", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 3f40ec4db758f772869a0bcc91fc506f66ed3697 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 9 May 2023 09:44:48 +0200 Subject: [PATCH 09/34] basenc: add help texts for options --- src/uu/basenc/src/basenc.rs | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/uu/basenc/src/basenc.rs b/src/uu/basenc/src/basenc.rs index afc25c736..3ec8cede0 100644 --- a/src/uu/basenc/src/basenc.rs +++ b/src/uu/basenc/src/basenc.rs @@ -24,15 +24,33 @@ use uucore::{help_about, help_usage}; const ABOUT: &str = help_about!("basenc.md"); const USAGE: &str = help_usage!("basenc.md"); -const ENCODINGS: &[(&str, Format)] = &[ - ("base64", Format::Base64), - ("base64url", Format::Base64Url), - ("base32", Format::Base32), - ("base32hex", Format::Base32Hex), - ("base16", Format::Base16), - ("base2lsbf", Format::Base2Lsbf), - ("base2msbf", Format::Base2Msbf), - ("z85", Format::Z85), +const ENCODINGS: &[(&str, Format, &str)] = &[ + ("base64", Format::Base64, "same as 'base64' program"), + ("base64url", Format::Base64Url, "file- and url-safe base64"), + ("base32", Format::Base32, "same as 'base32' program"), + ( + "base32hex", + Format::Base32Hex, + "extended hex alphabet base32", + ), + ("base16", Format::Base16, "hex encoding"), + ( + "base2lsbf", + Format::Base2Lsbf, + "bit string with least significant bit (lsb) first", + ), + ( + "base2msbf", + Format::Base2Msbf, + "bit string with most significant bit (msb) first", + ), + ( + "z85", + Format::Z85, + "ascii85-like encoding;\n\ + when encoding, input length must be a multiple of 4;\n\ + when decoding, input length must be a multiple of 5", + ), ]; pub fn uu_app() -> Command { @@ -41,6 +59,7 @@ pub fn uu_app() -> Command { command = command.arg( Arg::new(encoding.0) .long(encoding.0) + .help(encoding.2) .action(ArgAction::SetTrue), ); } From 6247986a529e3b69eaca75c7daf2c53b149e1e1e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 9 May 2023 10:25:04 +0200 Subject: [PATCH 10/34] docs: add extension (short options with args) --- docs/src/extensions.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/src/extensions.md b/docs/src/extensions.md index 7aaf9db14..281d8ef2e 100644 --- a/docs/src/extensions.md +++ b/docs/src/extensions.md @@ -5,6 +5,21 @@ features that are not supported by GNU coreutils. We take care not to introduce features that are incompatible with the GNU coreutils. Below is a list of uutils extensions. +## General + +GNU coreutils provides two ways to define short options taking an argument: + +``` +$ ls -w 80 +$ ls -w80 +``` + +We support a third way: + +``` +$ ls -w=80 +``` + ## `env` `env` has an additional `-f`/`--file` flag that can parse `.env` files and set From 7983e23d535b4603c935a45f340417e0759d67d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 18:00:46 +0000 Subject: [PATCH 11/34] fix(deps): update rust crate memmap2 to 0.6 --- Cargo.lock | 4 ++-- src/uu/tac/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa9cfef09..00bede9a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1404,9 +1404,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "7f9ff02d2efdc645fca1ee55f45545b996e7da776b5b60c4e170334457551693" dependencies = [ "libc", ] diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 50d83a67c..0d9056915 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -18,7 +18,7 @@ path = "src/tac.rs" [dependencies] memchr = { workspace=true } -memmap2 = "0.5" +memmap2 = "0.6" regex = { workspace=true } clap = { workspace=true } uucore = { workspace=true } From ba6eb392aa44804b1053756df5b93231d49b856f Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 10 May 2023 09:48:32 +0200 Subject: [PATCH 12/34] cksum: split test function into two --- tests/by-util/test_cksum.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 814d4c03a..2384b2ae2 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -33,7 +33,7 @@ fn test_stdin() { } #[test] -fn test_empty() { +fn test_empty_file() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("a"); @@ -62,25 +62,26 @@ fn test_arg_overrides_stdin() { } #[test] -fn test_invalid_file() { - let ts = TestScenario::new(util_name!()); - let at = ts.fixtures.clone(); +fn test_nonexisting_file() { + let file_name = "asdf"; - let folder_name = "asdf"; - - // First check when file doesn't exist - ts.ucmd() - .arg(folder_name) + new_ucmd!() + .arg(file_name) .fails() .no_stdout() - .stderr_contains("cksum: asdf: No such file or directory"); + .stderr_contains(format!("cksum: {file_name}: No such file or directory")); +} - // Then check when the file is of an invalid type +#[test] +fn test_folder() { + let (at, mut ucmd) = at_and_ucmd!(); + + let folder_name = "a_folder"; at.mkdir(folder_name); - ts.ucmd() - .arg(folder_name) + + ucmd.arg(folder_name) .succeeds() - .stdout_only("4294967295 0 asdf\n"); + .stdout_only(format!("4294967295 0 {folder_name}\n")); } // Make sure crc is correct for files larger than 32 bytes From d8f1f1c16cb132c0c2ec525dd8d3bdc4b56d51cc Mon Sep 17 00:00:00 2001 From: leone Date: Wed, 10 May 2023 18:40:58 +0200 Subject: [PATCH 13/34] date: bugfix test_date_for_no_permission_file (#4544) --- tests/by-util/test_date.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index edad87bd6..42a94099d 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -282,6 +282,27 @@ fn test_date_for_invalid_file() { } #[test] +#[cfg(unix)] +fn test_date_for_no_permission_file() { + let (at, mut ucmd) = at_and_ucmd!(); + const FILE: &str = "file-no-perm-1"; + + use std::os::unix::fs::PermissionsExt; + let file = std::fs::OpenOptions::new() + .create(true) + .write(true) + .open(at.plus(FILE)) + .unwrap(); + file.set_permissions(std::fs::Permissions::from_mode(0o222)) + .unwrap(); + let result = ucmd.arg("--file").arg(FILE).fails(); + result.no_stdout(); + assert_eq!( + result.stderr_str().trim(), + format!("date: {FILE}: Permission denied") + ); +} + fn test_date_for_dir_as_file() { let result = new_ucmd!().arg("--file").arg("/").fails(); result.no_stdout(); From 452be5a22005a239008874019d9a0c5fb83ba9ab Mon Sep 17 00:00:00 2001 From: SteveLauC Date: Thu, 11 May 2023 18:58:36 +0800 Subject: [PATCH 14/34] ls: device number for BSDs and solarishOS (#4841) --- src/uu/ls/src/ls.rs | 16 ++++++++++++++-- tests/by-util/test_ls.rs | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index db8024c2e..921987687 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -41,7 +41,13 @@ use unicode_width::UnicodeWidthStr; target_os = "linux", target_os = "macos", target_os = "android", - target_os = "ios" + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" ))] use uucore::libc::{dev_t, major, minor}; #[cfg(unix)] @@ -2716,7 +2722,13 @@ fn display_len_or_rdev(metadata: &Metadata, config: &Config) -> SizeOrDeviceId { target_os = "linux", target_os = "macos", target_os = "android", - target_os = "ios" + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" ))] { let ft = metadata.file_type(); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 84efb9daa..61f6d8d8d 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3393,3 +3393,44 @@ fn test_tabsize_formatting() { .succeeds() .stdout_is("aaaaaaaa bbbb\ncccc dddddddd"); } + +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" +))] +#[test] +fn test_device_number() { + use std::fs::{metadata, read_dir}; + use std::os::unix::fs::{FileTypeExt, MetadataExt}; + use uucore::libc::{dev_t, major, minor}; + + let dev_dir = read_dir("/dev").unwrap(); + // let's use the first device for test + let blk_dev = dev_dir + .map(|res_entry| res_entry.unwrap()) + .find(|entry| { + entry.file_type().unwrap().is_block_device() + || entry.file_type().unwrap().is_char_device() + }) + .expect("Expect a block/char device"); + let blk_dev_path = blk_dev.path(); + let blk_dev_meta = metadata(blk_dev_path.as_path()).unwrap(); + let blk_dev_number = blk_dev_meta.rdev() as dev_t; + let (major, minor) = unsafe { (major(blk_dev_number), minor(blk_dev_number)) }; + let major_minor_str = format!("{}, {}", major, minor); + + let scene = TestScenario::new(util_name!()); + scene + .ucmd() + .arg("-l") + .arg(blk_dev_path.to_str().expect("should be UTF-8 encoded")) + .succeeds() + .stdout_contains(major_minor_str); +} From 0781ad0a65f1d7dc45e4f6cc163db762ecb97037 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 11 May 2023 08:03:12 +0200 Subject: [PATCH 15/34] cksum: fix output of --algorithm for the algorithms md5, sha[1,224,256,384,512], blake2b, and sm3 from to () = to use the same format as GNU cksum --- src/uu/cksum/src/cksum.rs | 10 +- tests/by-util/test_cksum.rs | 110 +++++++----------- .../cksum/blake2b_multiple_files.expected | 2 + .../cksum/blake2b_single_file.expected | 1 + tests/fixtures/cksum/blake2b_stdin.expected | 1 + ...s.expected => crc_multiple_files.expected} | 0 ...file.expected => crc_single_file.expected} | 0 .../{stdin.expected => crc_stdin.expected} | 0 .../cksum/md5_multiple_files.expected | 2 + tests/fixtures/cksum/md5_single_file.expected | 1 + tests/fixtures/cksum/md5_stdin.expected | 1 + .../cksum/sha1_multiple_files.expected | 2 + .../fixtures/cksum/sha1_single_file.expected | 1 + tests/fixtures/cksum/sha1_stdin.expected | 1 + .../cksum/sha224_multiple_files.expected | 2 + .../cksum/sha224_single_file.expected | 1 + tests/fixtures/cksum/sha224_stdin.expected | 1 + .../cksum/sha256_multiple_files.expected | 2 + .../cksum/sha256_single_file.expected | 1 + tests/fixtures/cksum/sha256_stdin.expected | 1 + .../cksum/sha384_multiple_files.expected | 2 + .../cksum/sha384_single_file.expected | 1 + tests/fixtures/cksum/sha384_stdin.expected | 1 + .../cksum/sha512_multiple_files.expected | 2 + .../cksum/sha512_single_file.expected | 1 + tests/fixtures/cksum/sha512_stdin.expected | 1 + .../cksum/sm3_multiple_files.expected | 2 + tests/fixtures/cksum/sm3_single_file.expected | 1 + tests/fixtures/cksum/sm3_stdin.expected | 1 + 29 files changed, 79 insertions(+), 73 deletions(-) create mode 100644 tests/fixtures/cksum/blake2b_multiple_files.expected create mode 100644 tests/fixtures/cksum/blake2b_single_file.expected create mode 100644 tests/fixtures/cksum/blake2b_stdin.expected rename tests/fixtures/cksum/{multiple_files.expected => crc_multiple_files.expected} (100%) rename tests/fixtures/cksum/{single_file.expected => crc_single_file.expected} (100%) rename tests/fixtures/cksum/{stdin.expected => crc_stdin.expected} (100%) create mode 100644 tests/fixtures/cksum/md5_multiple_files.expected create mode 100644 tests/fixtures/cksum/md5_single_file.expected create mode 100644 tests/fixtures/cksum/md5_stdin.expected create mode 100644 tests/fixtures/cksum/sha1_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha1_single_file.expected create mode 100644 tests/fixtures/cksum/sha1_stdin.expected create mode 100644 tests/fixtures/cksum/sha224_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha224_single_file.expected create mode 100644 tests/fixtures/cksum/sha224_stdin.expected create mode 100644 tests/fixtures/cksum/sha256_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha256_single_file.expected create mode 100644 tests/fixtures/cksum/sha256_stdin.expected create mode 100644 tests/fixtures/cksum/sha384_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha384_single_file.expected create mode 100644 tests/fixtures/cksum/sha384_stdin.expected create mode 100644 tests/fixtures/cksum/sha512_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha512_single_file.expected create mode 100644 tests/fixtures/cksum/sha512_stdin.expected create mode 100644 tests/fixtures/cksum/sm3_multiple_files.expected create mode 100644 tests/fixtures/cksum/sm3_single_file.expected create mode 100644 tests/fixtures/cksum/sm3_stdin.expected diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 9bddd3d7a..5a8cec5ea 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -159,8 +159,14 @@ where div_ceil(sz, options.output_bits), filename.display() ), - (_, true) => println!("{sum} {sz}"), - (_, false) => println!("{sum} {sz} {}", filename.display()), + (ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"), + (ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()), + (ALGORITHM_OPTIONS_BLAKE2B, _) => println!("BLAKE2b ({}) = {sum}", filename.display()), + _ => println!( + "{} ({}) = {sum}", + options.algo_name.to_ascii_uppercase(), + filename.display() + ), } } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 2384b2ae2..28c978ba6 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -1,7 +1,11 @@ -// spell-checker:ignore (words) asdf +// spell-checker:ignore (words) asdf algo algos use crate::common::util::TestScenario; +const ALGOS: [&str; 11] = [ + "sysv", "bsd", "crc", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "sm3", +]; + #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); @@ -12,7 +16,7 @@ fn test_single_file() { new_ucmd!() .arg("lorem_ipsum.txt") .succeeds() - .stdout_is_fixture("single_file.expected"); + .stdout_is_fixture("crc_single_file.expected"); } #[test] @@ -21,7 +25,7 @@ fn test_multiple_files() { .arg("lorem_ipsum.txt") .arg("alice_in_wonderland.txt") .succeeds() - .stdout_is_fixture("multiple_files.expected"); + .stdout_is_fixture("crc_multiple_files.expected"); } #[test] @@ -29,7 +33,7 @@ fn test_stdin() { new_ucmd!() .pipe_in_fixture("lorem_ipsum.txt") .succeeds() - .stdout_is_fixture("stdin.expected"); + .stdout_is_fixture("crc_stdin.expected"); } #[test] @@ -117,77 +121,41 @@ fn test_stdin_larger_than_128_bytes() { } #[test] -fn test_sha1_single_file() { - new_ucmd!() - .arg("-a=sha1") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_is("ab1dd0bae1d8883a3d18a66de6afbd28252cfbef 772 lorem_ipsum.txt\n"); +fn test_algorithm_single_file() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_single_file.expected")); + } + } } #[test] -fn test_sm3_single_file() { - new_ucmd!() - .arg("-a=sm3") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_is( - "6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 772 lorem_ipsum.txt\n", - ); +fn test_algorithm_multiple_files() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_multiple_files.expected")); + } + } } #[test] -fn test_bsd_single_file() { - new_ucmd!() - .arg("-a=bsd") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("bsd_single_file.expected"); -} - -#[test] -fn test_bsd_multiple_files() { - new_ucmd!() - .arg("-a=bsd") - .arg("lorem_ipsum.txt") - .arg("alice_in_wonderland.txt") - .succeeds() - .stdout_only_fixture("bsd_multiple_files.expected"); -} - -#[test] -fn test_bsd_stdin() { - new_ucmd!() - .arg("-a=bsd") - .pipe_in_fixture("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("bsd_stdin.expected"); -} - -#[test] -fn test_sysv_single_file() { - new_ucmd!() - .arg("-a=sysv") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("sysv_single_file.expected"); -} - -#[test] -fn test_sysv_multiple_files() { - new_ucmd!() - .arg("-a=sysv") - .arg("lorem_ipsum.txt") - .arg("alice_in_wonderland.txt") - .succeeds() - .stdout_only_fixture("sysv_multiple_files.expected"); -} - -#[test] -fn test_sysv_stdin() { - new_ucmd!() - .arg("-a=sysv") - .pipe_in_fixture("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("sysv_stdin.expected"); +fn test_algorithm_stdin() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_stdin.expected")); + } + } } diff --git a/tests/fixtures/cksum/blake2b_multiple_files.expected b/tests/fixtures/cksum/blake2b_multiple_files.expected new file mode 100644 index 000000000..97d06eb6f --- /dev/null +++ b/tests/fixtures/cksum/blake2b_multiple_files.expected @@ -0,0 +1,2 @@ +BLAKE2b (lorem_ipsum.txt) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 +BLAKE2b (alice_in_wonderland.txt) = 91b8b0f0868e905ad18b8ac35e4a1dacd289857b19258ab5d1e071761af758b0134ec152d4f011fe1825ca889c80c2e072ca70eb50548c25fc49a98937515af4 diff --git a/tests/fixtures/cksum/blake2b_single_file.expected b/tests/fixtures/cksum/blake2b_single_file.expected new file mode 100644 index 000000000..64ede7ca0 --- /dev/null +++ b/tests/fixtures/cksum/blake2b_single_file.expected @@ -0,0 +1 @@ +BLAKE2b (lorem_ipsum.txt) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 diff --git a/tests/fixtures/cksum/blake2b_stdin.expected b/tests/fixtures/cksum/blake2b_stdin.expected new file mode 100644 index 000000000..15c34ea77 --- /dev/null +++ b/tests/fixtures/cksum/blake2b_stdin.expected @@ -0,0 +1 @@ +BLAKE2b (-) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 diff --git a/tests/fixtures/cksum/multiple_files.expected b/tests/fixtures/cksum/crc_multiple_files.expected similarity index 100% rename from tests/fixtures/cksum/multiple_files.expected rename to tests/fixtures/cksum/crc_multiple_files.expected diff --git a/tests/fixtures/cksum/single_file.expected b/tests/fixtures/cksum/crc_single_file.expected similarity index 100% rename from tests/fixtures/cksum/single_file.expected rename to tests/fixtures/cksum/crc_single_file.expected diff --git a/tests/fixtures/cksum/stdin.expected b/tests/fixtures/cksum/crc_stdin.expected similarity index 100% rename from tests/fixtures/cksum/stdin.expected rename to tests/fixtures/cksum/crc_stdin.expected diff --git a/tests/fixtures/cksum/md5_multiple_files.expected b/tests/fixtures/cksum/md5_multiple_files.expected new file mode 100644 index 000000000..54023e761 --- /dev/null +++ b/tests/fixtures/cksum/md5_multiple_files.expected @@ -0,0 +1,2 @@ +MD5 (lorem_ipsum.txt) = cd724690f7dc61775dfac400a71f2caa +MD5 (alice_in_wonderland.txt) = f6fa7033e16166a9589aa1c0388ffd58 diff --git a/tests/fixtures/cksum/md5_single_file.expected b/tests/fixtures/cksum/md5_single_file.expected new file mode 100644 index 000000000..5975053d1 --- /dev/null +++ b/tests/fixtures/cksum/md5_single_file.expected @@ -0,0 +1 @@ +MD5 (lorem_ipsum.txt) = cd724690f7dc61775dfac400a71f2caa diff --git a/tests/fixtures/cksum/md5_stdin.expected b/tests/fixtures/cksum/md5_stdin.expected new file mode 100644 index 000000000..b3b1090bc --- /dev/null +++ b/tests/fixtures/cksum/md5_stdin.expected @@ -0,0 +1 @@ +MD5 (-) = cd724690f7dc61775dfac400a71f2caa diff --git a/tests/fixtures/cksum/sha1_multiple_files.expected b/tests/fixtures/cksum/sha1_multiple_files.expected new file mode 100644 index 000000000..f20ea9471 --- /dev/null +++ b/tests/fixtures/cksum/sha1_multiple_files.expected @@ -0,0 +1,2 @@ +SHA1 (lorem_ipsum.txt) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef +SHA1 (alice_in_wonderland.txt) = 22b54b2520e8b4fa59eb10719028a4e587c12d1e diff --git a/tests/fixtures/cksum/sha1_single_file.expected b/tests/fixtures/cksum/sha1_single_file.expected new file mode 100644 index 000000000..1b820559f --- /dev/null +++ b/tests/fixtures/cksum/sha1_single_file.expected @@ -0,0 +1 @@ +SHA1 (lorem_ipsum.txt) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef diff --git a/tests/fixtures/cksum/sha1_stdin.expected b/tests/fixtures/cksum/sha1_stdin.expected new file mode 100644 index 000000000..ced9ce80d --- /dev/null +++ b/tests/fixtures/cksum/sha1_stdin.expected @@ -0,0 +1 @@ +SHA1 (-) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef diff --git a/tests/fixtures/cksum/sha224_multiple_files.expected b/tests/fixtures/cksum/sha224_multiple_files.expected new file mode 100644 index 000000000..0d6b45b10 --- /dev/null +++ b/tests/fixtures/cksum/sha224_multiple_files.expected @@ -0,0 +1,2 @@ +SHA224 (lorem_ipsum.txt) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 +SHA224 (alice_in_wonderland.txt) = 54c9c7d78458886418ce0845111fc49fe1c628ffd4bf3da14226ffd9 diff --git a/tests/fixtures/cksum/sha224_single_file.expected b/tests/fixtures/cksum/sha224_single_file.expected new file mode 100644 index 000000000..a08d66bb4 --- /dev/null +++ b/tests/fixtures/cksum/sha224_single_file.expected @@ -0,0 +1 @@ +SHA224 (lorem_ipsum.txt) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 diff --git a/tests/fixtures/cksum/sha224_stdin.expected b/tests/fixtures/cksum/sha224_stdin.expected new file mode 100644 index 000000000..1bd138698 --- /dev/null +++ b/tests/fixtures/cksum/sha224_stdin.expected @@ -0,0 +1 @@ +SHA224 (-) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 diff --git a/tests/fixtures/cksum/sha256_multiple_files.expected b/tests/fixtures/cksum/sha256_multiple_files.expected new file mode 100644 index 000000000..e6fd8beb5 --- /dev/null +++ b/tests/fixtures/cksum/sha256_multiple_files.expected @@ -0,0 +1,2 @@ +SHA256 (lorem_ipsum.txt) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 +SHA256 (alice_in_wonderland.txt) = 14ab7e5a0aa3a670222744714bc96961d51012cb216225d965db71824a46e5fe diff --git a/tests/fixtures/cksum/sha256_single_file.expected b/tests/fixtures/cksum/sha256_single_file.expected new file mode 100644 index 000000000..e16abcb0f --- /dev/null +++ b/tests/fixtures/cksum/sha256_single_file.expected @@ -0,0 +1 @@ +SHA256 (lorem_ipsum.txt) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 diff --git a/tests/fixtures/cksum/sha256_stdin.expected b/tests/fixtures/cksum/sha256_stdin.expected new file mode 100644 index 000000000..87bd84195 --- /dev/null +++ b/tests/fixtures/cksum/sha256_stdin.expected @@ -0,0 +1 @@ +SHA256 (-) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 diff --git a/tests/fixtures/cksum/sha384_multiple_files.expected b/tests/fixtures/cksum/sha384_multiple_files.expected new file mode 100644 index 000000000..a5a3324a2 --- /dev/null +++ b/tests/fixtures/cksum/sha384_multiple_files.expected @@ -0,0 +1,2 @@ +SHA384 (lorem_ipsum.txt) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb +SHA384 (alice_in_wonderland.txt) = b7966c97ef84ab5858db2e0cdd33fbaf4fa8346d84de65aba001e738c242598a43272854d0073ad1099404eaa1d93766 diff --git a/tests/fixtures/cksum/sha384_single_file.expected b/tests/fixtures/cksum/sha384_single_file.expected new file mode 100644 index 000000000..8d673e60b --- /dev/null +++ b/tests/fixtures/cksum/sha384_single_file.expected @@ -0,0 +1 @@ +SHA384 (lorem_ipsum.txt) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb diff --git a/tests/fixtures/cksum/sha384_stdin.expected b/tests/fixtures/cksum/sha384_stdin.expected new file mode 100644 index 000000000..3c0d5c818 --- /dev/null +++ b/tests/fixtures/cksum/sha384_stdin.expected @@ -0,0 +1 @@ +SHA384 (-) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb diff --git a/tests/fixtures/cksum/sha512_multiple_files.expected b/tests/fixtures/cksum/sha512_multiple_files.expected new file mode 100644 index 000000000..0f533b27c --- /dev/null +++ b/tests/fixtures/cksum/sha512_multiple_files.expected @@ -0,0 +1,2 @@ +SHA512 (lorem_ipsum.txt) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 +SHA512 (alice_in_wonderland.txt) = 251646d5a7eb481e0f3aced7839d78dd5e97153f822dc55938e17059c485990d85d602e2881b528b565ab6262584a69c97b068b26bda81acc9356c53c7c1c96d diff --git a/tests/fixtures/cksum/sha512_single_file.expected b/tests/fixtures/cksum/sha512_single_file.expected new file mode 100644 index 000000000..e9a02c96a --- /dev/null +++ b/tests/fixtures/cksum/sha512_single_file.expected @@ -0,0 +1 @@ +SHA512 (lorem_ipsum.txt) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 diff --git a/tests/fixtures/cksum/sha512_stdin.expected b/tests/fixtures/cksum/sha512_stdin.expected new file mode 100644 index 000000000..8321c4cc3 --- /dev/null +++ b/tests/fixtures/cksum/sha512_stdin.expected @@ -0,0 +1 @@ +SHA512 (-) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 diff --git a/tests/fixtures/cksum/sm3_multiple_files.expected b/tests/fixtures/cksum/sm3_multiple_files.expected new file mode 100644 index 000000000..eae2cde2f --- /dev/null +++ b/tests/fixtures/cksum/sm3_multiple_files.expected @@ -0,0 +1,2 @@ +SM3 (lorem_ipsum.txt) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 +SM3 (alice_in_wonderland.txt) = d66617ae3c4e87828298dcd836f79efbab488c53b84e09c3e8e83a16c902418d diff --git a/tests/fixtures/cksum/sm3_single_file.expected b/tests/fixtures/cksum/sm3_single_file.expected new file mode 100644 index 000000000..cf4b8304a --- /dev/null +++ b/tests/fixtures/cksum/sm3_single_file.expected @@ -0,0 +1 @@ +SM3 (lorem_ipsum.txt) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 diff --git a/tests/fixtures/cksum/sm3_stdin.expected b/tests/fixtures/cksum/sm3_stdin.expected new file mode 100644 index 000000000..436fcfb41 --- /dev/null +++ b/tests/fixtures/cksum/sm3_stdin.expected @@ -0,0 +1 @@ +SM3 (-) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 From 7a31d841ba9b2237c5536852395b7c59c6887411 Mon Sep 17 00:00:00 2001 From: John Shin <51249639+shinhs0506@users.noreply.github.com> Date: Thu, 11 May 2023 07:44:23 -0700 Subject: [PATCH 16/34] cp: preserve permission on -p --parents (#4853) --- src/uu/cp/src/cp.rs | 26 ++++++++++++++++++++++++++ tests/by-util/test_cp.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 3e69e5791..642bbcb14 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1704,6 +1704,11 @@ fn copy_file( } copy_attributes(source, dest, &options.attributes)?; + if options.parents && should_preserve_attribute(options) { + for (x, y) in aligned_ancestors(source, dest) { + copy_attributes(x, y, &options.attributes)?; + } + } if let Some(progress_bar) = progress_bar { progress_bar.inc(fs::metadata(source)?.len()); @@ -1753,6 +1758,27 @@ fn copy_helper( Ok(()) } +fn should_preserve_attribute(options: &Options) -> bool { + let checks = [ + &options.attributes.mode, + &options.attributes.timestamps, + &options.attributes.links, + &options.attributes.context, + &options.attributes.xattr, + ]; + + #[cfg(unix)] + let checks = [ + checks.as_slice(), + [&options.attributes.ownership].as_slice(), + ] + .concat(); + + checks + .iter() + .any(|attr| matches!(attr, Preserve::Yes { .. })) +} + // "Copies" a FIFO by creating a new one. This workaround is because Rust's // built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390). #[cfg(unix)] diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 0a6e58049..27c996f1b 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1075,6 +1075,46 @@ fn test_cp_parents_dest_not_directory() { .stderr_contains("with --parents, the destination must be a directory"); } +#[test] +fn test_cp_parents_with_permissions_copy_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dir = "dir"; + let file = "p1/p2/file"; + + at.mkdir(dir); + at.mkdir_all("p1/p2"); + at.touch(file); + + let p1_mode = 0o0777; + let p2_mode = 0o0711; + let file_mode = 0o0702; + + #[cfg(unix)] + { + at.set_mode("p1", p1_mode); + at.set_mode("p1/p2", p2_mode); + at.set_mode(file, file_mode); + } + + ucmd.arg("-p") + .arg("--parents") + .arg(file) + .arg(dir) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + let p1_metadata = at.metadata("p1"); + let p2_metadata = at.metadata("p1/p2"); + let file_metadata = at.metadata(file); + + assert_metadata_eq!(p1_metadata, at.metadata("dir/p1")); + assert_metadata_eq!(p2_metadata, at.metadata("dir/p1/p2")); + assert_metadata_eq!(file_metadata, at.metadata("dir/p1/p2/file")); + } +} + #[test] #[cfg(unix)] fn test_cp_writable_special_file_permissions() { From 536d12d20d7ab3ce2237de75eb82342cddb7088c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 11 May 2023 18:19:49 +0200 Subject: [PATCH 17/34] simplify code Co-authored-by: Daniel Hofstetter --- tests/by-util/test_tee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 41751f266..51d552d67 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -119,7 +119,7 @@ mod linux_only { let mut fds: [c_int; 2] = [0, 0]; assert!( - !(unsafe { libc::pipe(&mut fds as *mut c_int) } != 0), + (unsafe { libc::pipe(&mut fds as *mut c_int) } == 0), "Failed to create pipe" ); From d98293bdaacedb90afd7a1d61b2a9e83f2678471 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 11 May 2023 18:20:28 +0200 Subject: [PATCH 18/34] bring back the empty line --- tests/by-util/test_cp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 12dd625c8..22e5fbea2 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1392,6 +1392,7 @@ fn test_cp_target_file_dev_null() { fn test_cp_one_file_system() { use crate::common::util::AtPath; use walkdir::WalkDir; + let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; From 133ff41d813dd171cfef9cbedb3e945cbb8d5879 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 16:56:57 +0000 Subject: [PATCH 19/34] chore(deps): update rust crate humantime_to_duration to 0.2.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00bede9a3..a92292f64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,9 +1156,9 @@ dependencies = [ [[package]] name = "humantime_to_duration" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46276b15cd421d8262968eb5c3a075ae4a40bd787762ca0ddfead00fd5f6fbce" +checksum = "bcf364c7a07c8beae52fdab733304ceceeb9213f4137d938a17bae365a0136f9" dependencies = [ "regex", "time", diff --git a/Cargo.toml b/Cargo.toml index 9e87b7a06..243487096 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.1.3" +humantime_to_duration = "0.2.0" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" From 9415c6c8cc72aa347c59fb714bec29a9fe3fc871 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 14:50:22 +0000 Subject: [PATCH 20/34] chore(deps): update rust crate humantime_to_duration to 0.2.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c4815bee..5f8bddf94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,9 +1156,9 @@ dependencies = [ [[package]] name = "humantime_to_duration" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf364c7a07c8beae52fdab733304ceceeb9213f4137d938a17bae365a0136f9" +checksum = "714764645f21cc70c4c151d7798dd158409641f37ad820bed65224aae403cbed" dependencies = [ "regex", "time", diff --git a/Cargo.toml b/Cargo.toml index 243487096..c5d2a760b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.2.0" +humantime_to_duration = "0.2.1" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" From a817186e1073b659a5a05b6031d2fa72608ce163 Mon Sep 17 00:00:00 2001 From: John Shin Date: Fri, 12 May 2023 09:19:27 -0700 Subject: [PATCH 21/34] cp: preserve permissions on -r -p --parents --- src/uu/cp/src/copydir.rs | 12 +++++++++++- src/uu/cp/src/cp.rs | 36 ++++++++-------------------------- tests/by-util/test_cp.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/uu/cp/src/copydir.rs b/src/uu/cp/src/copydir.rs index c312b7cbb..aaeb73f5a 100644 --- a/src/uu/cp/src/copydir.rs +++ b/src/uu/cp/src/copydir.rs @@ -404,8 +404,18 @@ pub(crate) fn copy_directory( Err(e) => show_error!("{}", e), } } + // Copy the attributes from the root directory to the target directory. - copy_attributes(root, target, &options.attributes)?; + if options.parents { + let dest = target.join(root.file_name().unwrap()); + copy_attributes(root, dest.as_path(), &options.attributes)?; + for (x, y) in aligned_ancestors(root, dest.as_path()) { + copy_attributes(x, y, &options.attributes)?; + } + } else { + copy_attributes(root, target, &options.attributes)?; + } + Ok(()) } diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 642bbcb14..f7069f04f 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1151,14 +1151,20 @@ fn copy_source( } else { // Copy as file let dest = construct_dest_path(source_path, target, target_type, options)?; - copy_file( + let res = copy_file( progress_bar, source_path, dest.as_path(), options, symlinked_files, true, - ) + ); + if options.parents { + for (x, y) in aligned_ancestors(source, dest.as_path()) { + copy_attributes(x, y, &options.attributes)?; + } + } + res } } @@ -1704,11 +1710,6 @@ fn copy_file( } copy_attributes(source, dest, &options.attributes)?; - if options.parents && should_preserve_attribute(options) { - for (x, y) in aligned_ancestors(source, dest) { - copy_attributes(x, y, &options.attributes)?; - } - } if let Some(progress_bar) = progress_bar { progress_bar.inc(fs::metadata(source)?.len()); @@ -1758,27 +1759,6 @@ fn copy_helper( Ok(()) } -fn should_preserve_attribute(options: &Options) -> bool { - let checks = [ - &options.attributes.mode, - &options.attributes.timestamps, - &options.attributes.links, - &options.attributes.context, - &options.attributes.xattr, - ]; - - #[cfg(unix)] - let checks = [ - checks.as_slice(), - [&options.attributes.ownership].as_slice(), - ] - .concat(); - - checks - .iter() - .any(|attr| matches!(attr, Preserve::Yes { .. })) -} - // "Copies" a FIFO by creating a new one. This workaround is because Rust's // built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390). #[cfg(unix)] diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 86fbf9dcc..ef35f6c2d 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1115,6 +1115,48 @@ fn test_cp_parents_with_permissions_copy_file() { } } +#[test] +fn test_cp_parents_with_permissions_copy_dir() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dir1 = "dir"; + let dir2 = "p1/p2"; + let file = "p1/p2/file"; + + at.mkdir(dir1); + at.mkdir_all(dir2); + at.touch(file); + + let p1_mode = 0o0777; + let p2_mode = 0o0711; + let file_mode = 0o0702; + + #[cfg(unix)] + { + at.set_mode("p1", p1_mode); + at.set_mode("p1/p2", p2_mode); + at.set_mode(file, file_mode); + } + + ucmd.arg("-p") + .arg("--parents") + .arg("-r") + .arg(dir2) + .arg(dir1) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + let p1_metadata = at.metadata("p1"); + let p2_metadata = at.metadata("p1/p2"); + let file_metadata = at.metadata(file); + + assert_metadata_eq!(p1_metadata, at.metadata("dir/p1")); + assert_metadata_eq!(p2_metadata, at.metadata("dir/p1/p2")); + assert_metadata_eq!(file_metadata, at.metadata("dir/p1/p2/file")); + } +} + #[test] #[cfg(unix)] fn test_cp_writable_special_file_permissions() { From 690fff2fc9514391d4921a441795445cd2bd0aaa Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 14 May 2023 16:10:46 +0200 Subject: [PATCH 22/34] cksum: implement --untagged --- src/uu/cksum/src/cksum.rs | 35 +++++++--- tests/by-util/test_cksum.rs | 65 +++++++++++++++++++ .../untagged/blake2b_multiple_files.expected | 2 + .../untagged/blake2b_single_file.expected | 1 + .../cksum/untagged/blake2b_stdin.expected | 1 + .../untagged/bsd_multiple_files.expected | 2 + .../cksum/untagged/bsd_single_file.expected | 1 + .../cksum/untagged/bsd_stdin.expected | 1 + .../untagged/crc_multiple_files.expected | 2 + .../cksum/untagged/crc_single_file.expected | 1 + .../cksum/untagged/crc_stdin.expected | 1 + .../untagged/md5_multiple_files.expected | 2 + .../cksum/untagged/md5_single_file.expected | 1 + .../cksum/untagged/md5_stdin.expected | 1 + .../untagged/sha1_multiple_files.expected | 2 + .../cksum/untagged/sha1_single_file.expected | 1 + .../cksum/untagged/sha1_stdin.expected | 1 + .../untagged/sha224_multiple_files.expected | 2 + .../untagged/sha224_single_file.expected | 1 + .../cksum/untagged/sha224_stdin.expected | 1 + .../untagged/sha256_multiple_files.expected | 2 + .../untagged/sha256_single_file.expected | 1 + .../cksum/untagged/sha256_stdin.expected | 1 + .../untagged/sha384_multiple_files.expected | 2 + .../untagged/sha384_single_file.expected | 1 + .../cksum/untagged/sha384_stdin.expected | 1 + .../untagged/sha512_multiple_files.expected | 2 + .../untagged/sha512_single_file.expected | 1 + .../cksum/untagged/sha512_stdin.expected | 1 + .../untagged/sm3_multiple_files.expected | 2 + .../cksum/untagged/sm3_single_file.expected | 1 + .../cksum/untagged/sm3_stdin.expected | 1 + .../untagged/sysv_multiple_files.expected | 2 + .../cksum/untagged/sysv_single_file.expected | 1 + .../cksum/untagged/sysv_stdin.expected | 1 + 35 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/cksum/untagged/blake2b_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/blake2b_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/blake2b_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/crc_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/crc_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/crc_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/md5_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/md5_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/md5_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_stdin.expected diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 5a8cec5ea..a46f69302 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -6,7 +6,7 @@ // file that was distributed with this source code. // spell-checker:ignore (ToDO) fname, algo -use clap::{crate_version, Arg, Command}; +use clap::{crate_version, Arg, ArgAction, Command}; use hex::encode; use std::ffi::OsStr; use std::fs::File; @@ -103,6 +103,7 @@ struct Options { algo_name: &'static str, digest: Box, output_bits: usize, + untagged: bool, } /// Calculate checksum @@ -161,12 +162,20 @@ where ), (ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"), (ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()), - (ALGORITHM_OPTIONS_BLAKE2B, _) => println!("BLAKE2b ({}) = {sum}", filename.display()), - _ => println!( - "{} ({}) = {sum}", - options.algo_name.to_ascii_uppercase(), - filename.display() - ), + (ALGORITHM_OPTIONS_BLAKE2B, _) if !options.untagged => { + println!("BLAKE2b ({}) = {sum}", filename.display()); + } + _ => { + if options.untagged { + println!("{sum} {}", filename.display()); + } else { + println!( + "{} ({}) = {sum}", + options.algo_name.to_ascii_uppercase(), + filename.display() + ); + } + } } } @@ -208,8 +217,9 @@ fn digest_read( } mod options { - pub static FILE: &str = "file"; - pub static ALGORITHM: &str = "algorithm"; + pub const ALGORITHM: &str = "algorithm"; + pub const FILE: &str = "file"; + pub const UNTAGGED: &str = "untagged"; } #[uucore::main] @@ -228,6 +238,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { algo_name: name, digest: algo, output_bits: bits, + untagged: matches.get_flag(options::UNTAGGED), }; match matches.get_many::(options::FILE) { @@ -270,5 +281,11 @@ pub fn uu_app() -> Command { ALGORITHM_OPTIONS_SM3, ]), ) + .arg( + Arg::new(options::UNTAGGED) + .long(options::UNTAGGED) + .help("create a reversed style checksum, without digest type") + .action(ArgAction::SetTrue), + ) .after_help(AFTER_HELP) } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 28c978ba6..41ddc2ee0 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -159,3 +159,68 @@ fn test_algorithm_stdin() { } } } + +#[test] +fn test_untagged_single_file() { + new_ucmd!() + .arg("--untagged") + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_single_file.expected"); +} + +#[test] +fn test_untagged_multiple_files() { + new_ucmd!() + .arg("--untagged") + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_multiple_files.expected"); +} + +#[test] +fn test_untagged_stdin() { + new_ucmd!() + .arg("--untagged") + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_stdin.expected"); +} + +#[test] +fn test_untagged_algorithm_single_file() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_single_file.expected")); + } +} + +#[test] +fn test_untagged_algorithm_multiple_files() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_multiple_files.expected")); + } +} + +#[test] +fn test_untagged_algorithm_stdin() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_stdin.expected")); + } +} diff --git a/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected b/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected new file mode 100644 index 000000000..7c68c8573 --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected @@ -0,0 +1,2 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 lorem_ipsum.txt +91b8b0f0868e905ad18b8ac35e4a1dacd289857b19258ab5d1e071761af758b0134ec152d4f011fe1825ca889c80c2e072ca70eb50548c25fc49a98937515af4 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/blake2b_single_file.expected b/tests/fixtures/cksum/untagged/blake2b_single_file.expected new file mode 100644 index 000000000..1f5444c87 --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_single_file.expected @@ -0,0 +1 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/blake2b_stdin.expected b/tests/fixtures/cksum/untagged/blake2b_stdin.expected new file mode 100644 index 000000000..0892bff36 --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_stdin.expected @@ -0,0 +1 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 - diff --git a/tests/fixtures/cksum/untagged/bsd_multiple_files.expected b/tests/fixtures/cksum/untagged/bsd_multiple_files.expected new file mode 100644 index 000000000..941a2a512 --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_multiple_files.expected @@ -0,0 +1,2 @@ +08109 1 lorem_ipsum.txt +01814 1 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/bsd_single_file.expected b/tests/fixtures/cksum/untagged/bsd_single_file.expected new file mode 100644 index 000000000..293ada3bd --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_single_file.expected @@ -0,0 +1 @@ +08109 1 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/bsd_stdin.expected b/tests/fixtures/cksum/untagged/bsd_stdin.expected new file mode 100644 index 000000000..4843ba082 --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_stdin.expected @@ -0,0 +1 @@ +08109 1 diff --git a/tests/fixtures/cksum/untagged/crc_multiple_files.expected b/tests/fixtures/cksum/untagged/crc_multiple_files.expected new file mode 100644 index 000000000..d7a4f5b4f --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_multiple_files.expected @@ -0,0 +1,2 @@ +378294376 772 lorem_ipsum.txt +3805907707 302 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/crc_single_file.expected b/tests/fixtures/cksum/untagged/crc_single_file.expected new file mode 100644 index 000000000..e9fc1ca7c --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_single_file.expected @@ -0,0 +1 @@ +378294376 772 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/crc_stdin.expected b/tests/fixtures/cksum/untagged/crc_stdin.expected new file mode 100644 index 000000000..28b37d0be --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_stdin.expected @@ -0,0 +1 @@ +378294376 772 diff --git a/tests/fixtures/cksum/untagged/md5_multiple_files.expected b/tests/fixtures/cksum/untagged/md5_multiple_files.expected new file mode 100644 index 000000000..4b63cbff7 --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_multiple_files.expected @@ -0,0 +1,2 @@ +cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt +f6fa7033e16166a9589aa1c0388ffd58 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/md5_single_file.expected b/tests/fixtures/cksum/untagged/md5_single_file.expected new file mode 100644 index 000000000..ca9eb6785 --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_single_file.expected @@ -0,0 +1 @@ +cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/md5_stdin.expected b/tests/fixtures/cksum/untagged/md5_stdin.expected new file mode 100644 index 000000000..f4094dcc7 --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_stdin.expected @@ -0,0 +1 @@ +cd724690f7dc61775dfac400a71f2caa - diff --git a/tests/fixtures/cksum/untagged/sha1_multiple_files.expected b/tests/fixtures/cksum/untagged/sha1_multiple_files.expected new file mode 100644 index 000000000..1712c7409 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_multiple_files.expected @@ -0,0 +1,2 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef lorem_ipsum.txt +22b54b2520e8b4fa59eb10719028a4e587c12d1e alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha1_single_file.expected b/tests/fixtures/cksum/untagged/sha1_single_file.expected new file mode 100644 index 000000000..c8e8ddca6 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_single_file.expected @@ -0,0 +1 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha1_stdin.expected b/tests/fixtures/cksum/untagged/sha1_stdin.expected new file mode 100644 index 000000000..2396ed481 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_stdin.expected @@ -0,0 +1 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef - diff --git a/tests/fixtures/cksum/untagged/sha224_multiple_files.expected b/tests/fixtures/cksum/untagged/sha224_multiple_files.expected new file mode 100644 index 000000000..3eb2b500a --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_multiple_files.expected @@ -0,0 +1,2 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 lorem_ipsum.txt +54c9c7d78458886418ce0845111fc49fe1c628ffd4bf3da14226ffd9 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha224_single_file.expected b/tests/fixtures/cksum/untagged/sha224_single_file.expected new file mode 100644 index 000000000..c5ab1f7d1 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_single_file.expected @@ -0,0 +1 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha224_stdin.expected b/tests/fixtures/cksum/untagged/sha224_stdin.expected new file mode 100644 index 000000000..691e451b3 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_stdin.expected @@ -0,0 +1 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 - diff --git a/tests/fixtures/cksum/untagged/sha256_multiple_files.expected b/tests/fixtures/cksum/untagged/sha256_multiple_files.expected new file mode 100644 index 000000000..a57fa2eaf --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_multiple_files.expected @@ -0,0 +1,2 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 lorem_ipsum.txt +14ab7e5a0aa3a670222744714bc96961d51012cb216225d965db71824a46e5fe alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha256_single_file.expected b/tests/fixtures/cksum/untagged/sha256_single_file.expected new file mode 100644 index 000000000..1b1be9516 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_single_file.expected @@ -0,0 +1 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha256_stdin.expected b/tests/fixtures/cksum/untagged/sha256_stdin.expected new file mode 100644 index 000000000..998db6c66 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_stdin.expected @@ -0,0 +1 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 - diff --git a/tests/fixtures/cksum/untagged/sha384_multiple_files.expected b/tests/fixtures/cksum/untagged/sha384_multiple_files.expected new file mode 100644 index 000000000..d309034b4 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_multiple_files.expected @@ -0,0 +1,2 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb lorem_ipsum.txt +b7966c97ef84ab5858db2e0cdd33fbaf4fa8346d84de65aba001e738c242598a43272854d0073ad1099404eaa1d93766 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha384_single_file.expected b/tests/fixtures/cksum/untagged/sha384_single_file.expected new file mode 100644 index 000000000..88d4da577 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_single_file.expected @@ -0,0 +1 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha384_stdin.expected b/tests/fixtures/cksum/untagged/sha384_stdin.expected new file mode 100644 index 000000000..cde20b78b --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_stdin.expected @@ -0,0 +1 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb - diff --git a/tests/fixtures/cksum/untagged/sha512_multiple_files.expected b/tests/fixtures/cksum/untagged/sha512_multiple_files.expected new file mode 100644 index 000000000..a5dafa7c3 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_multiple_files.expected @@ -0,0 +1,2 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 lorem_ipsum.txt +251646d5a7eb481e0f3aced7839d78dd5e97153f822dc55938e17059c485990d85d602e2881b528b565ab6262584a69c97b068b26bda81acc9356c53c7c1c96d alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha512_single_file.expected b/tests/fixtures/cksum/untagged/sha512_single_file.expected new file mode 100644 index 000000000..adea498d6 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_single_file.expected @@ -0,0 +1 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha512_stdin.expected b/tests/fixtures/cksum/untagged/sha512_stdin.expected new file mode 100644 index 000000000..dd9c96843 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_stdin.expected @@ -0,0 +1 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 - diff --git a/tests/fixtures/cksum/untagged/sm3_multiple_files.expected b/tests/fixtures/cksum/untagged/sm3_multiple_files.expected new file mode 100644 index 000000000..de12ab0b9 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_multiple_files.expected @@ -0,0 +1,2 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 lorem_ipsum.txt +d66617ae3c4e87828298dcd836f79efbab488c53b84e09c3e8e83a16c902418d alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sm3_single_file.expected b/tests/fixtures/cksum/untagged/sm3_single_file.expected new file mode 100644 index 000000000..54d5f40d2 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_single_file.expected @@ -0,0 +1 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sm3_stdin.expected b/tests/fixtures/cksum/untagged/sm3_stdin.expected new file mode 100644 index 000000000..6ba002b45 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_stdin.expected @@ -0,0 +1 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 - diff --git a/tests/fixtures/cksum/untagged/sysv_multiple_files.expected b/tests/fixtures/cksum/untagged/sysv_multiple_files.expected new file mode 100644 index 000000000..83a6d6d83 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_multiple_files.expected @@ -0,0 +1,2 @@ +6985 2 lorem_ipsum.txt +27441 1 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sysv_single_file.expected b/tests/fixtures/cksum/untagged/sysv_single_file.expected new file mode 100644 index 000000000..e0f7252cb --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_single_file.expected @@ -0,0 +1 @@ +6985 2 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sysv_stdin.expected b/tests/fixtures/cksum/untagged/sysv_stdin.expected new file mode 100644 index 000000000..f0fba8c81 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_stdin.expected @@ -0,0 +1 @@ +6985 2 From 3e7594632bbdbcb4a299603acef78818160eac2b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 14 May 2023 21:47:58 +0200 Subject: [PATCH 23/34] ls: when facing an invalid utf-8, don't panic Fails with ``` thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "invalid-\xE0-"', src/uu/ls/src/ls.rs:1932:53 ``` --- src/uu/ls/src/ls.rs | 10 +++++++++- tests/by-util/test_ls.rs | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 921987687..5e3a5a078 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1997,7 +1997,15 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool { require_literal_separator: false, case_sensitive: true, }; - let file_name = entry.file_name().into_string().unwrap(); + let file_name = entry.file_name(); + // If the decoding fails, still show an incorrect rendering + let file_name = match file_name.to_str() { + Some(s) => s.to_string(), + None => { + let file_name_bytes = file_name.to_string_lossy(); + file_name_bytes.into_owned() + } + }; !config .ignore_patterns .iter() diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index d460952ed..45ced867a 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -7,6 +7,10 @@ use crate::common::util::TestScenario; use nix::unistd::{close, dup}; use regex::Regex; use std::collections::HashMap; +#[cfg(target_os = "linux")] +use std::ffi::OsStr; +#[cfg(target_os = "linux")] +use std::os::unix::ffi::OsStrExt; #[cfg(all(unix, feature = "chmod"))] use std::os::unix::io::IntoRawFd; use std::path::Path; @@ -3434,3 +3438,13 @@ fn test_device_number() { .succeeds() .stdout_contains(major_minor_str); } + +#[test] +#[cfg(target_os = "linux")] +fn test_invalid_utf8() { + let (at, mut ucmd) = at_and_ucmd!(); + + let filename = OsStr::from_bytes(b"-\xE0-foo"); + at.touch(filename); + ucmd.succeeds(); +} From 369a2a66314ab6f76e3ac2176edb0c0d6b5e9964 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 10:12:28 +0200 Subject: [PATCH 24/34] Simplify the declaration Co-authored-by: Daniel Hofstetter --- src/uu/ls/src/ls.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 5e3a5a078..e5ad4bcd4 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -2001,10 +2001,7 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool { // If the decoding fails, still show an incorrect rendering let file_name = match file_name.to_str() { Some(s) => s.to_string(), - None => { - let file_name_bytes = file_name.to_string_lossy(); - file_name_bytes.into_owned() - } + None => file_name.to_string_lossy().into_owned(), }; !config .ignore_patterns From e6f999a32f03f820081cafa0156203c143d1de78 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 16:25:37 +0200 Subject: [PATCH 25/34] ci: Install pre-built binaries instead of using cargo install --- .github/workflows/CICD.yml | 20 +++++++++----------- .github/workflows/GnuTests.yml | 5 ++--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 849fb3c67..c0b1363d2 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -52,6 +52,9 @@ jobs: run: | rustup toolchain install nightly --no-self-update --profile minimal rustup default nightly + ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option + ## * ... ref: + - uses: taiki-e/install-action@cargo-udeps - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars @@ -70,12 +73,6 @@ jobs: CARGO_FEATURES_OPTION='' ; if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option - ## * ... ref: - - name: Install `cargo-udeps` - run: cargo install cargo-udeps - env: - RUSTUP_TOOLCHAIN: stable - name: Detect unused dependencies shell: bash run: | @@ -356,8 +353,8 @@ jobs: ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal rustup default ${{ env.RUST_MIN_SRV }} - - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Initialize workflow variables @@ -765,7 +762,6 @@ jobs: outputs CARGO_CMD # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then - cargo install --version 0.2.1 cross printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\"]\n" > Cross.toml fi # * test only library and/or binaries for arm-type targets @@ -779,6 +775,10 @@ jobs: *-pc-windows-msvc) STRIP="" ;; esac; outputs STRIP + - uses: taiki-e/install-action@v2 + if: steps.vars.outputs.CARGO_CMD == 'cross' + with: + tool: cross@v0.2.1 - name: Create all needed build/work directories shell: bash run: | @@ -1106,6 +1106,7 @@ jobs: rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal rustup default ${{ matrix.job.toolchain }} - uses: taiki-e/install-action@nextest + - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1194,9 +1195,6 @@ jobs: RUSTDOCFLAGS: "-Cpanic=abort" RUST_BACKTRACE: "1" # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - - name: "`grcov` ~ install" - id: build_grcov - run: cargo install grcov - name: Generate coverage data (via `grcov`) id: coverage shell: bash diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 894e29ea8..f8a7977dd 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -2,7 +2,7 @@ name: GnuTests # spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests Swatinem # spell-checker:ignore (jargon) submodules -# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap +# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap taiki-e # spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic # spell-checker:ignore (people) Dawid Dziurla * dawidd # spell-checker:ignore (vars) FILESET SUBDIRS XPASS @@ -323,6 +323,7 @@ jobs: rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} rustup toolchain install nightly -c rustfmt --profile minimal rustup default nightly + - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Install dependencies run: | @@ -353,8 +354,6 @@ jobs: UU_MAKE_PROFILE=debug bash util/build-gnu.sh - name: Run GNU tests run: bash uutils/util/run-gnu-test.sh - - name: "`grcov` ~ install" - run: cargo install grcov - name: Generate coverage data (via `grcov`) id: coverage run: | From 2935e5d8f920017ed9699eafc4c4d873f654f40c Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 16:49:49 +0200 Subject: [PATCH 26/34] ci: Use dtolnay/rust-toolchain to install the toolchain instead of the manual setup --- .github/workflows/CICD.yml | 109 ++++++++++++--------------------- .github/workflows/FixPR.yml | 18 ++---- .github/workflows/GnuTests.yml | 22 +++---- 3 files changed, 53 insertions(+), 96 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index c0b1363d2..c18284398 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -3,7 +3,7 @@ name: CICD # spell-checker:ignore (abbrev/names) CICD CodeCOV MacOS MinGW MSVC musl taiki # spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic Dwarnings RUSTDOCFLAGS RUSTFLAGS Zpanic CARGOFLAGS # spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain fuzzers -# spell-checker:ignore (people) Peltoche rivy +# spell-checker:ignore (people) Peltoche rivy dtolnay # spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot fdesc fdescfs gmake grcov halium lcov libssl mkdir popd printf pushd rsync rustc rustfmt rustup shopt utmpdump xargs # spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR gecos gnueabihf issuecomment maint multisize nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils @@ -48,10 +48,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option ## * ... ref: - uses: taiki-e/install-action@cargo-udeps @@ -95,11 +92,10 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars @@ -136,10 +132,7 @@ jobs: RUN_FOR: 60 steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - name: Install `cargo-fuzz` run: cargo install cargo-fuzz - uses: Swatinem/rust-cache@v2 @@ -183,11 +176,10 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -294,11 +286,10 @@ jobs: # - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -348,11 +339,10 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - run: | - ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + components: rustfmt - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -418,11 +408,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: "`cargo update` testing" shell: bash @@ -445,11 +431,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -492,11 +474,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -524,11 +502,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -553,11 +527,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -677,11 +647,10 @@ jobs: - { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} -t ${{ matrix.job.target }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + targets: ${{ matrix.job.target }} - uses: Swatinem/rust-cache@v2 with: key: "${{ matrix.job.os }}_${{ matrix.job.target }}" @@ -762,7 +731,7 @@ jobs: outputs CARGO_CMD # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then - printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\"]\n" > Cross.toml + printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\", \"CARGO_TERM_COLOR\"]\n" > Cross.toml fi # * test only library and/or binaries for arm-type targets unset CARGO_TEST_OPTIONS ; case '${{ matrix.job.target }}' in aarch64-* | arm-*) CARGO_TEST_OPTIONS="--bins" ;; esac; @@ -778,7 +747,7 @@ jobs: - uses: taiki-e/install-action@v2 if: steps.vars.outputs.CARGO_CMD == 'cross' with: - tool: cross@v0.2.1 + tool: cross@0.2.1 - name: Create all needed build/work directories shell: bash run: | @@ -1017,11 +986,10 @@ jobs: TEST_SUMMARY_FILE="toybox-result.json" outputs TEST_SUMMARY_FILE - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1100,11 +1068,10 @@ jobs: - { os: windows-latest , features: windows, toolchain: nightly-x86_64-pc-windows-gnu } steps: - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal - rustup default ${{ matrix.job.toolchain }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.job.toolchain }} + components: rustfmt - uses: taiki-e/install-action@nextest - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/FixPR.yml b/.github/workflows/FixPR.yml index 52561fb36..e1729b173 100644 --- a/.github/workflows/FixPR.yml +++ b/.github/workflows/FixPR.yml @@ -1,6 +1,6 @@ name: FixPR -# spell-checker:ignore Swatinem +# spell-checker:ignore Swatinem dtolnay # Trigger automated fixes for PRs being merged (with associated commits) @@ -36,11 +36,7 @@ jobs: # surface MSRV from CICD workflow RUST_MIN_SRV=$(grep -P "^\s+RUST_MIN_SRV:" .github/workflows/CICD.yml | grep -Po "(?<=\x22)\d+[.]\d+(?:[.]\d+)?(?=\x22)" ) outputs RUST_MIN_SRV - - name: Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }}) - run: | - ## Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }}) - rustup toolchain install ${{ steps.vars.outputs.RUST_MIN_SRV }} --profile minimal - rustup default ${{ steps.vars.outputs.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@${{ steps.vars.outputs.RUST_MIN_SRV }} - uses: Swatinem/rust-cache@v2 - name: Ensure updated 'Cargo.lock' shell: bash @@ -101,12 +97,10 @@ jobs: CARGO_FEATURES_OPTION='' ; if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install stable -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: "`cargo fmt`" shell: bash diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index f8a7977dd..97ba05baf 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -4,7 +4,7 @@ name: GnuTests # spell-checker:ignore (jargon) submodules # spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap taiki-e # spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic -# spell-checker:ignore (people) Dawid Dziurla * dawidd +# spell-checker:ignore (people) Dawid Dziurla * dawidd dtolnay # spell-checker:ignore (vars) FILESET SUBDIRS XPASS # * note: to run a single test => `REPO/util/run-gnu-test.sh PATH/TO/TEST/SCRIPT` @@ -58,12 +58,10 @@ jobs: uses: actions/checkout@v3 with: path: '${{ steps.vars.outputs.path_UUTILS }}' - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install stable -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Checkout code (GNU coreutils) uses: actions/checkout@v3 @@ -317,12 +315,10 @@ jobs: path: 'gnu' ref: 'v9.3' submodules: recursive - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install nightly -c rustfmt --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: rustfmt - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Install dependencies From 4b243ba272fd625a414ea8283fdf30147fa0c5a7 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 18:00:18 +0200 Subject: [PATCH 27/34] ci: Cleanup enviroment variables which are already set by github actions --- .github/workflows/CICD.yml | 7 ------- .github/workflows/GnuTests.yml | 1 - 2 files changed, 8 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index c18284398..fb2300ba9 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -396,7 +396,6 @@ jobs: env: RUSTFLAGS: "-Awarnings" RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: always deps: name: Dependencies @@ -445,7 +444,6 @@ jobs: run: make nextest CARGOFLAGS="--profile ci --hide-progress-bar" env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" - name: "`make install`" shell: bash run: | @@ -483,7 +481,6 @@ jobs: run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" build_rust_nightly: name: Build/nightly @@ -511,7 +508,6 @@ jobs: run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" compute_size: name: Binary sizes @@ -1138,7 +1134,6 @@ jobs: - name: Test uucore run: cargo nextest run --profile ci --hide-progress-bar -p uucore env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" @@ -1147,7 +1142,6 @@ jobs: - name: Test run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" @@ -1156,7 +1150,6 @@ jobs: - name: Test individual utilities run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 97ba05baf..4bde3ff6e 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -341,7 +341,6 @@ jobs: locale -a - name: Build binaries env: - CARGO_INCREMENTAL: "0" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" run: | From a569f6167ec945a6c77285ae0102289aa56465a7 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 15:59:01 +0200 Subject: [PATCH 28/34] ci/gnu tests: Fix Swatinem/rust-cache action to use the correct workspace --- .github/workflows/GnuTests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 894e29ea8..964775580 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -65,6 +65,8 @@ jobs: rustup toolchain install stable -c rustfmt --profile minimal rustup default stable - uses: Swatinem/rust-cache@v2 + with: + workspaces: "./${{ steps.vars.outputs.path_UUTILS }} -> target" - name: Checkout code (GNU coreutils) uses: actions/checkout@v3 with: @@ -324,6 +326,8 @@ jobs: rustup toolchain install nightly -c rustfmt --profile minimal rustup default nightly - uses: Swatinem/rust-cache@v2 + with: + workspaces: "./uutils -> target" - name: Install dependencies run: | ## Install dependencies From 3870ee252ae884cc1dba53d57ee74b34c8703467 Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Sun, 14 May 2023 15:29:54 -0700 Subject: [PATCH 29/34] yes: support non-UTF-8 args Also, tighten the creation of the output buffer. Rather than copy "y\n" 8192 times, or any other input some number of times, it can be doubled in place using Vec::extend_from_within. --- Cargo.lock | 1 + src/uu/yes/Cargo.toml | 1 + src/uu/yes/src/yes.rs | 161 ++++++++++++++++++++++++++++++++------ tests/by-util/test_yes.rs | 26 +++++- 4 files changed, 161 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f8bddf94..6abb5014a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3379,6 +3379,7 @@ name = "uu_yes" version = "0.0.18" dependencies = [ "clap", + "itertools", "nix", "uucore", ] diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index fd3d9ddc0..9d661fb0d 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -16,6 +16,7 @@ path = "src/yes.rs" [dependencies] clap = { workspace=true } +itertools = { workspace=true } [target.'cfg(unix)'.dependencies] uucore = { workspace=true, features=["pipes", "signals"] } diff --git a/src/uu/yes/src/yes.rs b/src/uu/yes/src/yes.rs index 41bfeddca..fd5124064 100644 --- a/src/uu/yes/src/yes.rs +++ b/src/uu/yes/src/yes.rs @@ -7,8 +7,11 @@ /* last synced with: yes (GNU coreutils) 8.13 */ -use clap::{Arg, ArgAction, Command}; -use std::borrow::Cow; +// cSpell:ignore strs + +use clap::{builder::ValueParser, Arg, ArgAction, Command}; +use std::error::Error; +use std::ffi::OsString; use std::io::{self, Write}; use uucore::error::{UResult, USimpleError}; #[cfg(unix)] @@ -28,19 +31,11 @@ const BUF_SIZE: usize = 16 * 1024; pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; - let string = if let Some(values) = matches.get_many::("STRING") { - let mut result = values.fold(String::new(), |res, s| res + s + " "); - result.pop(); - result.push('\n'); - Cow::from(result) - } else { - Cow::from("y\n") - }; + let mut buffer = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut buffer, matches.get_many::("STRING")).unwrap(); + prepare_buffer(&mut buffer); - let mut buffer = [0; BUF_SIZE]; - let bytes = prepare_buffer(&string, &mut buffer); - - match exec(bytes) { + match exec(&buffer) { Ok(()) => Ok(()), Err(err) if err.kind() == io::ErrorKind::BrokenPipe => Ok(()), Err(err) => Err(USimpleError::new(1, format!("standard output: {err}"))), @@ -51,21 +46,73 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .about(ABOUT) .override_usage(format_usage(USAGE)) - .arg(Arg::new("STRING").action(ArgAction::Append)) + .arg( + Arg::new("STRING") + .value_parser(ValueParser::os_string()) + .action(ArgAction::Append), + ) .infer_long_args(true) } -fn prepare_buffer<'a>(input: &'a str, buffer: &'a mut [u8; BUF_SIZE]) -> &'a [u8] { - if input.len() < BUF_SIZE / 2 { - let mut size = 0; - while size < BUF_SIZE - input.len() { - let (_, right) = buffer.split_at_mut(size); - right[..input.len()].copy_from_slice(input.as_bytes()); - size += input.len(); - } - &buffer[..size] +// Copies words from `i` into `buf`, separated by spaces. +fn args_into_buffer<'a>( + buf: &mut Vec, + i: Option>, +) -> Result<(), Box> { + // TODO: this should be replaced with let/else once available in the MSRV. + let i = if let Some(i) = i { + i } else { - input.as_bytes() + buf.extend_from_slice(b"y\n"); + return Ok(()); + }; + + // On Unix (and wasi), OsStrs are just &[u8]'s underneath... + #[cfg(any(unix, target_os = "wasi"))] + { + #[cfg(unix)] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::ffi::OsStrExt; + + for part in itertools::intersperse(i.map(|a| a.as_bytes()), b" ") { + buf.extend_from_slice(part); + } + } + + // But, on Windows, we must hop through a String. + #[cfg(not(any(unix, target_os = "wasi")))] + { + for part in itertools::intersperse(i.map(|a| a.to_str()), Some(" ")) { + let bytes = match part { + Some(part) => part.as_bytes(), + None => return Err("arguments contain invalid UTF-8".into()), + }; + buf.extend_from_slice(bytes); + } + } + + buf.push(b'\n'); + + Ok(()) +} + +// Assumes buf holds a single output line forged from the command line arguments, copies it +// repeatedly until the buffer holds as many copies as it can under BUF_SIZE. +fn prepare_buffer(buf: &mut Vec) { + if buf.len() * 2 > BUF_SIZE { + return; + } + + assert!(!buf.is_empty()); + + let line_len = buf.len(); + let target_size = line_len * (BUF_SIZE / line_len); + + while buf.len() < target_size { + let to_copy = std::cmp::min(target_size - buf.len(), buf.len()); + debug_assert_eq!(to_copy % line_len, 0); + buf.extend_from_within(..to_copy); } } @@ -88,3 +135,67 @@ pub fn exec(bytes: &[u8]) -> io::Result<()> { stdout.write_all(bytes)?; } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_prepare_buffer() { + let tests = [ + (150, 16350), + (1000, 16000), + (4093, 16372), + (4099, 12297), + (4111, 12333), + (2, 16384), + (3, 16383), + (4, 16384), + (5, 16380), + (8192, 16384), + (8191, 16382), + (8193, 8193), + (10000, 10000), + (15000, 15000), + (25000, 25000), + ]; + + for (line, final_len) in tests { + let mut v = std::iter::repeat(b'a').take(line).collect::>(); + prepare_buffer(&mut v); + assert_eq!(v.len(), final_len); + } + } + + #[test] + fn test_args_into_buf() { + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut v, None::>).unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "y\n"); + } + + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut v, Some([OsString::from("foo")].iter())).unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "foo\n"); + } + + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer( + &mut v, + Some( + [ + OsString::from("foo"), + OsString::from("bar baz"), + OsString::from("qux"), + ] + .iter(), + ), + ) + .unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "foo bar baz qux\n"); + } + } +} diff --git a/tests/by-util/test_yes.rs b/tests/by-util/test_yes.rs index c054a6e5f..89a68e7e1 100644 --- a/tests/by-util/test_yes.rs +++ b/tests/by-util/test_yes.rs @@ -1,3 +1,4 @@ +use std::ffi::OsStr; use std::process::{ExitStatus, Stdio}; #[cfg(unix)] @@ -15,8 +16,10 @@ fn check_termination(result: ExitStatus) { assert!(result.success(), "yes did not exit successfully"); } +const NO_ARGS: &[&str] = &[]; + /// Run `yes`, capture some of the output, close the pipe, and verify it. -fn run(args: &[&str], expected: &[u8]) { +fn run(args: &[impl AsRef], expected: &[u8]) { let mut cmd = new_ucmd!(); let mut child = cmd.args(args).set_stdout(Stdio::piped()).run_no_wait(); let buf = child.stdout_exact_bytes(expected.len()); @@ -34,7 +37,7 @@ fn test_invalid_arg() { #[test] fn test_simple() { - run(&[], b"y\ny\ny\ny\n"); + run(NO_ARGS, b"y\ny\ny\ny\n"); } #[test] @@ -44,7 +47,7 @@ fn test_args() { #[test] fn test_long_output() { - run(&[], "y\n".repeat(512 * 1024).as_bytes()); + run(NO_ARGS, "y\n".repeat(512 * 1024).as_bytes()); } /// Test with an output that seems likely to get mangled in case of incomplete writes. @@ -88,3 +91,20 @@ fn test_piped_to_dev_full() { } } } + +#[test] +#[cfg(any(unix, target_os = "wasi"))] +fn test_non_utf8() { + #[cfg(unix)] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::ffi::OsStrExt; + + run( + &[ + OsStr::from_bytes(b"\xbf\xff\xee"), + OsStr::from_bytes(b"bar"), + ], + &b"\xbf\xff\xee bar\n".repeat(5000), + ); +} From a1a136650b2048071bcbeadc69a5a9dabb420eb8 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 21:46:07 +0200 Subject: [PATCH 30/34] remaining-gnu-error.py: split SKIP & ERROR --- util/remaining-gnu-error.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/util/remaining-gnu-error.py b/util/remaining-gnu-error.py index eda37094d..5fd47300a 100755 --- a/util/remaining-gnu-error.py +++ b/util/remaining-gnu-error.py @@ -19,7 +19,8 @@ urllib.request.urlretrieve( types = ("/*/*.sh", "/*/*.pl", "/*/*.xpl") tests = [] -error_or_skip_tests = [] +error_tests = [] +skip_tests = [] for files in types: tests.extend(glob.glob(base + files)) @@ -58,14 +59,23 @@ for d in data: print("Could not find test '%s'. Maybe update the GNU repo?" % a) sys.exit(1) - # if it is SKIP or ERROR, show it - if data[d][e] in ("SKIP", "ERROR"): + # if it is SKIP, show it + if data[d][e] == "SKIP": list_of_files.remove(a) - error_or_skip_tests.append(a) + skip_tests.append(a) + # if it is ERROR, show it + if data[d][e] == "ERROR": + list_of_files.remove(a) + error_tests.append(a) -print("SKIP and ERROR tests:") -show_list(error_or_skip_tests) +print("===============") +print("SKIP tests:") +show_list(skip_tests) +print("") +print("===============") +print("ERROR tests:") +show_list(error_tests) print("") print("===============") print("FAIL tests:") From 6c1552cc202e982af3393208bb1b458f073c8597 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 23:08:49 +0200 Subject: [PATCH 31/34] Document why tests are skipped --- util/why-skip.txt | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 util/why-skip.txt diff --git a/util/why-skip.txt b/util/why-skip.txt new file mode 100644 index 000000000..9f72ad7e0 --- /dev/null +++ b/util/why-skip.txt @@ -0,0 +1,96 @@ += trapping SIGPIPE is not supported = +tests/tail-2/pipe-f.sh +tests/misc/seq-epipe.sh +tests/misc/printf-surprise.sh +tests/misc/env-signal-handler.sh + += skipped test: breakpoint not hit = +tests/tail-2/inotify-race2.sh +tail-2/inotify-race.sh + += internal test failure: maybe LD_PRELOAD doesn't work? = +tests/rm/rm-readdir-fail.sh +tests/rm/r-root.sh +tests/df/skip-duplicates.sh +tests/df/no-mtab-status.sh + += LD_PRELOAD was ineffective? = +tests/cp/nfs-removal-race.sh + += failed to create hfs file system = +tests/mv/hardlink-case.sh + += temporarily disabled = +tests/mkdir/writable-under-readonly.sh + += this system lacks SMACK support = +tests/mkdir/smack-root.sh +tests/mkdir/smack-no-root.sh +tests/id/smack.sh + += this system lacks SELinux support = +tests/mkdir/selinux.sh +tests/mkdir/restorecon.sh +tests/misc/selinux.sh +tests/misc/chcon.sh +tests/install/install-Z-selinux.sh +tests/install/install-C-selinux.sh +tests/id/no-context.sh +tests/id/context.sh +tests/cp/no-ctx.sh +tests/cp/cp-a-selinux.sh + += failed to set xattr of file = +tests/misc/xattr.sh + += timeout returned 142. SIGALRM not handled? = +tests/misc/timeout-group.sh + += FULL_PARTITION_TMPDIR not defined = +tests/misc/tac-continue.sh + += can't get window size = +tests/misc/stty-row-col.sh + += The Swedish locale with blank thousands separator is unavailable. = +tests/misc/sort-h-thousands-sep.sh + += this shell lacks ulimit support = +tests/misc/csplit-heap.sh + += multicall binary is disabled = +tests/misc/coreutils.sh + += your ls doesn't call capget = +tests/ls/no-cap.sh + + += not running on GNU/Hurd = +tests/id/gnu-zero-uids.sh + += file system cannot represent big timestamps = +tests/du/bigtime.sh + += no rootfs in mtab = +tests/df/skip-rootfs.sh + += insufficient mount/ext2 support = +tests/df/problematic-chars.sh +tests/cp/cp-mv-enotsup-xattr.sh + += 512 byte aligned O_DIRECT is not supported on this (file) system = +tests/dd/direct.sh + += skipped test: /usr/bin/touch -m -d '1998-01-15 23:00' didn't work = +tests/misc/ls-time.sh + += requires controlling input terminal = +tests/misc/stty-pairs.sh +tests/misc/stty.sh +tests/misc/stty-invalid.sh + += insufficient SEEK_DATA support = +tests/cp/sparse-perf.sh +tests/cp/sparse-extents.sh +tests/cp/sparse-extents-2.sh +tests/cp/sparse-2.sh From 354cb0341c09fe8bd9fd5c9f96b634f71a275f0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 10:35:39 +0000 Subject: [PATCH 32/34] chore(deps): update rust crate zip to 0.6.6 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6abb5014a..2a189c819 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3667,9 +3667,9 @@ checksum = "2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fc" [[package]] name = "zip" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e92305c174683d78035cbf1b70e18db6329cc0f1b9cae0a52ca90bf5bfe7125" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "byteorder", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index c5d2a760b..24bbafab2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -331,7 +331,7 @@ walkdir = "2.3" winapi-util = "0.1.5" windows-sys = { version="0.45.0", default-features=false } xattr = "1.0.0" -zip = { version = "0.6.5", default_features=false, features=["deflate"] } +zip = { version = "0.6.6", default_features=false, features=["deflate"] } hex = "0.4.3" md-5 = "0.10.5" From 11b72d3849745cbdd3fb0c05c4811c94f841b30e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 11:30:17 +0000 Subject: [PATCH 33/34] chore(deps): update rust crate sm3 to 0.4.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a189c819..a9f9532b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2158,9 +2158,9 @@ dependencies = [ [[package]] name = "sm3" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f943a7c5e3089f2bd046221d1e9f4fa59396bf0fe966360983649683086215da" +checksum = "ebb9a3b702d0a7e33bc4d85a14456633d2b165c2ad839c5fd9a8417c1ab15860" dependencies = [ "digest", ] diff --git a/Cargo.toml b/Cargo.toml index 24bbafab2..8f62a87f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -340,7 +340,7 @@ sha2 = "0.10.6" sha3 = "0.10.8" blake2b_simd = "1.0.1" blake3 = "1.3.3" -sm3 = "0.4.1" +sm3 = "0.4.2" digest = "0.10.6" uucore = { version=">=0.0.18", package="uucore", path="src/uucore" } From 5b715b4085005d13b014456debd932e9f625d0db Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 16 May 2023 16:10:18 +0200 Subject: [PATCH 34/34] Add "spell-checker:ignore" line --- util/why-skip.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/why-skip.txt b/util/why-skip.txt index 9f72ad7e0..c790311c1 100644 --- a/util/why-skip.txt +++ b/util/why-skip.txt @@ -1,3 +1,5 @@ +# spell-checker:ignore epipe readdir restorecon SIGALRM capget bigtime rootfs enotsup + = trapping SIGPIPE is not supported = tests/tail-2/pipe-f.sh tests/misc/seq-epipe.sh