diff options
-rwxr-xr-x | tests/ln.test | 8 | ||||
-rw-r--r-- | toys/posix/ln.c | 18 |
2 files changed, 18 insertions, 8 deletions
diff --git a/tests/ln.test b/tests/ln.test index 3e70cd83..9effcbd6 100755 --- a/tests/ln.test +++ b/tests/ln.test @@ -44,6 +44,14 @@ rm slink testing "no_dereference" "ln -s dir slink && ln -n -s file slink 2>/dev/null || [ -L slink ] && readlink slink" \ "dir\n" "" "" +rm slink + +testing "-T acts like -n" "ln -s dir slink && + ln -Tsf file slink || [ -L slink ] && readlink slink" "file\n" "" "" +rm slink + +testing "-T with dir" "ln -Ts file dir 2>/dev/null || echo yes" "yes\n" "" "" + rm -rf file dir slink touch file1 file2 && mkdir dir diff --git a/toys/posix/ln.c b/toys/posix/ln.c index 7f635402..fb47e911 100644 --- a/toys/posix/ln.c +++ b/toys/posix/ln.c @@ -4,7 +4,7 @@ * * See http://opengroup.org/onlinepubs/9699919799/utilities/ln.html -USE_LN(NEWTOY(ln, "<1vnfs", TOYFLAG_BIN)) +USE_LN(NEWTOY(ln, "<1Tvnfs", TOYFLAG_BIN)) config LN bool "ln" @@ -13,11 +13,12 @@ config LN usage: ln [-sfnv] [FROM...] TO Create a link between FROM and TO. - With only one argument, create link in current directory. + One/two/many arguments work like "mv" or "cp". -s Create a symbolic link -f Force the creation of the link, even if TO already exists - -n Symlink at destination treated as file + -n Symlink at TO treated as file + -T TO always treated as file -v Verbose */ @@ -37,11 +38,12 @@ void ln_main(void) } // Is destination a directory? - if ((FLAG(n) ? lstat : stat)(dest, &buf) || !S_ISDIR(buf.st_mode)) - { - if (toys.optc>1) error_exit("'%s' not a directory", dest); - buf.st_mode = 0; - } + if (!((FLAG(n)||FLAG(T)) ? lstat : stat)(dest, &buf)) { + i = S_ISDIR(buf.st_mode); + + if ((FLAG(T) && i) || (!i && toys.optc>1)) + error_exit("'%s' %s a directory", dest, i ? "is" : "not"); + } else buf.st_mode = 0; for (i=0; i<toys.optc; i++) { int rc; |