|
|
|
@ -1,14 +1,15 @@ |
|
|
|
|
#include "selfdrive/common/util.h" |
|
|
|
|
|
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
#include <dirent.h> |
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
|
#include <cerrno> |
|
|
|
|
#include <cstring> |
|
|
|
|
#include <dirent.h> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <sstream> |
|
|
|
|
#include <iomanip> |
|
|
|
|
#include <sstream> |
|
|
|
|
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
#include <sys/prctl.h> |
|
|
|
@ -121,6 +122,37 @@ bool file_exists(const std::string& fn) { |
|
|
|
|
return stat(fn.c_str(), &st) != -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool createDirectory(std::string dir, mode_t mode) { |
|
|
|
|
auto verify_dir = [](const std::string& dir) -> bool { |
|
|
|
|
struct stat st = {}; |
|
|
|
|
return (stat(dir.c_str(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR); |
|
|
|
|
}; |
|
|
|
|
// remove trailing /'s
|
|
|
|
|
while (dir.size() > 1 && dir.back() == '/') { |
|
|
|
|
dir.pop_back(); |
|
|
|
|
} |
|
|
|
|
// try to mkdir this directory
|
|
|
|
|
if (mkdir(dir.c_str(), mode) == 0) return true; |
|
|
|
|
if (errno == EEXIST) return verify_dir(dir); |
|
|
|
|
if (errno != ENOENT) return false; |
|
|
|
|
|
|
|
|
|
// mkdir failed because the parent dir doesn't exist, so try to create it
|
|
|
|
|
size_t slash = dir.rfind('/'); |
|
|
|
|
if ((slash == std::string::npos || slash < 1) || |
|
|
|
|
!createDirectory(dir.substr(0, slash), mode)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// try again
|
|
|
|
|
if (mkdir(dir.c_str(), mode) == 0) return true; |
|
|
|
|
return errno == EEXIST && verify_dir(dir); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool create_directories(const std::string& dir, mode_t mode) { |
|
|
|
|
if (dir.empty()) return false; |
|
|
|
|
return createDirectory(dir, mode); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::string getenv(const char* key, const char* default_val) { |
|
|
|
|
const char* val = ::getenv(key); |
|
|
|
|
return val ? val : default_val; |
|
|
|
|