mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
ln: Use basename when target directory is specfied
The following should work, but without this patch, it tries to create the link as x/y and it fails with EEXIST. $ mkdir -p x/y $ ln -s -t . x/y
This commit is contained in:
parent
626a3b7611
commit
47acbb0e82
2 changed files with 36 additions and 2 deletions
11
src/ln/ln.rs
11
src/ln/ln.rs
|
@ -189,7 +189,16 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &PathBuf, settings: &Setting
|
||||||
let mut all_successful = true;
|
let mut all_successful = true;
|
||||||
for srcpath in files.iter() {
|
for srcpath in files.iter() {
|
||||||
let targetpath = match srcpath.as_os_str().to_str() {
|
let targetpath = match srcpath.as_os_str().to_str() {
|
||||||
Some(name) => target_dir.join(name),
|
Some(name) => {
|
||||||
|
match Path::new(name).file_name() {
|
||||||
|
Some(basename) => target_dir.join(basename),
|
||||||
|
// This can be None only for "." or "..". Trying
|
||||||
|
// to create a link with such name will fail with
|
||||||
|
// EEXIST, which agrees with the bahavior of GNU
|
||||||
|
// coreutils.
|
||||||
|
None => target_dir.join(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
show_error!("cannot stat '{}': No such file or directory",
|
show_error!("cannot stat '{}': No such file or directory",
|
||||||
srcpath.display());
|
srcpath.display());
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use common::util::*;
|
use common::util::*;
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_symlink_existing_file() {
|
fn test_symlink_existing_file() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
@ -248,6 +247,32 @@ fn test_symlink_target_dir() {
|
||||||
assert_eq!(at.resolve_link(file_b_link), file_b);
|
assert_eq!(at.resolve_link(file_b_link), file_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_symlink_target_dir_from_dir() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let dir = "test_ln_target_dir_dir";
|
||||||
|
let from_dir = "test_ln_target_dir_from_dir";
|
||||||
|
let filename_a = "test_ln_target_dir_file_a";
|
||||||
|
let filename_b = "test_ln_target_dir_file_b";
|
||||||
|
let file_a = &format!("{}/{}", from_dir, filename_a);
|
||||||
|
let file_b = &format!("{}/{}", from_dir, filename_b);
|
||||||
|
|
||||||
|
at.mkdir(from_dir);
|
||||||
|
at.touch(file_a);
|
||||||
|
at.touch(file_b);
|
||||||
|
at.mkdir(dir);
|
||||||
|
|
||||||
|
ucmd.args(&["-s", "-t", dir, file_a, file_b]).succeeds().no_stderr();
|
||||||
|
|
||||||
|
let file_a_link = &format!("{}/{}", dir, filename_a);
|
||||||
|
assert!(at.is_symlink(file_a_link));
|
||||||
|
assert_eq!(&at.resolve_link(file_a_link), file_a);
|
||||||
|
|
||||||
|
let file_b_link = &format!("{}/{}", dir, filename_b);
|
||||||
|
assert!(at.is_symlink(file_b_link));
|
||||||
|
assert_eq!(&at.resolve_link(file_b_link), file_b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_symlink_overwrite_dir() {
|
fn test_symlink_overwrite_dir() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue