From: Joel Rosdahl Date: Wed, 12 Jul 2023 19:15:31 +0000 (+0200) Subject: refactor: Use std::filesystem::canonical X-Git-Tag: v4.9~131 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3cacab8daa1ca13a4f3d93096fe6550989b17182;p=thirdparty%2Fccache.git refactor: Use std::filesystem::canonical --- diff --git a/src/Config.cpp b/src/Config.cpp index 971faac8e..f7fef61ae 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -869,7 +869,7 @@ Config::set_value_in_file(const std::string& path, Config dummy_config; dummy_config.set_item(key, value, std::nullopt, false, ""); - const auto resolved_path = Util::real_path(path); + const auto resolved_path = util::real_path(path); const auto st = Stat::stat(resolved_path); if (!st) { Util::ensure_dir_exists(Util::dir_name(resolved_path)); diff --git a/src/Util.cpp b/src/Util.cpp index 2efbe2e99..61b65b697 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -96,21 +96,6 @@ find_first_ansi_csi_seq(std::string_view string) } } -size_t -path_max(const std::string& path) -{ -#ifdef PATH_MAX - (void)path; - return PATH_MAX; -#elif defined(MAXPATHLEN) - (void)path; - return MAXPATHLEN; -#elif defined(_PC_PATH_MAX) - long maxlen = pathconf(path.c_str(), _PC_PATH_MAX); - return maxlen >= 4096 ? maxlen : 4096; -#endif -} - template std::vector split_into(std::string_view string, @@ -159,7 +144,7 @@ rewrite_stderr_to_absolute_paths(std::string_view text) } else { std::string path(line.substr(0, path_end)); if (Stat::stat(path)) { - result += Util::real_path(path); + result += util::real_path(path); auto tail = line.substr(path_end); result.append(tail.data(), tail.length()); } else { @@ -582,7 +567,7 @@ make_relative_path(const std::string& base_dir, path = Util::dir_name(path); } const auto path_suffix = std::string(original_path.substr(path.length())); - const auto real_path = Util::real_path(std::string(path)); + const auto real_path = util::real_path(path); const auto add_relpath_candidates = [&](auto p) { const std::string normalized_path = @@ -737,47 +722,6 @@ parse_duration(std::string_view duration) } } -std::string -real_path(const std::string& path, bool return_empty_on_error) -{ - size_t buffer_size = path_max(path); - std::unique_ptr managed_buffer(new char[buffer_size]); - char* buffer = managed_buffer.get(); - char* resolved = nullptr; - -#ifdef HAVE_REALPATH - resolved = realpath(path.c_str(), buffer); -#elif defined(_WIN32) - const char* c_path = path.c_str(); - if (c_path[0] == '/') { - c_path++; // Skip leading slash. - } - HANDLE path_handle = CreateFile(c_path, - GENERIC_READ, - FILE_SHARE_READ, - nullptr, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - nullptr); - if (INVALID_HANDLE_VALUE != path_handle) { - bool ok = GetFinalPathNameByHandle( - path_handle, buffer, buffer_size, FILE_NAME_NORMALIZED); - CloseHandle(path_handle); - if (!ok) { - return path; - } - resolved = buffer + 4; // Strip \\?\ from the file name. - } else { - snprintf(buffer, buffer_size, "%s", c_path); - resolved = buffer; - } -#else -# error No realpath function available -#endif - - return resolved ? resolved : (return_empty_on_error ? "" : path); -} - std::string_view remove_extension(std::string_view path) { diff --git a/src/Util.hpp b/src/Util.hpp index 9ff59de73..bf7a0ec9b 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -179,12 +179,6 @@ std::string normalize_concrete_absolute_path(const std::string& path); // into seconds. Throws `core::Error` on error. uint64_t parse_duration(std::string_view duration); -// Return a normalized absolute path of `path`. On error (e.g. if the `path` -// doesn't exist) the empty string is returned if return_empty_on_error is true, -// otherwise `path` unmodified. -std::string real_path(const std::string& path, - bool return_empty_on_error = false); - // Return a view into `path` containing the given path without the filename // extension as determined by `get_extension()`. std::string_view remove_extension(std::string_view path); diff --git a/src/ccache.cpp b/src/ccache.cpp index 20bd454bd..d43cc0ddc 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -242,7 +242,7 @@ guess_compiler(std::string_view path) #ifndef _WIN32 // Follow symlinks to the real compiler to learn its name. We're not using - // Util::real_path in order to save some unnecessary stat calls. + // util::real_path in order to save some unnecessary stat calls. while (true) { std::error_code ec; auto symlink_target = fs::read_symlink(compiler_path, ec); @@ -1523,8 +1523,7 @@ hash_common_info(const Context& ctx, if (!ctx.args_info.profile_path.empty()) { dir = ctx.args_info.profile_path; } else { - dir = - Util::real_path(std::string(Util::dir_name(ctx.args_info.output_obj))); + dir = util::real_path(Util::dir_name(ctx.args_info.output_obj)); } std::string_view stem = Util::remove_extension(Util::base_name(ctx.args_info.output_obj)); diff --git a/src/execute.cpp b/src/execute.cpp index 2b3b499a0..10263ba12 100644 --- a/src/execute.cpp +++ b/src/execute.cpp @@ -367,7 +367,7 @@ find_executable_in_path(const std::string& name, } const auto real_exclude_path = - exclude_path ? Util::real_path(*exclude_path) : ""; + exclude_path ? util::real_path(*exclude_path) : ""; // Search the path list looking for the first compiler of the right name that // isn't us. @@ -396,7 +396,7 @@ find_executable_in_path(const std::string& name, access(candidate.c_str(), X_OK) == 0; #endif if (candidate_exists) { - const auto real_candidate = Util::real_path(candidate); + const auto real_candidate = util::real_path(candidate); if ((real_exclude_path.empty() || real_candidate != real_exclude_path) && !Util::is_ccache_executable(real_candidate)) { return candidate; diff --git a/src/util/path.cpp b/src/util/path.cpp index d1e6b7e85..5a9ab4add 100644 --- a/src/util/path.cpp +++ b/src/util/path.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Joel Rosdahl and other contributors +// Copyright (C) 2021-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -29,6 +29,8 @@ const char k_dev_null_path[] = "/dev/null"; const char k_path_delimiter[] = ":"; #endif +namespace fs = std::filesystem; + namespace util { const char* @@ -85,6 +87,14 @@ path_starts_with(std::string_view path, std::string_view prefix) return true; } +std::string +real_path(std::string_view path) +{ + std::error_code ec; + auto real_path = fs::canonical(path, ec).string(); + return ec ? std::string(path) : real_path; +} + std::vector split_path_list(std::string_view path_list) { diff --git a/src/util/path.hpp b/src/util/path.hpp index 6fa3291e0..476fbcc1d 100644 --- a/src/util/path.hpp +++ b/src/util/path.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Joel Rosdahl and other contributors +// Copyright (C) 2021-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -38,6 +38,10 @@ bool is_full_path(std::string_view path); // Windows bool path_starts_with(std::string_view path, std::string_view prefix); +// Return a normalized absolute path of `path`. On error (e.g. if the `path` +// doesn't exist) path is returned unmodified. +std::string real_path(std::string_view path); + // Split a list of paths (such as the content of $PATH on Unix platforms or // %PATH% on Windows platforms) into paths. std::vector split_path_list(std::string_view path_list); diff --git a/test/run b/test/run index 43a573125..7a27d38a7 100755 --- a/test/run +++ b/test/run @@ -473,9 +473,13 @@ TEST() { remove_cache rm -rf $ABS_TESTDIR/run $ABS_TESTDIR/run.real - # Verify that tests behave well when apparent CWD != actual CWD. - mkdir $ABS_TESTDIR/run.real - ln -s run.real $ABS_TESTDIR/run + if $HOST_OS_WINDOWS; then + mkdir $ABS_TESTDIR/run + else + # Verify that tests behave well when apparent CWD != actual CWD. + mkdir $ABS_TESTDIR/run.real + ln -s run.real $ABS_TESTDIR/run + fi cd $ABS_TESTDIR/run if type SUITE_${suite_name}_SETUP >/dev/null 2>&1; then