From 9aaf9491ad6a144ad096bcde9a5605c628c83e42 Mon Sep 17 00:00:00 2001 From: me Date: Tue, 21 Nov 2023 20:52:38 +0300 Subject: [PATCH] When handling bookmark, use readlink, not realpath 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 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/nnn.c b/src/nnn.c index d8e33260..07dcba60 100644 --- 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;