]> Sergey Matveev's repositories - nnn.git/commitdiff
When handling bookmark, use readlink, not realpath
authorme <email>
Tue, 21 Nov 2023 17:52:38 +0000 (20:52 +0300)
committerme <email>
Wed, 22 Nov 2023 17:41:49 +0000 (20:41 +0300)
This is to cd to path as it pointed by symlink, not to it's real path. Bookmarked directory may itself contain symlinks in path, which should be respected.

For example: if directory is physically in /mnt/storage/some and it's symlinked to ~/some and directory ~/some/dir added to bookmarks, it's expected that when following bookmark directory will be changed to ~/some/dir (as in bookmark's link) not to /mnt/storage/some/dir (as dir real path).

src/nnn.c

index d8e332602e48cb99ea932b459c5ca2dc9d654c97..07dcba608b4c16cfa21e9955b1eb691ac0c83a23 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -1310,6 +1310,18 @@ static char *abspath(const char *filepath, char *cwd, char *buf)
        return resolved_path;
 }
 
+/* finds abspath of link pointed by filepath, taking cwd into account */
+static char *bmtarget(const char *filepath, char *cwd, char *buf) 
+{
+       char target[PATH_MAX + 1];
+       ssize_t n = readlink(filepath, target, PATH_MAX);
+       if (n != -1) {
+               target[n] = '\0';
+               return abspath(target, cwd, buf);
+       } 
+       return NULL;
+}
+
 /* wraps the argument in single quotes so it can be safely fed to shell */
 static bool shell_escape(char *output, size_t outlen, const char *s)
 {
@@ -7053,7 +7065,7 @@ nochange:
 
                        pent = &pdents[cur];
                        if (!g_state.selbm || !(S_ISLNK(pent->mode) &&
-                                               realpath(pent->name, newpath) &&
+                                               bmtarget(pent->name, path, newpath) &&
                                                xstrsncpy(path, lastdir, PATH_MAX)))
                                mkpath(path, pent->name, newpath);
                        g_state.selbm = 0;