diff options
author | 2016-12-07 12:40:40 +0000 | |
---|---|---|
committer | 2016-12-07 12:53:56 +0000 | |
commit | 227369a44a1061cfb26913cc2609c27801482368 (patch) | |
tree | 14f7e974d2b0ee706dbdd3a6663c4ab4ea93b306 /src/main/cpp | |
parent | 12474d03da2b49447efd67e6b2ac93cd43539ec4 (diff) |
move MakeDirectories() into file_platform.h
This way we can remove the dependency on blaze_util (which is Bazel's
client specific) from singlejar.
This work was made possible by commit 49970e0136d0: ("Bazel client:
platform-specific {Read,Write}File").
--
Change-Id: I6e95fb9119a271e4d48cbe2eefc1d5354ee188aa
Reviewed-on: https://cr.bazel.build/7650
PiperOrigin-RevId: 141294165
MOS_MIGRATED_REVID=141294165
Diffstat (limited to 'src/main/cpp')
-rw-r--r-- | src/main/cpp/blaze.cc | 8 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_platform.h | 5 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_posix.cc | 97 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_windows.cc | 104 | ||||
-rw-r--r-- | src/main/cpp/util/file_platform.h | 5 | ||||
-rw-r--r-- | src/main/cpp/util/file_posix.cc | 94 | ||||
-rw-r--r-- | src/main/cpp/util/file_windows.cc | 102 |
7 files changed, 207 insertions, 208 deletions
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 6f63e16c1d..4c7b40131d 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -714,7 +714,7 @@ static void StartServerAndConnect(BlazeServer *server) { // The server dir has the socket, so we don't allow access by other // users. - if (!MakeDirectories(server_dir, 0700)) { + if (!blaze_util::MakeDirectories(server_dir, 0700)) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "server directory '%s' could not be created", server_dir.c_str()); } @@ -799,7 +799,7 @@ class ExtractBlazeZipProcessor : public devtools_ijar::ZipExtractorProcessor { virtual void Process(const char *filename, const devtools_ijar::u4 attr, const devtools_ijar::u1 *data, const size_t size) { string path = blaze_util::JoinPath(embedded_binaries_, filename); - if (!MakeDirectories(blaze_util::Dirname(path), 0777)) { + if (!blaze_util::MakeDirectories(blaze_util::Dirname(path), 0777)) { pdie(blaze_exit_code::INTERNAL_ERROR, "couldn't create '%s'", path.c_str()); } @@ -820,7 +820,7 @@ class ExtractBlazeZipProcessor : public devtools_ijar::ZipExtractorProcessor { static void ActuallyExtractData(const string &argv0, const string &embedded_binaries) { ExtractBlazeZipProcessor processor(embedded_binaries); - if (!MakeDirectories(embedded_binaries, 0777)) { + if (!blaze_util::MakeDirectories(embedded_binaries, 0777)) { pdie(blaze_exit_code::INTERNAL_ERROR, "couldn't create '%s'", embedded_binaries.c_str()); } @@ -1177,7 +1177,7 @@ static void ComputeBaseDirectories(const string &self_path) { const char *output_base = globals->options->output_base.c_str(); if (!blaze_util::PathExists(globals->options->output_base)) { - if (!MakeDirectories(globals->options->output_base, 0777)) { + if (!blaze_util::MakeDirectories(globals->options->output_base, 0777)) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Output base directory '%s' could not be created", output_base); diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h index 0e0c1665ca..3f7a8e3522 100644 --- a/src/main/cpp/blaze_util_platform.h +++ b/src/main/cpp/blaze_util_platform.h @@ -175,11 +175,6 @@ std::string GetHashedBaseDir(const std::string& root, // user, and not accessible to anyone else. void CreateSecureOutputRoot(const std::string& path); -// mkdir -p path. All newly created directories use the given mode. -// `mode` should be an octal permission mask, e.g. 0755 -// Returns false on failure, sets errno. -bool MakeDirectories(const std::string &path, unsigned int mode); - std::string GetEnv(const std::string& name); void SetEnv(const std::string& name, const std::string& value); diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc index 99360d70fe..ff4e99fc35 100644 --- a/src/main/cpp/blaze_util_posix.cc +++ b/src/main/cpp/blaze_util_posix.cc @@ -320,7 +320,7 @@ void CreateSecureOutputRoot(const string& path) { const char* root = path.c_str(); struct stat fileinfo = {}; - if (!MakeDirectories(root, 0755)) { + if (!blaze_util::MakeDirectories(root, 0755)) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "mkdir('%s')", root); } @@ -357,101 +357,6 @@ void CreateSecureOutputRoot(const string& path) { ExcludePathFromBackup(root); } -// Runs "stat" on `path`. Returns -1 and sets errno if stat fails or -// `path` isn't a directory. If check_perms is true, this will also -// make sure that `path` is owned by the current user and has `mode` -// permissions (observing the umask). It attempts to run chmod to -// correct the mode if necessary. If `path` is a symlink, this will -// check ownership of the link, not the underlying directory. -static bool GetDirectoryStat(const string& path, mode_t mode, - bool check_perms) { - struct stat filestat = {}; - if (stat(path.c_str(), &filestat) == -1) { - return false; - } - - if (!S_ISDIR(filestat.st_mode)) { - errno = ENOTDIR; - return false; - } - - if (check_perms) { - // If this is a symlink, run checks on the link. (If we did lstat above - // then it would return false for ISDIR). - struct stat linkstat = {}; - if (lstat(path.c_str(), &linkstat) != 0) { - return false; - } - if (linkstat.st_uid != geteuid()) { - // The directory isn't owned by me. - errno = EACCES; - return false; - } - - mode_t mask = umask(022); - umask(mask); - mode = (mode & ~mask); - if ((filestat.st_mode & 0777) != mode - && chmod(path.c_str(), mode) == -1) { - // errno set by chmod. - return false; - } - } - return true; -} - -static bool MakeDirectories(const string& path, mode_t mode, bool childmost) { - if (path.empty() || path == "/") { - errno = EACCES; - return false; - } - - bool stat_succeeded = GetDirectoryStat(path, mode, childmost); - if (stat_succeeded) { - return true; - } - - if (errno == ENOENT) { - // Path does not exist, attempt to create its parents, then it. - string parent = blaze_util::Dirname(path); - if (!MakeDirectories(parent, mode, false)) { - // errno set by stat. - return false; - } - - if (mkdir(path.c_str(), mode) == -1) { - if (errno == EEXIST) { - if (childmost) { - // If there are multiple bazel calls at the same time then the - // directory could be created between the MakeDirectories and mkdir - // calls. This is okay, but we still have to check the permissions. - return GetDirectoryStat(path, mode, childmost); - } else { - // If this isn't the childmost directory, we don't care what the - // permissions were. If it's not even a directory then that error will - // get caught when we attempt to create the next directory down the - // chain. - return true; - } - } - // errno set by mkdir. - return false; - } - return true; - } - - return stat_succeeded; -} - -// mkdir -p path. Returns 0 if the path was created or already exists and could -// be chmod-ed to exactly the given permissions. If final part of the path is a -// symlink, this ensures that the destination of the symlink has the desired -// permissions. It also checks that the directory or symlink is owned by us. -// On failure, this returns -1 and sets errno. -bool MakeDirectories(const string& path, unsigned int mode) { - return MakeDirectories(path, mode, true); -} - string GetEnv(const string& name) { char* result = getenv(name.c_str()); return result != NULL ? string(result) : ""; diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc index 28ee9db7fe..3e2ae3b7d3 100644 --- a/src/main/cpp/blaze_util_windows.cc +++ b/src/main/cpp/blaze_util_windows.cc @@ -1030,7 +1030,7 @@ void CreateSecureOutputRoot(const string& path) { const char* root = path.c_str(); struct stat fileinfo = {}; - if (!MakeDirectories(root, 0755)) { + if (!blaze_util::MakeDirectories(root, 0755)) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "mkdir('%s')", root); } @@ -1068,108 +1068,6 @@ void CreateSecureOutputRoot(const string& path) { #endif // COMPILER_MSVC } -#ifdef COMPILER_MSVC -bool MakeDirectories(const string& path, unsigned int mode) { - // TODO(bazel-team): implement this. - pdie(255, "blaze::MakeDirectories is not implemented on Windows"); - return false; -} -#else // not COMPILER_MSVC -// Runs "stat" on `path`. Returns -1 and sets errno if stat fails or -// `path` isn't a directory. If check_perms is true, this will also -// make sure that `path` is owned by the current user and has `mode` -// permissions (observing the umask). It attempts to run chmod to -// correct the mode if necessary. If `path` is a symlink, this will -// check ownership of the link, not the underlying directory. -static bool GetDirectoryStat(const string& path, mode_t mode, - bool check_perms) { - struct stat filestat = {}; - if (stat(path.c_str(), &filestat) == -1) { - return false; - } - - if (!S_ISDIR(filestat.st_mode)) { - errno = ENOTDIR; - return false; - } - - if (check_perms) { - // If this is a symlink, run checks on the link. (If we did lstat above - // then it would return false for ISDIR). - struct stat linkstat = {}; - if (lstat(path.c_str(), &linkstat) != 0) { - return false; - } - if (linkstat.st_uid != geteuid()) { - // The directory isn't owned by me. - errno = EACCES; - return false; - } - - mode_t mask = umask(022); - umask(mask); - mode = (mode & ~mask); - if ((filestat.st_mode & 0777) != mode && chmod(path.c_str(), mode) == -1) { - // errno set by chmod. - return false; - } - } - return true; -} - -static bool MakeDirectories(const string& path, mode_t mode, bool childmost) { - if (path.empty() || path == "/") { - errno = EACCES; - return false; - } - - bool stat_succeeded = GetDirectoryStat(path, mode, childmost); - if (stat_succeeded) { - return true; - } - - if (errno == ENOENT) { - // Path does not exist, attempt to create its parents, then it. - string parent = blaze_util::Dirname(path); - if (!MakeDirectories(parent, mode, false)) { - // errno set by stat. - return false; - } - - if (mkdir(path.c_str(), mode) == -1) { - if (errno == EEXIST) { - if (childmost) { - // If there are multiple bazel calls at the same time then the - // directory could be created between the MakeDirectories and mkdir - // calls. This is okay, but we still have to check the permissions. - return GetDirectoryStat(path, mode, childmost); - } else { - // If this isn't the childmost directory, we don't care what the - // permissions were. If it's not even a directory then that error will - // get caught when we attempt to create the next directory down the - // chain. - return true; - } - } - // errno set by mkdir. - return false; - } - return true; - } - - return stat_succeeded; -} - -// mkdir -p path. Returns 0 if the path was created or already exists and could -// be chmod-ed to exactly the given permissions. If final part of the path is a -// symlink, this ensures that the destination of the symlink has the desired -// permissions. It also checks that the directory or symlink is owned by us. -// On failure, this returns -1 and sets errno. -bool MakeDirectories(const string& path, mode_t mode) { - return MakeDirectories(path, mode, true); -} -#endif // COMPILER_MSVC - string GetEnv(const string& name) { #ifdef COMPILER_MSVC // TODO(bazel-team): implement this. diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h index 17c7e2efb6..1db579a494 100644 --- a/src/main/cpp/util/file_platform.h +++ b/src/main/cpp/util/file_platform.h @@ -79,6 +79,11 @@ time_t GetMtimeMillisec(const std::string& path); // Returns true upon success. bool SetMtimeMillisec(const std::string& path, time_t mtime); +// mkdir -p path. All newly created directories use the given mode. +// `mode` should be an octal permission mask, e.g. 0755. +// Returns false on failure, sets errno. +bool MakeDirectories(const std::string &path, unsigned int mode); + // Returns the current working directory. std::string GetCwd(); diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index 803dec78a6..c4c6f4a290 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc @@ -34,6 +34,91 @@ namespace blaze_util { using std::pair; using std::string; +// Runs "stat" on `path`. Returns -1 and sets errno if stat fails or +// `path` isn't a directory. If check_perms is true, this will also +// make sure that `path` is owned by the current user and has `mode` +// permissions (observing the umask). It attempts to run chmod to +// correct the mode if necessary. If `path` is a symlink, this will +// check ownership of the link, not the underlying directory. +static bool GetDirectoryStat(const string &path, mode_t mode, + bool check_perms) { + struct stat filestat = {}; + if (stat(path.c_str(), &filestat) == -1) { + return false; + } + + if (!S_ISDIR(filestat.st_mode)) { + errno = ENOTDIR; + return false; + } + + if (check_perms) { + // If this is a symlink, run checks on the link. (If we did lstat above + // then it would return false for ISDIR). + struct stat linkstat = {}; + if (lstat(path.c_str(), &linkstat) != 0) { + return false; + } + if (linkstat.st_uid != geteuid()) { + // The directory isn't owned by me. + errno = EACCES; + return false; + } + + mode_t mask = umask(022); + umask(mask); + mode = (mode & ~mask); + if ((filestat.st_mode & 0777) != mode && chmod(path.c_str(), mode) == -1) { + // errno set by chmod. + return false; + } + } + return true; +} + +static bool MakeDirectories(const string &path, mode_t mode, bool childmost) { + if (path.empty() || path == "/") { + errno = EACCES; + return false; + } + + bool stat_succeeded = GetDirectoryStat(path, mode, childmost); + if (stat_succeeded) { + return true; + } + + if (errno == ENOENT) { + // Path does not exist, attempt to create its parents, then it. + string parent = Dirname(path); + if (!MakeDirectories(parent, mode, false)) { + // errno set by stat. + return false; + } + + if (mkdir(path.c_str(), mode) == -1) { + if (errno == EEXIST) { + if (childmost) { + // If there are multiple bazel calls at the same time then the + // directory could be created between the MakeDirectories and mkdir + // calls. This is okay, but we still have to check the permissions. + return GetDirectoryStat(path, mode, childmost); + } else { + // If this isn't the childmost directory, we don't care what the + // permissions were. If it's not even a directory then that error will + // get caught when we attempt to create the next directory down the + // chain. + return true; + } + } + // errno set by mkdir. + return false; + } + return true; + } + + return stat_succeeded; +} + class PosixPipe : public IPipe { public: PosixPipe(int recv_socket, int send_socket) @@ -200,6 +285,15 @@ bool SetMtimeMillisec(const string& path, time_t mtime) { return utime(path.c_str(), ×) == 0; } +// mkdir -p path. Returns 0 if the path was created or already exists and could +// be chmod-ed to exactly the given permissions. If final part of the path is a +// symlink, this ensures that the destination of the symlink has the desired +// permissions. It also checks that the directory or symlink is owned by us. +// On failure, this returns -1 and sets errno. +bool MakeDirectories(const string &path, unsigned int mode) { + return MakeDirectories(path, mode, true); +} + string GetCwd() { char cwdbuf[PATH_MAX]; if (getcwd(cwdbuf, sizeof cwdbuf) == NULL) { diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index cbf17d1c7f..214372abd6 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc @@ -106,6 +106,108 @@ bool SetMtimeMillisec(const string& path, time_t mtime) { return false; } +#ifdef COMPILER_MSVC +bool MakeDirectories(const string& path, unsigned int mode) { + // TODO(bazel-team): implement this. + pdie(255, "blaze::MakeDirectories is not implemented on Windows"); + return false; +} +#else // not COMPILER_MSVC +// Runs "stat" on `path`. Returns -1 and sets errno if stat fails or +// `path` isn't a directory. If check_perms is true, this will also +// make sure that `path` is owned by the current user and has `mode` +// permissions (observing the umask). It attempts to run chmod to +// correct the mode if necessary. If `path` is a symlink, this will +// check ownership of the link, not the underlying directory. +static bool GetDirectoryStat(const string& path, mode_t mode, + bool check_perms) { + struct stat filestat = {}; + if (stat(path.c_str(), &filestat) == -1) { + return false; + } + + if (!S_ISDIR(filestat.st_mode)) { + errno = ENOTDIR; + return false; + } + + if (check_perms) { + // If this is a symlink, run checks on the link. (If we did lstat above + // then it would return false for ISDIR). + struct stat linkstat = {}; + if (lstat(path.c_str(), &linkstat) != 0) { + return false; + } + if (linkstat.st_uid != geteuid()) { + // The directory isn't owned by me. + errno = EACCES; + return false; + } + + mode_t mask = umask(022); + umask(mask); + mode = (mode & ~mask); + if ((filestat.st_mode & 0777) != mode && chmod(path.c_str(), mode) == -1) { + // errno set by chmod. + return false; + } + } + return true; +} + +static bool MakeDirectories(const string& path, mode_t mode, bool childmost) { + if (path.empty() || path == "/") { + errno = EACCES; + return false; + } + + bool stat_succeeded = GetDirectoryStat(path, mode, childmost); + if (stat_succeeded) { + return true; + } + + if (errno == ENOENT) { + // Path does not exist, attempt to create its parents, then it. + string parent = Dirname(path); + if (!MakeDirectories(parent, mode, false)) { + // errno set by stat. + return false; + } + + if (mkdir(path.c_str(), mode) == -1) { + if (errno == EEXIST) { + if (childmost) { + // If there are multiple bazel calls at the same time then the + // directory could be created between the MakeDirectories and mkdir + // calls. This is okay, but we still have to check the permissions. + return GetDirectoryStat(path, mode, childmost); + } else { + // If this isn't the childmost directory, we don't care what the + // permissions were. If it's not even a directory then that error will + // get caught when we attempt to create the next directory down the + // chain. + return true; + } + } + // errno set by mkdir. + return false; + } + return true; + } + + return stat_succeeded; +} + +// mkdir -p path. Returns 0 if the path was created or already exists and could +// be chmod-ed to exactly the given permissions. If final part of the path is a +// symlink, this ensures that the destination of the symlink has the desired +// permissions. It also checks that the directory or symlink is owned by us. +// On failure, this returns -1 and sets errno. +bool MakeDirectories(const string& path, mode_t mode) { + return MakeDirectories(path, mode, true); +} +#endif // COMPILER_MSVC + string GetCwd() { // TODO(bazel-team): implement this. pdie(255, "blaze_util::GetCwd is not implemented on Windows"); |