Verified Commit 176c04a7 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Store CWD in environment to surivive across exec

parent ffc27e88
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3,3 +3,10 @@
bool resolve_path (const std::string& path, std::string& resolved);

std::string get_sys_cwd();
void set_sys_cwd(const std::string& path);

void set_env_cwd(const std::string& path);
void unset_env_cwd();

void init_cwd();
void set_cwd(const std::string& path, bool internal);
+11 −18
Original line number Diff line number Diff line
@@ -1298,8 +1298,8 @@ int chdir(const char* path){

    CTX->log()->trace("{}() called with path '{}'", __func__, path);
    std::string rel_path;
    const char* fake_path;
    if (CTX->relativize_path(path, rel_path)) {
    bool internal = CTX->relativize_path(path, rel_path);
    if (internal) {
        //path falls in our namespace
        struct stat st;
        if(adafs_stat(rel_path, &st) != 0) {
@@ -1312,7 +1312,6 @@ int chdir(const char* path){
            errno = ENOTDIR;
            return -1;
        }
        fake_path = CTX->mountdir().c_str();
        //TODO get complete path from relativize_path instead of
        // removing mountdir and then adding again here
        rel_path.insert(0, CTX->mountdir());
@@ -1320,17 +1319,12 @@ int chdir(const char* path){
            // open_dir is '/'
            rel_path.pop_back();
        }
    } else {
        fake_path = rel_path.c_str();
    }

    if(LIBC_FUNC(chdir, fake_path)) {
        CTX->log()->error("{}() failed to change dir: {}",
               __func__, std::strerror(errno));
    try {
        set_cwd(rel_path, internal);
    } catch (const std::system_error& se) {
        return -1;
    }

    CTX->cwd(rel_path);
    return 0;
}

@@ -1351,23 +1345,22 @@ int fchdir(int fd) {
            return -1;
        }

        if (LIBC_FUNC(chdir, CTX->mountdir().c_str())) {
            CTX->log()->error("{}() failed to change dir: {}",
                   __func__, std::strerror(errno));
            return -1;
        }

        std::string new_path = CTX->mountdir() + open_dir->path();
        if (has_trailing_slash(new_path)) {
            // open_dir is '/'
            new_path.pop_back();
        }
        CTX->cwd(new_path);
        try {
            set_cwd(new_path, true);
        } catch (const std::system_error& se) {
            return -1;
        }
    } else {
        if(LIBC_FUNC(fchdir, fd) != 0) {
            CTX->log()->error("{}() failed to change dir: {}",
                    __func__, std::strerror(errno));
        }
        unset_env_cwd();
        CTX->cwd(get_sys_cwd());
    }
    return 0;
+19 −2
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@
#include <preload/passthrough.hpp>
#include <preload/preload_util.hpp>

#include <fstream>

enum class Margo_mode {
    RPC, IPC
};
@@ -300,6 +302,20 @@ void init_logging() {
    CTX->log(spdlog::get(logger_names.at(0)));
}

void log_prog_name() {
    std::string line;
    std::ifstream cmdline("/proc/self/cmdline");
    if (!cmdline.is_open()) {
        CTX->log()->error("Unable to open cmdline file");
        throw runtime_error("Unable to open cmdline file");
    }
    if(!getline(cmdline, line)) {
        throw runtime_error("Unable to read cmdline file");
    }
    CTX->log()->info("Command to itercept: '{}'", line);
    cmdline.close();
}

/**
 * Called initially ONCE when preload library is used with the LD_PRELOAD environment variable
 */
@@ -307,7 +323,8 @@ void init_preload() {
    init_passthrough_if_needed();
    init_logging();
    CTX->log()->debug("Initialized logging subsystem");
    CTX->cwd(get_sys_cwd());
    log_prog_name();
    init_cwd();
    CTX->log()->debug("Current working directory: '{}'", CTX->cwd());
    if (get_daemon_pid() == -1 || CTX->mountdir().empty()) {
        cerr << "ADA-FS daemon not running or mountdir could not be loaded. Check adafs_preload.log" << endl;
+53 −0
Original line number Diff line number Diff line
@@ -109,3 +109,56 @@ std::string get_sys_cwd() {
    }
    return {temp};
}

void set_sys_cwd(const std::string& path) {
    CTX->log()->debug("{}() to '{}'", __func__, path);
    if (LIBC_FUNC(chdir, path.c_str())) {
        CTX->log()->error("{}() failed to set system current working directory: {}",
                __func__, std::strerror(errno));
        throw std::system_error(errno,
                                std::system_category(),
                                "Failed to set system current working directory");
    }
}

void set_env_cwd(const std::string& path) {
    CTX->log()->debug("{}() to '{}'", __func__, path);
    if(setenv("ADAFS_CWD", path.c_str(), 1)) {
        CTX->log()->error("{}() failed to set environment current working directory: {}",
                __func__, std::strerror(errno));
        throw std::system_error(errno,
                                std::system_category(),
                                "Failed to set environment current working directory");
    }
}

void unset_env_cwd() {
    CTX->log()->debug("{}()", __func__);
    if(unsetenv("ADAFS_CWD")) {
        CTX->log()->error("{}() failed to unset environment current working directory: {}",
                __func__, std::strerror(errno));
        throw std::system_error(errno,
                                std::system_category(),
                                "Failed to unset environment current working directory");
    }
}

void init_cwd() {
    const char* env_cwd = std::getenv("ADAFS_CWD");
    if (env_cwd != nullptr) {
        CTX->cwd(env_cwd);
    } else {
        CTX->cwd(get_sys_cwd());
    }
}

void set_cwd(const std::string& path, bool internal) {
    if(internal) {
        set_sys_cwd(CTX->mountdir());
        set_env_cwd(path);
    } else {
        set_sys_cwd(path);
        unset_env_cwd();
    }
    CTX->cwd(path);
}