aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp
diff options
context:
space:
mode:
authorGravatar Dave MacLachlan <dmaclach@google.com>2016-07-18 16:05:56 +0000
committerGravatar John Cater <jcater@google.com>2016-07-18 18:09:35 +0000
commit75f367c6b5f26244777e26134c61f0c26af2549c (patch)
tree2cec9a3d0adb610a99acb30c3cab764d0fb4680c /src/main/cpp
parentc760f133604877e7b6d8ac3f2bcb9b13b0983f4e (diff)
Add support for checking to see if we are on a network drive for darwin.
Fix for: https://github.com/bazelbuild/bazel/issues/1511 -- MOS_MIGRATED_REVID=127722500
Diffstat (limited to 'src/main/cpp')
-rw-r--r--src/main/cpp/BUILD2
-rw-r--r--src/main/cpp/blaze_util_darwin.cc76
2 files changed, 76 insertions, 2 deletions
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index 4604d1d683..963866f722 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -35,8 +35,10 @@ cc_library(
],
linkopts = select({
"//src:darwin": [
+ "-framework CoreFoundation",
],
"//src:darwin_x86_64": [
+ "-framework CoreFoundation",
],
"//src:freebsd": [
],
diff --git a/src/main/cpp/blaze_util_darwin.cc b/src/main/cpp/blaze_util_darwin.cc
index b1e1d692c9..d926cf2ea5 100644
--- a/src/main/cpp/blaze_util_darwin.cc
+++ b/src/main/cpp/blaze_util_darwin.cc
@@ -18,6 +18,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
+#include <CoreFoundation/CoreFoundation.h>
#include <cstdio>
#include "src/main/cpp/blaze_util.h"
@@ -32,14 +33,85 @@ namespace blaze {
using blaze_util::die;
using blaze_util::pdie;
using std::string;
+using std::vector;
+
+// A stack based class for RAII type handling of CF based types that need
+// CFRelease called on them. Checks for NULL before calling release.
+template <typename T> class CFScopedReleaser {
+ public:
+ explicit CFScopedReleaser(T value) : value_(value) { }
+ ~CFScopedReleaser() {
+ if (isValid()) {
+ CFRelease(value_);
+ }
+ }
+ T get() { return value_; }
+ operator T() { return value_; }
+ bool isValid() { return value_ != NULL; }
+
+ private:
+ T value_;
+
+ CFScopedReleaser() { }
+ CFScopedReleaser(const CFScopedReleaser&);
+ CFScopedReleaser& operator=(CFScopedReleaser&);
+};
+
+// Convert a CFStringRef to a UTF8 encoded c string
+static string UTF8StringFromCFStringRef(CFStringRef cf_string) {
+ std::string utf8_string;
+ if (cf_string) {
+ CFIndex length = CFStringGetLength(cf_string);
+ CFIndex max_size =
+ CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
+ vector<char> buffer(max_size);
+ if (CFStringGetCString(cf_string, &buffer[0], max_size,
+ kCFStringEncodingUTF8)) {
+ utf8_string = &buffer[0];
+ }
+ }
+ return utf8_string;
+}
+
+// Extract description from a CFError.
+static string DescriptionFromCFError(CFErrorRef cf_err) {
+ if (!cf_err) {
+ return "";
+ }
+ CFScopedReleaser<CFStringRef> cf_err_string(CFErrorCopyDescription(cf_err));
+ return UTF8StringFromCFStringRef(cf_err_string);
+}
string GetOutputRoot() {
return "/var/tmp";
}
void WarnFilesystemType(const string& output_base) {
- // TODO(bazel-team): Should check for NFS.
- // TODO(bazel-team): Should check for case insensitive file systems?
+ // Check to see if we are on a non-local drive.
+ CFScopedReleaser<CFURLRef> cf_url(CFURLCreateFromFileSystemRepresentation(
+ kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(output_base.c_str()),
+ output_base.length(), true));
+ CFBooleanRef cf_local = NULL;
+ CFErrorRef cf_error = NULL;
+ if (!cf_url.isValid() ||
+ !CFURLCopyResourcePropertyForKey(cf_url, kCFURLVolumeIsLocalKey,
+ &cf_local, &cf_error)) {
+ CFScopedReleaser<CFErrorRef> cf_error_releaser(cf_error);
+ string error_desc = DescriptionFromCFError(cf_error_releaser);
+ fprintf(stderr, "Warning: couldn't get file system type information for "
+ "'%s'", output_base.c_str());
+ if (error_desc.length() > 0) {
+ fprintf(stderr, " - '%s'", error_desc.c_str());
+ }
+ fprintf(stderr, "\n");
+ return;
+ }
+ CFScopedReleaser<CFBooleanRef> cf_local_releaser(cf_local);
+ if (!CFBooleanGetValue(cf_local_releaser)) {
+ fprintf(stderr, "Warning: Output base '%s' is on a non-local drive. This "
+ "may lead to surprising failures and undetermined behavior.\n",
+ output_base.c_str());
+ }
}
pid_t GetPeerProcessId(int socket) {