From: Joel Rosdahl Date: Tue, 11 Feb 2020 20:56:02 +0000 (+0100) Subject: Implement Util::read_link, replacing legacy x_readlink X-Git-Tag: v4.0~620 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ead2edebf08a6e3088ee6ecc014ffb7939d4e707;p=thirdparty%2Fccache.git Implement Util::read_link, replacing legacy x_readlink --- diff --git a/src/Util.cpp b/src/Util.cpp index 59024626c..216559d76 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -281,6 +281,21 @@ read_file(const std::string& path) std::istreambuf_iterator()); } +#ifndef _WIN32 +std::string +read_link(const std::string& path) +{ + size_t buffer_size = path_max(path.c_str()); + std::unique_ptr buffer(new char[buffer_size]); + ssize_t len = readlink(path.c_str(), buffer.get(), buffer_size - 1); + if (len == -1) { + return ""; + } + buffer[len] = 0; + return buffer.get(); +} +#endif + std::string real_path(const std::string& path, bool return_empty_on_error) { diff --git a/src/Util.hpp b/src/Util.hpp index 1d70aadcf..f4576bc41 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -189,6 +189,11 @@ int parse_int(const std::string& value); // Throws Error on error. std::string read_file(const std::string& path); +#ifndef _WIN32 +// Like readlink(2) but returns the string (or the empty string on failure). +std::string read_link(const std::string& path); +#endif + // Return a canonicalized 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. diff --git a/src/legacy_util.cpp b/src/legacy_util.cpp index 80832c20f..48840a073 100644 --- a/src/legacy_util.cpp +++ b/src/legacy_util.cpp @@ -54,21 +54,6 @@ # endif #endif -static long -path_max(const char* 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, _PC_PATH_MAX); - return maxlen >= 4096 ? maxlen : 4096; -#endif -} - // Something went badly wrong! void fatal(const char* format, ...) @@ -1008,23 +993,6 @@ x_try_unlink(const char* path) return do_x_unlink(path, false); } -#ifndef _WIN32 -// Like readlink() but returns the string or NULL on failure. Caller frees. -char* -x_readlink(const char* path) -{ - long maxlen = path_max(path); - char* buf = static_cast(x_malloc(maxlen)); - ssize_t len = readlink(path, buf, maxlen - 1); - if (len == -1) { - free(buf); - return NULL; - } - buf[len] = 0; - return buf; -} -#endif - // Reads the content of a file. Size hint 0 means no hint. Returns true on // success, otherwise false. bool diff --git a/src/legacy_util.hpp b/src/legacy_util.hpp index b21a25765..7a9953901 100644 --- a/src/legacy_util.hpp +++ b/src/legacy_util.hpp @@ -66,9 +66,6 @@ int x_rename(const char* oldpath, const char* newpath); int tmp_unlink(const char* path); int x_unlink(const char* path); int x_try_unlink(const char* path); -#ifndef _WIN32 -char* x_readlink(const char* path); -#endif bool read_file(const char* path, size_t size_hint, char** data, size_t* size); char* read_text_file(const char* path, size_t size_hint); char* subst_env_in_string(const char* str, char** errmsg); diff --git a/src/lockfile.cpp b/src/lockfile.cpp index 390bb587f..6092e6ad4 100644 --- a/src/lockfile.cpp +++ b/src/lockfile.cpp @@ -123,8 +123,8 @@ lockfile_acquire(const char* path, unsigned staleness_limit) goto out; } free(content); - content = x_readlink(lockfile); - if (!content) { + content = x_strdup(Util::read_link(lockfile).c_str()); + if (str_eq(content, "")) { if (errno == ENOENT) { // The symlink was removed after the symlink() call above, so retry // acquiring it. diff --git a/unittest/test_lockfile.cpp b/unittest/test_lockfile.cpp index e389c954a..7ad4a2b7d 100644 --- a/unittest/test_lockfile.cpp +++ b/unittest/test_lockfile.cpp @@ -19,6 +19,7 @@ // This file contains tests for functions in lockfile.c. #include "../src/Stat.hpp" +#include "../src/Util.hpp" #include "../src/legacy_util.hpp" #include "../src/lockfile.hpp" #include "framework.hpp" @@ -61,7 +62,7 @@ TEST(lock_breaking) #if defined(_WIN32) || defined(__CYGWIN__) p = read_text_file("test.lock", 0); #else - p = x_readlink("test.lock"); + p = x_strdup(Util::read_link("test.lock").c_str()); #endif CHECK(p); CHECK(!str_eq(p, "foo"));