diff --git a/lib/vfs/vfs.c b/lib/vfs/vfs.c index f14e22ab3..6e5d8a229 100644 --- a/lib/vfs/vfs.c +++ b/lib/vfs/vfs.c @@ -44,6 +44,7 @@ #include #include +#include #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); diff --git a/src/main.c b/src/main.c index 00e1a172d..76932b984 100644 --- a/src/main.c +++ b/src/main.c @@ -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 (); diff --git a/src/setup.c b/src/setup.c index 2da22b095..a52349246 100644 --- a/src/setup.c +++ b/src/setup.c @@ -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 */ diff --git a/tests/lib/vfs/Makefile.am b/tests/lib/vfs/Makefile.am index 226f3f650..8b7b844e3 100644 --- a/tests/lib/vfs/Makefile.am +++ b/tests/lib/vfs/Makefile.am @@ -26,6 +26,7 @@ TESTS = \ vfs_path_from_str_flags \ vfs_path_string_convert \ vfs_prefix_to_class \ + vfs_setup_cwd \ vfs_split \ vfs_s_get_path @@ -66,6 +67,9 @@ tempdir_SOURCES = \ vfs_get_encoding_SOURCES = \ vfs_get_encoding.c +vfs_setup_cwd_SOURCES = \ + vfs_setup_cwd.c + vfs_split_SOURCES = \ vfs_split.c diff --git a/tests/lib/vfs/vfs_setup_cwd.c b/tests/lib/vfs/vfs_setup_cwd.c new file mode 100644 index 000000000..432143198 --- /dev/null +++ b/tests/lib/vfs/vfs_setup_cwd.c @@ -0,0 +1,165 @@ +/* + lib/vfs - test vfs_setup_cwd() functionality + + Copyright (C) 2013 + The Free Software Foundation, Inc. + + Written by: + Slava Zanko , 2013 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define TEST_SUITE_NAME "/lib/vfs" + +#include "tests/mctest.h" + +#include + +#include "lib/strutil.h" +#include "lib/vfs/xdirentry.h" +#include "src/vfs/local/local.c" + +/* --------------------------------------------------------------------------------------------- */ + +/* @Mock */ +char * +g_get_current_dir (void) +{ + return g_strdup ("/some/path"); +} + +/* --------------------------------------------------------------------------------------------- */ + +static gboolean mc_stat__is_2nd_call_different = FALSE; +static gboolean mc_stat__call_count = 0; + +/* @Mock */ +int +mc_stat (const vfs_path_t * vpath, struct stat *my_stat) +{ + (void) vpath; + + if (mc_stat__call_count++ > 1 && mc_stat__is_2nd_call_different) + { + my_stat->st_ino = 2; + my_stat->st_dev = 22; + } + else + { + my_stat->st_ino = 1; + my_stat->st_dev = 11; + } + if (mc_stat__call_count > 2) + { + mc_stat__call_count = 0; + } + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @Before */ +static void +setup (void) +{ + str_init_strings (NULL); + + vfs_init (); + init_localfs (); + vfs_setup_work_dir (); +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @After */ +static void +teardown (void) +{ + vfs_shut (); + str_uninit_strings (); +} + +/* --------------------------------------------------------------------------------------------- */ + +/* @DataSource("test_vfs_setup_cwd_symlink_ds") */ +/* *INDENT-OFF* */ +static const struct test_vfs_setup_cwd_symlink_ds +{ + gboolean is_2nd_call_different; + const char *expected_result; +} test_vfs_setup_cwd_symlink_ds[] = +{ + { /* 0. */ + TRUE, + "/some/path" + }, + { /* 1. */ + FALSE, + "/some/path2" + }, +}; +/* *INDENT-ON* */ + +/* @Test */ +/* *INDENT-OFF* */ +START_PARAMETRIZED_TEST (test_vfs_setup_cwd_symlink, test_vfs_setup_cwd_symlink_ds) +/* *INDENT-ON* */ +{ + /* given */ + vfs_set_raw_current_dir (NULL); + mc_stat__is_2nd_call_different = data->is_2nd_call_different; + mc_stat__call_count = 0; + setenv ("PWD", "/some/path2", 1); + + /* when */ + vfs_setup_cwd (); + + /* then */ + mctest_assert_str_eq (vfs_path_as_str (vfs_get_raw_current_dir ()), data->expected_result); +} +/* *INDENT-OFF* */ +END_PARAMETRIZED_TEST +/* *INDENT-ON* */ + +/* --------------------------------------------------------------------------------------------- */ + +int +main (void) +{ + int number_failed; + + Suite *s = suite_create (TEST_SUITE_NAME); + TCase *tc_core = tcase_create ("Core"); + SRunner *sr; + + tcase_add_checked_fixture (tc_core, setup, teardown); + + /* Add new tests here: *************** */ + mctest_add_parameterized_test (tc_core, test_vfs_setup_cwd_symlink, + test_vfs_setup_cwd_symlink_ds); + /* *********************************** */ + + suite_add_tcase (s, tc_core); + sr = srunner_create (s); + srunner_set_log (sr, "vfs_setup_cwd.log"); + srunner_run_all (sr, CK_NOFORK); + number_failed = srunner_ntests_failed (sr); + srunner_free (sr); + return (number_failed == 0) ? 0 : 1; +} + +/* --------------------------------------------------------------------------------------------- */