logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: b170e6a9eb7564dbead8a94660c9808131d827a2
parent d99da98d804678e12b7bce2e21c56d03dad6a5e9
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 28 Aug 2024 18:53:16 +0200

cmd/mv: follow source file symlink only when found

Diffstat:

Mcmd/mv.c10+++++++++-
Mtest-cmd/mv.t51+++++++++++++++++++++++++++++++++------------------
2 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/cmd/mv.c b/cmd/mv.c @@ -133,7 +133,7 @@ do_renameat(struct named_fd srcdir, } struct stat src_status; - if(fstatat(srcdir.fd, src, &src_status, 0) < 0) + if(fstatat(srcdir.fd, src, &src_status, AT_SYMLINK_NOFOLLOW) < 0) { fprintf(stderr, "mv: Failed getting status for source file '%s/%s': %s\n", @@ -142,6 +142,14 @@ do_renameat(struct named_fd srcdir, strerror(errno)); return -1; } + if(S_ISLNK(src_status.st_mode)) + { + struct stat src_link_status; + if(fstatat(srcdir.fd, src, &src_link_status, 0) == 0) + { + src_status = src_link_status; + } + } errno = 0; diff --git a/test-cmd/mv.t b/test-cmd/mv.t @@ -55,25 +55,32 @@ POSIX mv(1) step 1b, no -f option, -i passed $ rm -fr 1a_no-f_write POSIX mv(1) step 2, same file - $ touch same - $ mv same same - mv: Error, passed to both source and destination: 'same' + $ touch same-name + $ mv same-name same-name + mv: Error, passed to both source and destination: 'same-name' [1] - $ test -e same - $ ln same Same - $ mv same Same - $ test -e same - $ test -e Same - $ ln -s same same-s - $ mv same same-s - $ test -e same - $ test -e Same - $ test -e same-s - $ mv Same same-s - $ test -e same - $ test -e Same - $ test -e same-s - $ rm same Same same-s + $ test -e same-name + $ rm same-name + +POSIX mv(1) step 2, same file, hardlink + $ touch same-src-h + $ ln same-src-h same-dest-h + $ mv same-src-h same-src-h + mv: Error, passed to both source and destination: 'same-src-h' + [1] + $ test -e same-src-h + $ test -e same-dest-h + $ rm same-src-h same-dest-h + +POSIX mv(1) step 2, same file, symlink + $ touch same-src-s + $ ln -s same-src-s same-dest-s + $ mv same-src-s same-src-s + mv: Error, passed to both source and destination: 'same-src-s' + [1] + $ test -e same-src-s + $ test -e same-dest-s + $ rm same-src-s same-dest-s Where destination is an existing directory $ mkdir destdir @@ -135,6 +142,14 @@ Last component used for destination filename $ test -f dest_last/file $ rm -r src_last dest_last +Works with non-resolving source symlinks + $ ln -s /var/empty/e/no/ent symlink_enoent + $ test -L symlink_enoent + $ mv symlink_enoent symlink_enoent.done + $ test ! -L symlink_enoent + $ test -L symlink_enoent.done + $ rm symlink_enoent.done + No files should be left $ find . .