Ticket #3093: keep symlinks in cwd at startup.

If you navigate in your shell to a directory containing symlinks and
then start mc, mc will show the canonical path instead. It would be nice
to make it show the directory with the symlinks.

Example: in your shell execute these:

user:~$ mkdir -p /tmp/a/b /tmp/x ; ln -s /tmp/a/b /tmp/x/y
user:~$ cd /tmp/x/y
user:/tmp/x/y$ mc

In mc you'll find yourself in /tmp/a/b, though it'd be nicer to see
/tmp/x/y at the top, and correspondingly navigating to the parent would
take you to /tmp/x.

If you start bash or zsh from /tmp/x/y, the new instance will start
displaying the working directory as such. They do this via the PWD env
variable. On one hand, they set and maintain PWD to point to the current
directory, using the path as specified by the user (possibly containing
symbolic links). On the other hand, they check its value at startup. If
$PWD points to the same physical directory as the actual working
directory then they use this value. If $PWD points somewhere else then
it's simply ignored (so it's a hint only as to which symlinks to use to
get to the working directory, but never alters the actual cwd).

Now mc also does the same at startup (with respect of "Cd follows
links" option). Relative directories specified in the command line  are
applied after possibly replacing the canonical cwd with $PWD. This way
for example

user:/tmp/x/y$ mc . ..

opens two panels in /tmp/x/y and /tmp/x instead of /tmp/a/b and /tmp/a
(whereas /tmp/x is actually a different directory than /tmp/a).

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Egmont Koblinger 2013-12-02 14:38:43 +04:00 committed by Andrew Borodin
parent 56b76cecdf
commit 7866bf7342
3 changed files with 38 additions and 22 deletions

View File

@ -44,6 +44,7 @@
#include <config.h>
#include <errno.h>
#include <stdlib.h>
#include "lib/global.h"
#include "lib/strutil.h"
@ -529,24 +530,37 @@ vfs_print_message (const char *msg, ...)
void
vfs_setup_cwd (void)
{
char *current_dir;
vfs_path_t *tmp_vpath;
const vfs_path_element_t *path_element;
if (vfs_get_raw_current_dir () == NULL)
{
char *tmp;
current_dir = g_get_current_dir ();
vfs_set_raw_current_dir (vfs_path_from_str (current_dir));
g_free (current_dir);
tmp = g_get_current_dir ();
vfs_set_raw_current_dir (vfs_path_from_str (tmp));
g_free (tmp);
current_dir = getenv ("PWD");
tmp_vpath = vfs_path_from_str (current_dir);
if (tmp_vpath != NULL)
{
struct stat my_stat, my_stat2;
if (mc_global.vfs.cd_symlinks
&& mc_stat (tmp_vpath, &my_stat) == 0
&& mc_stat (vfs_get_raw_current_dir (), &my_stat2) == 0
&& my_stat.st_ino == my_stat2.st_ino && my_stat.st_dev == my_stat2.st_dev)
vfs_set_raw_current_dir (tmp_vpath);
else
vfs_path_free (tmp_vpath);
}
}
path_element = vfs_path_get_by_index (vfs_get_raw_current_dir (), -1);
if ((path_element->class->flags & VFSF_LOCAL) != 0)
{
char *current_dir;
vfs_path_t *tmp_vpath;
current_dir = g_get_current_dir ();
tmp_vpath = vfs_path_from_str (current_dir);
g_free (current_dir);

View File

@ -292,7 +292,6 @@ main (int argc, char *argv[])
vfs_init ();
vfs_plugins_init ();
vfs_setup_work_dir ();
/* Set up temporary directory after VFS initialization */
mc_tmpdir ();
@ -340,6 +339,23 @@ main (int argc, char *argv[])
load_setup ();
/* Must be done after load_setup because depends on mc_global.vfs.cd_symlinks */
vfs_setup_work_dir ();
/* Resolve the other_dir panel option. Must be done after vfs_setup_work_dir */
{
char *buffer;
vfs_path_t *vpath;
buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
vpath = vfs_path_from_str (buffer);
if (vfs_file_is_local (vpath))
saved_other_dir = buffer;
else
g_free (buffer);
vfs_path_free (vpath);
}
/* start check mc_global.display_codepage and mc_global.source_codepage */
check_codeset ();

View File

@ -43,8 +43,6 @@
#include "lib/util.h"
#include "lib/widget.h"
#include "lib/vfs/vfs.h"
#ifdef ENABLE_VFS_FTP
#include "src/vfs/ftpfs/ftpfs.h"
#endif
@ -991,18 +989,6 @@ load_setup (void)
if (startup_left_mode != view_listing && startup_right_mode != view_listing)
startup_left_mode = view_listing;
{
vfs_path_t *vpath;
buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
vpath = vfs_path_from_str (buffer);
if (vfs_file_is_local (vpath))
saved_other_dir = buffer;
else
g_free (buffer);
vfs_path_free (vpath);
}
boot_current_is_left = mc_config_get_bool (mc_panels_config, "Dirs", "current_is_left", TRUE);
/* Load time formats */