Verified Commit 0d7d83e5 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

path resolution

add support for path resolution, this will be used to get canonical path.

More info at `man path_resolution`
parent 039c07d0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -6,13 +6,15 @@

#define PATH_MAX_LEN 4096 // 4k chars

constexpr char PSP = '/'; // PATH SEPARATOR


bool is_relative_path(const std::string& path);
bool is_absolute_path(const std::string& path);
bool has_trailing_slash(const std::string& path);

std::string path_to_relative(const std::string& root_path, const std::string& complete_path);
std::string prepend_path(const std::string& path, const char * raw_path);
std::string dirname(const std::string& path);
std::string get_current_working_dir();
std::vector<std::string> split_path(const std::string& path);

#endif //IFS_PATH_UTIL_HPP
+4 −0
Original line number Diff line number Diff line
@@ -92,6 +92,10 @@ extern void* libc_readdir;
extern void* libc_closedir;

extern void* libc_chdir;
extern void* libc_fchdir;

extern void* libc_getcwd;
extern void* libc_get_current_dir_name;

extern void* libc_realpath;

+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ class PreloadContext {
    void cwd(const std::string& path);
    const std::string& cwd() const;

    bool relativize_path(std::string& path) const;
    bool relativize_path(const char * raw_path, std::string& relative_path) const;

    const std::shared_ptr<OpenFileMap>& file_map() const;

+5 −0
Original line number Diff line number Diff line
#include <string>

bool resolve_path (const std::string& path, std::string& resolved);

std::string get_sys_cwd();
+45 −20
Original line number Diff line number Diff line
#include <global/path_util.hpp>
#include <unistd.h>
#include <system_error>
#include <cstring>
#include <cassert>
#include <sys/stat.h>


const constexpr char PSP('/'); // PATH SEPARATOR

bool is_relative_path(const std::string& path) {
    return (!path.empty()) &&
           (path.front() != PSP);
@@ -20,6 +20,43 @@ bool has_trailing_slash(const std::string& path) {
    return path.back() == PSP;
}

/* Add path prefix to a given C string.
 *
 * Returns a string composed by the `prefix_path`
 * followed by `raw_path`.
 *
 * This would return the same of:
 * ```
 * std::string(raw_path).append(prefix_path);
 * ```
 * But it is faster because it avoids to copy the `raw_path` twice.
 *
 *
 * Time cost approx: O(len(prefix_path)) + 2 O(len(raw_path))
 *
 * Example:
 * ```
 * prepend_path("/tmp/prefix", "./my/path") == "/tmp/prefix/./my/path"
 * ```
 */
std::string prepend_path(const std::string& prefix_path, const char * raw_path) {
    assert(!has_trailing_slash(prefix_path));
    std::size_t raw_len = std::strlen(raw_path);
    std::string res;
    res.reserve(prefix_path.size() + 1 + raw_len);
    res.append(prefix_path);
    res.push_back(PSP);
    res.append(raw_path, raw_len);
    return res;
}

/* Split a path into its components
 *
 * Returns a vector of the components of the given path.
 *
 * Example:
 *  split_path("/first/second/third") == ["first", "second", "third"]
 */
std::vector<std::string> split_path(const std::string& path) {
    std::vector<std::string> tokens;
    size_t start = std::string::npos;
@@ -35,6 +72,10 @@ std::vector<std::string> split_path(const std::string& path) {
    return tokens;
}





/* Make an absolute path relative to a root path
 *
 * Convert @absolute_path into a relative one with respect to the given @root_path.
@@ -86,19 +127,3 @@ std::string dirname(const std::string& path) {
    }
    return path.substr(0, parent_path_size);
}

std::string get_current_working_dir() {
    char temp[PATH_MAX_LEN];
    if(getcwd(temp, PATH_MAX_LEN) == NULL) {
        throw std::system_error(errno,
                                std::system_category(),
                                "Failed to retrieve current working directory");
    }
    // getcwd could return "(unreachable)<PATH>" in some cases
    if(temp[0] != '/') {
        throw std::runtime_error(
                "Current working directory is unreachable");
    }
    return {temp};
}
Loading