Add android::base::GetExecutablePath, switch adb and fastboot over.

We'd long had two copies of this stuff, so rather than rewrite both
Linux versions to use android::base::Readlink, let's kill the duplication
too...

Bug: http://b/30988271
Change-Id: I4de58a94a22a4b1faf969a6fc70ca1560a4d5121
diff --git a/base/file.cpp b/base/file.cpp
index 3963081..03ce4ea 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -30,6 +30,13 @@
 #include "android-base/utf8.h"
 #include "utils/Compat.h"
 
+#if defined(__APPLE__)
+#import <Carbon/Carbon.h>
+#endif
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
 namespace android {
 namespace base {
 
@@ -197,5 +204,32 @@
 }
 #endif
 
+std::string GetExecutablePath() {
+#if defined(__linux__)
+  std::string path;
+  android::base::Readlink("/proc/self/exe", &path);
+  return path;
+#elif defined(__APPLE__)
+  // TODO: use _NSGetExecutablePath instead (http://b/31240820)?
+  CFBundleRef mainBundle = CFBundleGetMainBundle();
+  CFURLRef executableURL = CFBundleCopyExecutableURL(mainBundle);
+  CFStringRef executablePathString = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
+  CFRelease(executableURL);
+
+  char path[PATH_MAX + 1];
+  CFStringGetFileSystemRepresentation(executablePathString, path, sizeof(PATH_MAX)-1);
+  CFRelease(executablePathString);
+  return path;
+#elif defined(_WIN32)
+  char path[PATH_MAX + 1];
+  DWORD result = GetModuleFileName(NULL, path, sizeof(path) - 1);
+  if (result == 0 || result == sizeof(path) - 1) return "";
+  path[PATH_MAX - 1] = 0;
+  return path;
+#else
+#error unknown OS
+#endif
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/base/file_test.cpp b/base/file_test.cpp
index ca01ee8..f5d6062 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -136,3 +136,7 @@
   ASSERT_EQ(max, result);
 #endif
 }
+
+TEST(file, GetExecutablePath) {
+  ASSERT_NE("", android::base::GetExecutablePath());
+}
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 2726a62..5b22a65 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -47,6 +47,8 @@
 bool Readlink(const std::string& path, std::string* result);
 #endif
 
+std::string GetExecutablePath();
+
 }  // namespace base
 }  // namespace android