diff options
author | Laszlo Csomor <laszlocsomor@google.com> | 2016-11-10 13:31:27 +0000 |
---|---|---|
committer | Klaus Aehlig <aehlig@google.com> | 2016-11-10 16:17:29 +0000 |
commit | 9c95196bf21e42bf46df9436a84d263c26e972d2 (patch) | |
tree | 5960e30273a63b95c5f16ca458d9b3511f3d7092 | |
parent | bff767a0e24be19c6535214abb69f3d5d1d24210 (diff) |
Bazel client: wrap some POSIX functions
This change:
- starts using blaze_util::CanAccess and
blaze_util::PathExists instead of access(2)
- implements and starts using blaze_util::GetCwd
instead of getcwd(2)
- implements and starts using
blaze_util::ChangeDirectory instead of chdir(2)
- adds tests for the new wrapper methods
--
MOS_MIGRATED_REVID=138750297
-rw-r--r-- | src/main/cpp/blaze.cc | 13 | ||||
-rw-r--r-- | src/main/cpp/blaze_util.cc | 11 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_posix.cc | 13 | ||||
-rw-r--r-- | src/main/cpp/option_processor.cc | 8 | ||||
-rw-r--r-- | src/main/cpp/startup_options.cc | 10 | ||||
-rw-r--r-- | src/main/cpp/util/BUILD | 10 | ||||
-rw-r--r-- | src/main/cpp/util/file_platform.h | 6 | ||||
-rw-r--r-- | src/main/cpp/util/file_posix.cc | 13 | ||||
-rw-r--r-- | src/main/cpp/util/file_windows.cc | 10 | ||||
-rw-r--r-- | src/main/cpp/workspace_layout.cc | 12 | ||||
-rw-r--r-- | src/test/cpp/util/BUILD | 12 | ||||
-rw-r--r-- | src/test/cpp/util/file_posix_test.cc | 122 |
12 files changed, 199 insertions, 41 deletions
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 39215a51be..b69586012a 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -75,6 +75,7 @@ #include "src/main/cpp/util/errors.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" #include "src/main/cpp/util/md5.h" #include "src/main/cpp/util/numbers.h" #include "src/main/cpp/util/port.h" @@ -614,9 +615,9 @@ static string GetArgumentString(const vector<string>& argument_array) { // Do a chdir into the workspace, and die if it fails. static void GoToWorkspace() { if (WorkspaceLayout::InWorkspace(globals->workspace) && - chdir(globals->workspace.c_str()) != 0) { + !blaze_util::ChangeDirectory(globals->workspace)) { pdie(blaze_exit_code::INTERNAL_ERROR, - "chdir() into %s failed", globals->workspace.c_str()); + "changing directory into %s failed", globals->workspace.c_str()); } } @@ -1334,11 +1335,7 @@ static string MakeCanonical(const char *path) { // Compute the globals globals->cwd and globals->workspace. static void ComputeWorkspace() { - char cwdbuf[PATH_MAX]; - if (getcwd(cwdbuf, sizeof cwdbuf) == NULL) { - pdie(blaze_exit_code::INTERNAL_ERROR, "getcwd() failed"); - } - globals->cwd = MakeCanonical(cwdbuf); + globals->cwd = MakeCanonical(blaze_util::GetCwd().c_str()); globals->workspace = WorkspaceLayout::GetWorkspace(globals->cwd); } @@ -1392,7 +1389,7 @@ static void ComputeBaseDirectories(const string &self_path) { output_base); } } - if (access(output_base, R_OK | W_OK | X_OK) != 0) { + if (!blaze_util::CanAccess(globals->options->output_base, true, true, true)) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Error: Output base directory '%s' must be readable and writable.", output_base); diff --git a/src/main/cpp/blaze_util.cc b/src/main/cpp/blaze_util.cc index b93c699b4d..fe2bb72931 100644 --- a/src/main/cpp/blaze_util.cc +++ b/src/main/cpp/blaze_util.cc @@ -16,7 +16,6 @@ #include <errno.h> #include <fcntl.h> -#include <limits.h> #include <pwd.h> #include <stdarg.h> #include <stdio.h> @@ -35,6 +34,7 @@ #include "src/main/cpp/util/errors.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" #include "src/main/cpp/util/numbers.h" #include "src/main/cpp/util/strings.h" #include "src/main/cpp/util/port.h" @@ -68,14 +68,11 @@ string MakeAbsolute(const string &path) { return path; } - char cwdbuf[PATH_MAX]; - if (getcwd(cwdbuf, sizeof cwdbuf) == NULL) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "getcwd() failed"); - } + string cwd = blaze_util::GetCwd(); // Determine whether the cwd ends with "/" or not. - string separator = (cwdbuf[strlen(cwdbuf) - 1] == '/') ? "" : "/"; - return cwdbuf + separator + path; + string separator = cwd.back() == '/' ? "" : "/"; + return cwd + separator + path; } // Runs "stat" on `path`. Returns -1 and sets errno if stat fails or diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc index 7b4718ad90..e67876144a 100644 --- a/src/main/cpp/blaze_util_posix.cc +++ b/src/main/cpp/blaze_util_posix.cc @@ -14,7 +14,7 @@ #include <errno.h> #include <fcntl.h> -#include <limits.h> +#include <limits.h> // PATH_MAX #include <signal.h> #include <stdio.h> #include <sys/types.h> @@ -26,6 +26,7 @@ #include "src/main/cpp/util/errors.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" namespace blaze { @@ -43,13 +44,9 @@ void ExecuteProgram(const string &exe, const vector<string> &args_vector) { dbg.append(" "); } - char cwd[PATH_MAX] = {}; - if (getcwd(cwd, sizeof(cwd)) == NULL) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "getcwd() failed"); - } - - fprintf(stderr, "Invoking binary %s in %s:\n %s\n", exe.c_str(), cwd, - dbg.c_str()); + string cwd = blaze_util::GetCwd(); + fprintf(stderr, "Invoking binary %s in %s:\n %s\n", exe.c_str(), + cwd.c_str(), dbg.c_str()); } // Copy to a char* array for execv: diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc index 1cd1d81f5b..29f59cf8fe 100644 --- a/src/main/cpp/option_processor.cc +++ b/src/main/cpp/option_processor.cc @@ -17,7 +17,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include <algorithm> #include <cassert> #include <set> @@ -26,6 +25,7 @@ #include "src/main/cpp/blaze_util.h" #include "src/main/cpp/blaze_util_platform.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" #include "src/main/cpp/util/strings.h" #include "src/main/cpp/workspace_layout.h" @@ -180,7 +180,7 @@ blaze_exit_code::ExitCode OptionProcessor::FindUserBlazerc( string* error) { if (cmdLineRcFile != NULL) { string rcFile = MakeAbsolute(cmdLineRcFile); - if (access(rcFile.c_str(), R_OK)) { + if (!blaze_util::CanAccess(rcFile, true, false, false)) { blaze_util::StringPrintf(error, "Error: Unable to read .blazerc file '%s'.", rcFile.c_str()); return blaze_exit_code::BAD_ARGV; @@ -190,7 +190,7 @@ blaze_exit_code::ExitCode OptionProcessor::FindUserBlazerc( } string workspaceRcFile = blaze_util::JoinPath(workspace, rc_basename); - if (!access(workspaceRcFile.c_str(), R_OK)) { + if (blaze_util::CanAccess(workspaceRcFile, true, false, false)) { *blaze_rc_file = workspaceRcFile; return blaze_exit_code::SUCCESS; } @@ -202,7 +202,7 @@ blaze_exit_code::ExitCode OptionProcessor::FindUserBlazerc( } string userRcFile = blaze_util::JoinPath(home, rc_basename); - if (!access(userRcFile.c_str(), R_OK)) { + if (blaze_util::CanAccess(userRcFile, true, false, false)) { *blaze_rc_file = userRcFile; return blaze_exit_code::SUCCESS; } diff --git a/src/main/cpp/startup_options.cc b/src/main/cpp/startup_options.cc index 9b048d9014..c4590b9336 100644 --- a/src/main/cpp/startup_options.cc +++ b/src/main/cpp/startup_options.cc @@ -16,7 +16,6 @@ #include <assert.h> #include <errno.h> // errno, ENOENT #include <string.h> // strerror -#include <unistd.h> // access #include <cstdio> #include <cstdlib> @@ -25,6 +24,7 @@ #include "src/main/cpp/blaze_util.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" #include "src/main/cpp/util/numbers.h" #include "src/main/cpp/util/strings.h" #include "src/main/cpp/workspace_layout.h" @@ -331,8 +331,8 @@ string StartupOptions::GetHostJavabase() { string StartupOptions::GetJvm() { string java_program = GetHostJavabase() + "/bin/java"; - if (access(java_program.c_str(), X_OK) == -1) { - if (errno == ENOENT) { + if (!blaze_util::CanAccess(java_program, false, false, true)) { + if (!blaze_util::PathExists(java_program)) { fprintf(stderr, "Couldn't find java at '%s'.\n", java_program.c_str()); } else { fprintf(stderr, "Couldn't access %s: %s\n", java_program.c_str(), @@ -344,8 +344,8 @@ string StartupOptions::GetJvm() { string jdk_rt_jar = GetHostJavabase() + "/jre/lib/rt.jar"; // If just the JRE is installed string jre_rt_jar = GetHostJavabase() + "/lib/rt.jar"; - if ((access(jdk_rt_jar.c_str(), R_OK) == 0) - || (access(jre_rt_jar.c_str(), R_OK) == 0)) { + if (blaze_util::CanAccess(jdk_rt_jar, true, false, false) + || blaze_util::CanAccess(jre_rt_jar, true, false, false)) { return java_program; } fprintf(stderr, "Problem with java installation: " diff --git a/src/main/cpp/util/BUILD b/src/main/cpp/util/BUILD index 7537ac594d..600725f1c3 100644 --- a/src/main/cpp/util/BUILD +++ b/src/main/cpp/util/BUILD @@ -33,7 +33,10 @@ cc_library( ], }), hdrs = ["file_platform.h"], - visibility = ["//src/main/cpp:__pkg__"], + visibility = [ + "//src/main/cpp:__pkg__", + "//src/test/cpp:__pkg__", + ], deps = [ ":blaze_exit_code", ":errors", @@ -46,7 +49,10 @@ cc_library( name = "file", srcs = ["file.cc"], hdrs = ["file.h"], - visibility = ["//src/tools/singlejar:__pkg__"], + visibility = [ + "//src/test/cpp:__pkg__", + "//src/tools/singlejar:__pkg__", + ], deps = [ ":blaze_exit_code", ":errors", diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h index 6d00daffff..b0df5ea18d 100644 --- a/src/main/cpp/util/file_platform.h +++ b/src/main/cpp/util/file_platform.h @@ -34,6 +34,12 @@ bool PathExists(const std::string& path); // openable. bool CanAccess(const std::string& path, bool read, bool write, bool exec); +// Returns the current working directory. +std::string GetCwd(); + +// Changes the current working directory to `path`, returns true upon success. +bool ChangeDirectory(const std::string& path); + } // namespace blaze_util #endif // BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_ diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index 11f5d1058b..90355b92ee 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc @@ -14,6 +14,7 @@ #include "src/main/cpp/util/file_platform.h" #include <sys/stat.h> +#include <limits.h> // PATH_MAX #include <stdlib.h> // getenv #include <unistd.h> // access #include <vector> @@ -71,4 +72,16 @@ bool CanAccess(const string& path, bool read, bool write, bool exec) { return access(path.c_str(), mode) == 0; } +string GetCwd() { + char cwdbuf[PATH_MAX]; + if (getcwd(cwdbuf, sizeof cwdbuf) == NULL) { + pdie(blaze_exit_code::INTERNAL_ERROR, "getcwd() failed"); + } + return string(cwdbuf); +} + +bool ChangeDirectory(const string& path) { + return chdir(path.c_str()) == 0; +} + } // namespace blaze_util diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index 34f8bcf7a2..5cf9987486 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc @@ -33,4 +33,14 @@ bool CanAccess(const string& path, bool read, bool write, bool exec) { pdie(255, "blaze_util::CanAccess is not implemented on Windows"); } +string GetCwd() { + // TODO(bazel-team): implement this. + pdie(255, "blaze_util::GetCwd is not implemented on Windows"); +} + +bool ChangeDirectory(const string& path) { + // TODO(bazel-team): implement this. + pdie(255, "blaze_util::ChangeDirectory is not implemented on Windows"); +} + } // namespace blaze_util diff --git a/src/main/cpp/workspace_layout.cc b/src/main/cpp/workspace_layout.cc index d4836b5415..aa8bb09f2a 100644 --- a/src/main/cpp/workspace_layout.cc +++ b/src/main/cpp/workspace_layout.cc @@ -14,10 +14,10 @@ #include "src/main/cpp/workspace_layout.h" #include <assert.h> -#include <unistd.h> // access #include "src/main/cpp/blaze_util_platform.h" #include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/file_platform.h" namespace blaze { @@ -31,8 +31,8 @@ string WorkspaceLayout::GetOutputRoot() { } bool WorkspaceLayout::InWorkspace(const string &workspace) { - return access( - blaze_util::JoinPath(workspace, kWorkspaceMarker).c_str(), F_OK) == 0; + return blaze_util::PathExists( + blaze_util::JoinPath(workspace, kWorkspaceMarker)); } string WorkspaceLayout::GetWorkspace(const string &cwd) { @@ -59,7 +59,7 @@ static string FindDepotBlazerc(const string& workspace) { WorkspaceLayout::WorkspaceRcFileSearchPath(&candidates); for (const auto& candidate : candidates) { string blazerc = blaze_util::JoinPath(workspace, candidate); - if (!access(blazerc.c_str(), R_OK)) { + if (blaze_util::CanAccess(blazerc, true, false, false)) { return blazerc; } } @@ -71,7 +71,7 @@ static string FindAlongsideBinaryBlazerc(const string& cwd, string path = arg0[0] == '/' ? arg0 : blaze_util::JoinPath(cwd, arg0); string base = blaze_util::Basename(arg0); string binary_blazerc_path = path + "." + base + "rc"; - if (!access(binary_blazerc_path.c_str(), R_OK)) { + if (blaze_util::CanAccess(binary_blazerc_path, true, false, false)) { return binary_blazerc_path; } return ""; @@ -79,7 +79,7 @@ static string FindAlongsideBinaryBlazerc(const string& cwd, static string FindSystemWideBlazerc() { string path = "/etc/bazel.bazelrc"; - if (!access(path.c_str(), R_OK)) { + if (blaze_util::CanAccess(path, true, false, false)) { return path; } return ""; diff --git a/src/test/cpp/util/BUILD b/src/test/cpp/util/BUILD index 0ec570063e..01c2b7c04d 100644 --- a/src/test/cpp/util/BUILD +++ b/src/test/cpp/util/BUILD @@ -22,7 +22,17 @@ cc_test( name = "file_test", srcs = ["file_test.cc"], deps = [ - "//src/main/cpp/util", + "//src/main/cpp/util:file", + "//third_party:gtest", + ], +) + +cc_test( + name = "file_platform_test", + srcs = ["file_posix_test.cc"], + deps = [ + "//src/main/cpp/util:file", + "//src/main/cpp/util:file_platform", "//third_party:gtest", ], ) diff --git a/src/test/cpp/util/file_posix_test.cc b/src/test/cpp/util/file_posix_test.cc new file mode 100644 index 0000000000..52ddbd6da2 --- /dev/null +++ b/src/test/cpp/util/file_posix_test.cc @@ -0,0 +1,122 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include <fcntl.h> +#include <unistd.h> + +#include "src/main/cpp/util/file_platform.h" +#include "gtest/gtest.h" + +namespace blaze_util { + +TEST(FilePosixTest, Which) { + ASSERT_EQ("", Which("")); + ASSERT_EQ("", Which("foo")); + ASSERT_EQ("", Which("/")); + + // /usr/bin/yes exists on Linux, Darwin, and MSYS, but "which yes" does not + // always return that (if $PATH is different). + string actual = Which("yes"); + // Assert that it's an absolute path + ASSERT_EQ(0, actual.find("/")); + // Assert that it ends with /yes, we cannot assume more than that. + ASSERT_EQ(actual.size() - string("/yes").size(), actual.rfind("/yes")); +} + +TEST(FilePosixTest, PathExists) { + ASSERT_FALSE(PathExists("/this/should/not/exist/mkay")); + ASSERT_FALSE(PathExists("non.existent")); + ASSERT_FALSE(PathExists("")); + + // /usr/bin/yes exists on Linux, Darwin, and MSYS + ASSERT_TRUE(PathExists("/")); + ASSERT_TRUE(PathExists("/usr")); + ASSERT_TRUE(PathExists("/usr/")); + ASSERT_TRUE(PathExists("/usr/bin/yes")); +} + +TEST(FilePosixTest, CanAccess) { + for (int i = 0; i < 8; ++i) { + ASSERT_FALSE(CanAccess("/this/should/not/exist/mkay", i & 1, i & 2, i & 4)); + ASSERT_FALSE(CanAccess("non.existent", i & 1, i & 2, i & 4)); + } + + for (int i = 0; i < 4; ++i) { + // /usr/bin/yes exists on Linux, Darwin, and MSYS + ASSERT_TRUE(CanAccess("/", i & 1, false, i & 2)); + ASSERT_TRUE(CanAccess("/usr", i & 1, false, i & 2)); + ASSERT_TRUE(CanAccess("/usr/", i & 1, false, i & 2)); + ASSERT_TRUE(CanAccess("/usr/bin/yes", i & 1, false, i & 2)); + } + + char* tmpdir_cstr = getenv("TEST_TMPDIR"); + ASSERT_FALSE(tmpdir_cstr == NULL); + + string tmpdir(tmpdir_cstr); + ASSERT_NE("", tmpdir); + + string mock_file = tmpdir + (tmpdir.back() == '/' ? "" : "/") + + "FilePosixTest.CanAccess.mock_file"; + int fd = open(mock_file.c_str(), O_CREAT, 0500); + ASSERT_GT(fd, 0); + close(fd); + + // Sanity check: assert that we successfully created the file with the given + // permissions. + ASSERT_EQ(0, access(mock_file.c_str(), R_OK | X_OK)); + ASSERT_NE(0, access(mock_file.c_str(), R_OK | W_OK | X_OK)); + + // Actual assertion + for (int i = 0; i < 4; ++i) { + ASSERT_TRUE(CanAccess(mock_file, i & 1, false, i & 2)); + ASSERT_FALSE(CanAccess(mock_file, i & 1, true, i & 2)); + } +} + +TEST(FilePosixTest, GetCwd) { + char cwdbuf[PATH_MAX]; + ASSERT_EQ(cwdbuf, getcwd(cwdbuf, PATH_MAX)); + + // Assert that GetCwd() and getcwd() return the same value. + string cwd(cwdbuf); + ASSERT_EQ(cwd, blaze_util::GetCwd()); + + // Change to a different directory. + ASSERT_EQ(0, chdir("/usr")); + + // Assert that GetCwd() returns the new CWD. + ASSERT_EQ(string("/usr"), blaze_util::GetCwd()); + + ASSERT_EQ(0, chdir(cwd.c_str())); + ASSERT_EQ(cwd, blaze_util::GetCwd()); +} + +TEST(FilePosixTest, ChangeDirectory) { + // Retrieve the current working directory. + char old_wd[PATH_MAX]; + ASSERT_EQ(old_wd, getcwd(old_wd, PATH_MAX)); + + // Change to a different directory and assert it was successful. + ASSERT_FALSE(blaze_util::ChangeDirectory("/non/existent/path")); + ASSERT_TRUE(blaze_util::ChangeDirectory("/usr")); + char new_wd[PATH_MAX]; + ASSERT_EQ(new_wd, getcwd(new_wd, PATH_MAX)); + ASSERT_EQ(string("/usr"), string(new_wd)); + + // Change back to the original CWD. + ASSERT_TRUE(blaze_util::ChangeDirectory(old_wd)); + ASSERT_EQ(new_wd, getcwd(new_wd, PATH_MAX)); + ASSERT_EQ(string(old_wd), string(new_wd)); +} + +} // namespace blaze_util |