From 0ba93322514d546643b73313cbdb736a0ad1ea70 Mon Sep 17 00:00:00 2001 From: ngie Date: Mon, 17 Jul 2017 21:13:43 +0000 Subject: [PATCH] MFC r319856,r320172,r320173: r319856: Add a testcase for `ln -sF` The testcase fails today, so mark it with atf_expect_fail: in particular, the target (B) isn't being unlinked and the documentation doesn't suggest special handling for directories. Thus, there's either a doc or an implementation bug in ln(1) that needs to be resolved. MFC with: r319714, r319854, r319855 PR: 219943 r320172: ln(1): fix -F behavior When '-F' option is used, the target directory needs to be unlinked. Currently, the modified target ("target/source") is being unlinked, and since it doesn't yet exist, the original target isn't removed. This is fixed by skipping the block where target is modified to "target/source" when '-F' option is set. Hence, a symbolic link (with the same name as of the original target) to the source_file is produced. Update the test for ln(1) to reflect fix for option '-F' PR: 219943 r320173: Don't expect :sF_flag to fail anymore While here, also add a check to verify that the link target is updated in the testcase MFC with: r320172 PR: 219943 git-svn-id: svn://svn.freebsd.org/base/stable/10@321094 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- bin/ln/ln.c | 6 +++--- bin/ln/tests/ln_test.sh | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/bin/ln/ln.c b/bin/ln/ln.c index f50802a9f..ef8d5320c 100644 --- a/bin/ln/ln.c +++ b/bin/ln/ln.c @@ -245,11 +245,11 @@ linkit(const char *source, const char *target, int isdir) /* * If the target is a directory (and not a symlink if hflag), - * append the source's name. + * append the source's name, unless Fflag is set. */ - if (isdir || + if (!Fflag && (isdir || (lstat(target, &sb) == 0 && S_ISDIR(sb.st_mode)) || - (!hflag && stat(target, &sb) == 0 && S_ISDIR(sb.st_mode))) { + (!hflag && stat(target, &sb) == 0 && S_ISDIR(sb.st_mode)))) { if (strlcpy(bbuf, source, sizeof(bbuf)) >= sizeof(bbuf) || (p = basename(bbuf)) == NULL || snprintf(path, sizeof(path), "%s/%s", target, p) >= diff --git a/bin/ln/tests/ln_test.sh b/bin/ln/tests/ln_test.sh index f059f56c9..ad731f38e 100644 --- a/bin/ln/tests/ln_test.sh +++ b/bin/ln/tests/ln_test.sh @@ -145,6 +145,22 @@ snf_flag_dir_body() atf_check -o inline:'C: symbolic link to B\n' file C } +atf_test_case sF_flag +sF_flag_head() +{ + atf_set "descr" "Verify that if the target file already exists " \ + "and is a directory, then '-sF' option removes " \ + "it so that the link may occur" +} + +sF_flag_body() +{ + atf_check mkdir A B + atf_check ln -sF A B + atf_check -o inline:'Symbolic Link\n' stat -f %SHT B + atf_check -o inline:'A\n' readlink B +} + atf_test_case sf_flag sf_flag_head() { @@ -210,6 +226,7 @@ atf_init_test_cases() atf_add_test_case target_exists_symbolic atf_add_test_case shf_flag_dir atf_add_test_case snf_flag_dir + atf_add_test_case sF_flag atf_add_test_case sf_flag atf_add_test_case s_flag atf_add_test_case s_flag_broken -- 2.45.0