Skip to content

Commit 51d225f

Browse files
authored
Merge branch 'main' into fix-suf-errors
2 parents fdd499b + 2916d2b commit 51d225f

File tree

4 files changed

+59
-33
lines changed

4 files changed

+59
-33
lines changed

src/uu/cp/src/cp.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,11 +2510,13 @@ fn copy_file(
25102510
}
25112511

25122512
if options.dereference(source_in_command_line) {
2513-
if let Ok(src) = canonicalize(source, MissingHandling::Normal, ResolveMode::Physical) {
2514-
if src.exists() {
2515-
copy_attributes(&src, dest, &options.attributes)?;
2516-
}
2517-
}
2513+
// Try to canonicalize, but if it fails (e.g., due to inaccessible parent directories),
2514+
// fall back to the original source path
2515+
let src_for_attrs = canonicalize(source, MissingHandling::Normal, ResolveMode::Physical)
2516+
.ok()
2517+
.filter(|p| p.exists())
2518+
.unwrap_or_else(|| source.to_path_buf());
2519+
copy_attributes(&src_for_attrs, dest, &options.attributes)?;
25182520
} else if source_is_stream && !source.exists() {
25192521
// Some stream files may not exist after we have copied it,
25202522
// like anonymous pipes. Thus, we can't really copy its

src/uu/du/src/du.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,7 @@ fn safe_du(
501501

502502
// Handle inodes
503503
if let Some(inode) = this_stat.inode {
504-
if seen_inodes.contains(&inode) && (!options.count_links || !options.all) {
505-
if options.count_links && !options.all {
506-
my_stat.inodes += 1;
507-
}
504+
if seen_inodes.contains(&inode) && !options.count_links {
508505
continue;
509506
}
510507
seen_inodes.insert(inode);
@@ -660,13 +657,7 @@ fn du_regular(
660657

661658
if let Some(inode) = this_stat.inode {
662659
// Check if the inode has been seen before and if we should skip it
663-
if seen_inodes.contains(&inode)
664-
&& (!options.count_links || !options.all)
665-
{
666-
// If `count_links` is enabled and `all` is not, increment the inode count
667-
if options.count_links && !options.all {
668-
my_stat.inodes += 1;
669-
}
660+
if seen_inodes.contains(&inode) && !options.count_links {
670661
// Skip further processing for this inode
671662
continue;
672663
}

src/uu/nice/src/nice.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
55

6-
// spell-checker:ignore (ToDO) getpriority execvp setpriority nstr PRIO cstrs ENOENT
6+
// spell-checker:ignore (ToDO) getpriority setpriority nstr PRIO
77

88
use clap::{Arg, ArgAction, Command};
9-
use libc::{PRIO_PROCESS, c_char, c_int, execvp};
10-
use std::ffi::{CString, OsString};
11-
use std::io::{Error, Write};
12-
use std::ptr;
9+
use libc::PRIO_PROCESS;
10+
use std::ffi::OsString;
11+
use std::io::{Error, ErrorKind, Write};
12+
use std::os::unix::process::CommandExt;
13+
use std::process;
1314

1415
use uucore::translate;
1516
use uucore::{
@@ -156,21 +157,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
156157
}
157158
}
158159

159-
let cstrs: Vec<CString> = matches
160-
.get_many::<String>(options::COMMAND)
161-
.unwrap()
162-
.map(|x| CString::new(x.as_bytes()).unwrap())
163-
.collect();
160+
let mut cmd_iter = matches.get_many::<String>(options::COMMAND).unwrap();
161+
let cmd = cmd_iter.next().unwrap();
162+
let args: Vec<&String> = cmd_iter.collect();
164163

165-
let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect();
166-
args.push(ptr::null::<c_char>());
167-
unsafe {
168-
execvp(args[0], args.as_mut_ptr());
169-
}
164+
let err = process::Command::new(cmd).args(args).exec();
170165

171-
show_error!("execvp: {}", Error::last_os_error());
166+
show_error!("{}: {}", cmd, err);
172167

173-
let exit_code = if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT {
168+
let exit_code = if err.kind() == ErrorKind::NotFound {
174169
127
175170
} else {
176171
126

tests/by-util/test_du.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,44 @@ fn test_du_inodes_with_count_links_all() {
804804
assert_eq!(result_seq, ["1\td/d", "1\td/f", "1\td/h", "4\td"]);
805805
}
806806

807+
#[cfg(not(target_os = "android"))]
808+
#[test]
809+
fn test_du_count_links_hardlinks_separately() {
810+
let ts = TestScenario::new(util_name!());
811+
let at = &ts.fixtures;
812+
813+
at.mkdir("dir");
814+
at.touch("dir/file");
815+
at.hard_link("dir/file", "dir/hard_link");
816+
817+
let result_without_l = ts.ucmd().arg("-b").arg("dir").succeeds();
818+
let size_without_l: u64 = result_without_l
819+
.stdout_str()
820+
.split('\t')
821+
.next()
822+
.unwrap()
823+
.trim()
824+
.parse()
825+
.unwrap();
826+
827+
for arg in ["-l", "--count-links"] {
828+
let result_with_l = ts.ucmd().arg("-b").arg(arg).arg("dir").succeeds();
829+
let size_with_l: u64 = result_with_l
830+
.stdout_str()
831+
.split('\t')
832+
.next()
833+
.unwrap()
834+
.trim()
835+
.parse()
836+
.unwrap();
837+
838+
assert!(
839+
size_with_l >= size_without_l,
840+
"With {arg}, size ({size_with_l}) should be >= size without -l ({size_without_l})"
841+
);
842+
}
843+
}
844+
807845
#[test]
808846
fn test_du_h_flag_empty_file() {
809847
new_ucmd!()

0 commit comments

Comments
 (0)