diff --git a/selfdrive/common/params.cc b/selfdrive/common/params.cc index 1bb719874c..0d7534554b 100644 --- a/selfdrive/common/params.cc +++ b/selfdrive/common/params.cc @@ -49,6 +49,7 @@ static int fsync_dir(const char* path){ return result; } +// TODO: replace by std::filesystem::create_directories static int mkdir_p(std::string path) { char * _path = (char *)path.c_str(); @@ -70,18 +71,51 @@ static int mkdir_p(std::string path) { return 0; } -static int ensure_dir_exists(std::string path) { - // TODO: replace by std::filesystem::create_directories - return mkdir_p(path.c_str()); -} +static bool ensure_params_path(const std::string ¶m_path, const std::string &key_path) { + // Make sure params path exists + if (!util::file_exists(param_path) && mkdir_p(param_path) != 0) { + return false; + } + + // See if the symlink exists, otherwise create it + if (!util::file_exists(key_path)) { + // 1) Create temp folder + // 2) Set permissions + // 3) Symlink it to temp link + // 4) Move symlink to /d + + std::string tmp_path = param_path + "/.tmp_XXXXXX"; + // this should be OK since mkdtemp just replaces characters in place + char *tmp_dir = mkdtemp((char *)tmp_path.c_str()); + if (tmp_dir == NULL) { + return false; + } + + if (chmod(tmp_dir, 0777) != 0) { + return false; + } + + std::string link_path = std::string(tmp_dir) + ".link"; + if (symlink(tmp_dir, link_path.c_str()) != 0) { + return false; + } + // don't return false if it has been created by other + if (rename(link_path.c_str(), key_path.c_str()) != 0 && errno != EEXIST) { + return false; + } + } -Params::Params(bool persistent_param){ - params_path = persistent_param ? persistent_params_path : default_params_path; + // Ensure permissions are correct in case we didn't create the symlink + return chmod(key_path.c_str(), 0777) == 0; } -Params::Params(const std::string &path) { - params_path = path; +Params::Params(bool persistent_param) : Params(persistent_param ? persistent_params_path : default_params_path) {} + +Params::Params(const std::string &path) : params_path(path) { + if (!ensure_params_path(params_path, params_path + "/d")) { + throw std::runtime_error(util::string_format("Failed to ensure params path, errno=%d", errno)); + } } int Params::put(const char* key, const char* value, size_t value_size) { @@ -99,52 +133,6 @@ int Params::put(const char* key, const char* value, size_t value_size) { std::string tmp_path; ssize_t bytes_written; - // Make sure params path exists - result = ensure_dir_exists(params_path); - if (result < 0) { - goto cleanup; - } - - // See if the symlink exists, otherwise create it - path = params_path + "/d"; - struct stat st; - if (stat(path.c_str(), &st) == -1) { - // Create temp folder - path = params_path + "/.tmp_XXXXXX"; - - char *t = mkdtemp((char*)path.c_str()); - if (t == NULL){ - goto cleanup; - } - std::string tmp_dir(t); - - // Set permissions - result = chmod(tmp_dir.c_str(), 0777); - if (result < 0) { - goto cleanup; - } - - // Symlink it to temp link - tmp_path = tmp_dir + ".link"; - result = symlink(tmp_dir.c_str(), tmp_path.c_str()); - if (result < 0) { - goto cleanup; - } - - // Move symlink to /d - path = params_path + "/d"; - result = rename(tmp_path.c_str(), path.c_str()); - if (result < 0) { - goto cleanup; - } - } else { - // Ensure permissions are correct in case we didn't create the symlink - result = chmod(path.c_str(), 0777); - if (result < 0) { - goto cleanup; - } - } - // Write value to temp. tmp_path = params_path + "/.tmp_value_XXXXXX"; tmp_fd = mkstemp((char*)tmp_path.c_str());