Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/uu/ln/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ ln-prompt-replace = replace {$file}?
ln-cannot-backup = cannot backup {$file}
ln-failed-to-access = failed to access {$file}
ln-failed-to-create-hard-link = failed to create hard link {$source} => {$dest}
ln-failed-to-create-hard-link-dir = {$source}: hard link not allowed for directory
ln-backup = backup: {$backup}
1 change: 1 addition & 0 deletions src/uu/ln/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ ln-prompt-replace = remplacer {$file} ?
ln-cannot-backup = impossible de sauvegarder {$file}
ln-failed-to-access = échec d'accès à {$file}
ln-failed-to-create-hard-link = échec de création du lien physique {$source} => {$dest}
ln-failed-to-create-hard-link-dir = {$source} : lien physique non autorisé pour un répertoire
ln-backup = sauvegarde : {$backup}
9 changes: 9 additions & 0 deletions src/uu/ln/src/ln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ enum LnError {

#[error("{}", translate!("ln-error-extra-operand", "operand" => _0.to_string_lossy(), "program" => _1.clone()))]
ExtraOperand(OsString, String),

#[error("{}", translate!("ln-failed-to-create-hard-link-dir", "source" => _0.to_string_lossy()))]
FailedToCreateHardLinkDir(PathBuf),
}

impl UError for LnError {
Expand Down Expand Up @@ -431,6 +434,12 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
if settings.symbolic {
symlink(&source, dst)?;
} else {
// Cannot create hard link to a directory directly
// We can however create hard link to a symlink that points to a directory, so long as -L is not passed
if src.is_dir() && (!src.is_symlink() || settings.logical) {
return Err(LnError::FailedToCreateHardLinkDir(source.to_path_buf()).into());
}

let p = if settings.logical && source.is_symlink() {
// if we want to have an hard link,
// source is a symlink and -L is passed
Expand Down
14 changes: 14 additions & 0 deletions tests/by-util/test_ln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,3 +934,17 @@ fn test_ln_non_utf8_paths() {
let symlink_path = at.plus(symlink_name);
assert!(symlink_path.is_symlink());
}

#[test]
fn test_ln_hard_link_dir() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

at.mkdir("dir");

scene
.ucmd()
.args(&["dir", "dir_link"])
.fails()
.stderr_contains("hard link not allowed for directory");
}
3 changes: 0 additions & 3 deletions util/build-gnu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,6 @@ sed -i -e "s/cat opts/sed -i -e \"s| <.\*$||g\" opts/" tests/misc/usage_vs_getop
# for some reasons, some stuff are duplicated, strip that
sed -i -e "s/provoked error./provoked error\ncat pat |sort -u > pat/" tests/misc/usage_vs_getopt.sh

# Update the GNU error message to match ours
sed -i -e "s/link-to-dir: hard link not allowed for directory/failed to create hard link 'link-to-dir' =>/" -e "s|link-to-dir/: hard link not allowed for directory|failed to create hard link 'link-to-dir/' =>|" tests/ln/hard-to-sym.sh

# install verbose messages shows ginstall as command
sed -i -e "s/ginstall: creating directory/install: creating directory/g" tests/install/basic-1.sh

Expand Down
Loading