From e045b045da837714ff6bc80c9b994eed4b296e6b Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Fri, 28 Sep 2018 10:14:27 -0500 Subject: [PATCH] Move get_runtime_path() to env.cpp and expose it in env.h It was previously a file-local static function in env_universal.cpp. --- src/env.cpp | 62 ++++++++++++++++++++++++++++++++++++ src/env.h | 3 ++ src/env_universal_common.cpp | 58 +-------------------------------- src/env_universal_common.h | 2 ++ 4 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/env.cpp b/src/env.cpp index fc00031f1..80af2f2e2 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1631,6 +1631,68 @@ maybe_t env_vars_snapshot_t::get(const wcstring &key) const { return iter->second; } + +#if !defined(__APPLE__) && !defined(__CYGWIN__) +/// Check, and create if necessary, a secure runtime path. Derived from tmux.c in tmux +/// (http://tmux.sourceforge.net/). +static int check_runtime_path(const char *path) { + // Copyright (c) 2007 Nicholas Marriott + // + // Permission to use, copy, modify, and distribute this software for any + // purpose with or without fee is hereby granted, provided that the above + // copyright notice and this permission notice appear in all copies. + // + // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + // WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + // IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + // OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + struct stat statpath; + uid_t uid = geteuid(); + + if (mkdir(path, S_IRWXU) != 0 && errno != EEXIST) return errno; + if (lstat(path, &statpath) != 0) return errno; + if (!S_ISDIR(statpath.st_mode) || statpath.st_uid != uid || + (statpath.st_mode & (S_IRWXG | S_IRWXO)) != 0) + return EACCES; + return 0; +} +#endif + +/// Return the path of an appropriate runtime data directory. +wcstring env_get_runtime_path() { + wcstring result; + const char *dir = getenv("XDG_RUNTIME_DIR"); + + // Check that the path is actually usable. Technically this is guaranteed by the fdo spec but in + // practice it is not always the case: see #1828 and #2222. + int mode = R_OK | W_OK | X_OK; + if (dir != NULL && access(dir, mode) == 0 && check_runtime_path(dir) == 0) { + result = str2wcstring(dir); + } else { + // Don't rely on $USER being set, as setup_user() has not yet been called. + // See https://github.com/fish-shell/fish-shell/issues/5180 + const char *uname = getpwuid(geteuid())->pw_name; + // /tmp/fish.user + std::string tmpdir = "/tmp/fish."; + tmpdir.append(uname); + +#if !defined(__APPLE__) && !defined(__CYGWIN__) + if (check_runtime_path(tmpdir.c_str()) != 0) { + debug(0, L"Runtime path not available."); + debug(0, L"Try deleting the directory %s and restarting fish.", tmpdir.c_str()); + return result; + } +#endif + + result = str2wcstring(tmpdir); + } + return result; +} + + const wchar_t *const env_vars_snapshot_t::highlighting_keys[] = {L"PATH", L"CDPATH", L"fish_function_path", NULL}; diff --git a/src/env.h b/src/env.h index aac7b8f7a..6a7ddb15f 100644 --- a/src/env.h +++ b/src/env.h @@ -197,4 +197,7 @@ extern bool term_has_xn; // does the terminal have the "eat_newline_glitch" /// Returns true if we think the terminal supports setting its title. bool term_supports_setting_title(); + +/// Gets a path appropriate for runtime storage +wcstring env_get_runtime_path(); #endif diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 3e07ff9c6..c8747e60b 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -101,71 +101,15 @@ static maybe_t default_vars_path() { return none(); } -#if !defined(__APPLE__) && !defined(__CYGWIN__) -/// Check, and create if necessary, a secure runtime path. Derived from tmux.c in tmux -/// (http://tmux.sourceforge.net/). -static int check_runtime_path(const char *path) { - // Copyright (c) 2007 Nicholas Marriott - // - // Permission to use, copy, modify, and distribute this software for any - // purpose with or without fee is hereby granted, provided that the above - // copyright notice and this permission notice appear in all copies. - // - // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - // WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - // IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - // OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - struct stat statpath; - uid_t uid = geteuid(); - - if (mkdir(path, S_IRWXU) != 0 && errno != EEXIST) return errno; - if (lstat(path, &statpath) != 0) return errno; - if (!S_ISDIR(statpath.st_mode) || statpath.st_uid != uid || - (statpath.st_mode & (S_IRWXG | S_IRWXO)) != 0) - return EACCES; - return 0; -} - -/// Return the path of an appropriate runtime data directory. -static wcstring get_runtime_path() { - wcstring result; - const char *dir = getenv("XDG_RUNTIME_DIR"); - - // Check that the path is actually usable. Technically this is guaranteed by the fdo spec but in - // practice it is not always the case: see #1828 and #2222. - int mode = R_OK | W_OK | X_OK; - if (dir != NULL && access(dir, mode) == 0 && check_runtime_path(dir) == 0) { - result = str2wcstring(dir); - } else { - // Don't rely on $USER being set, as setup_user() has not yet been called. - // See https://github.com/fish-shell/fish-shell/issues/5180 - const char *uname = getpwuid(geteuid())->pw_name; - // /tmp/fish.user - std::string tmpdir = "/tmp/fish."; - tmpdir.append(uname); - if (check_runtime_path(tmpdir.c_str()) != 0) { - debug(0, L"Runtime path not available."); - debug(0, L"Try deleting the directory %s and restarting fish.", tmpdir.c_str()); - } else { - result = str2wcstring(tmpdir); - } - } - return result; -} - /// Returns a "variables" file in the appropriate runtime directory. This is called infrequently and /// so does not need to be cached. static wcstring default_named_pipe_path() { - wcstring result = get_runtime_path(); + wcstring result = env_get_runtime_path(); if (!result.empty()) { result.append(L"/fish_universal_variables"); } return result; } -#endif /// Test if the message msg contains the command cmd. static bool match(const wchar_t *msg, const wchar_t *cmd) { diff --git a/src/env_universal_common.h b/src/env_universal_common.h index 512bf7107..0f0f723d0 100644 --- a/src/env_universal_common.h +++ b/src/env_universal_common.h @@ -161,6 +161,8 @@ class universal_notifier_t { virtual bool notification_fd_became_readable(int fd); }; +wcstring get_runtime_path(); + // Environment variable for requesting a particular universal notifier. See // fetch_default_strategy_from_environment for names. #define UNIVERSAL_NOTIFIER_ENV_NAME "fish_universal_notifier"