Merge "Add android::base::GetExecutablePath, switch adb and fastboot over."
diff --git a/adb/Android.mk b/adb/Android.mk
index 0a9c454..b2a0dc4 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -81,12 +81,10 @@
     $(ADB_COMMON_windows_CFLAGS) \
 
 LIBADB_darwin_SRC_FILES := \
-    get_my_path_darwin.cpp \
     sysdeps_unix.cpp \
     usb_osx.cpp \
 
 LIBADB_linux_SRC_FILES := \
-    get_my_path_linux.cpp \
     sysdeps_unix.cpp \
     usb_linux.cpp \
 
diff --git a/adb/adb.cpp b/adb/adb.cpp
index be390d9..3308950 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -34,6 +34,7 @@
 #include <vector>
 
 #include <android-base/errors.h>
+#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/parsenetaddress.h>
@@ -843,18 +844,18 @@
         return -1;
     }
 #else /* !defined(_WIN32) */
-    char    path[PATH_MAX];
-    int     fd[2];
-
     // set up a pipe so the child can tell us when it is ready.
     // fd[0] will be parent's end, and the child will write on fd[1]
+    int fd[2];
     if (pipe(fd)) {
         fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
         return -1;
     }
-    get_my_path(path, PATH_MAX);
+
+    std::string path = android::base::GetExecutablePath();
+
     pid_t pid = fork();
-    if(pid < 0) return -1;
+    if (pid < 0) return -1;
 
     if (pid == 0) {
         // child side of the fork
@@ -866,7 +867,7 @@
         char reply_fd[30];
         snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
         // child process
-        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
+        int result = execl(path.c_str(), "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
         // this should not return
         fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
     } else  {
diff --git a/adb/adb.h b/adb/adb.h
index cd6b7bd..4a2da91 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -126,7 +126,6 @@
 
 void handle_packet(apacket *p, atransport *t);
 
-void get_my_path(char *s, size_t maxLen);
 int launch_server(int server_port);
 int adb_server_main(int is_daemon, int server_port, int ack_reply_fd);
 
diff --git a/adb/get_my_path_darwin.cpp b/adb/get_my_path_darwin.cpp
deleted file mode 100644
index b0c962e..0000000
--- a/adb/get_my_path_darwin.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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.
- */
-
-#import <Carbon/Carbon.h>
-#include <unistd.h>
-
-#include "adb.h"
-
-void get_my_path(char *s, size_t maxLen)
-{
-    CFBundleRef mainBundle = CFBundleGetMainBundle();
-    CFURLRef executableURL = CFBundleCopyExecutableURL(mainBundle);
-    CFStringRef executablePathString = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
-    CFRelease(executableURL);
-
-    CFStringGetFileSystemRepresentation(executablePathString, s, maxLen);
-    CFRelease(executablePathString);
-}
-
diff --git a/adb/get_my_path_linux.cpp b/adb/get_my_path_linux.cpp
deleted file mode 100644
index 11c0b21..0000000
--- a/adb/get_my_path_linux.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <limits.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "adb.h"
-
-void get_my_path(char *exe, size_t maxLen)
-{
-    char proc[64];
-    snprintf(proc, sizeof proc, "/proc/%d/exe", getpid());
-    int err = readlink(proc, exe, maxLen - 1);
-    if(err > 0) {
-        exe[err] = '\0';
-    } else {
-        exe[0] = '\0';
-    }
-}
-
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
 
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 28e3d4b..7112d1d 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -43,15 +43,15 @@
 
 LOCAL_CFLAGS += -DFASTBOOT_REVISION='"$(fastboot_version)"'
 
-LOCAL_SRC_FILES_linux := usb_linux.cpp util_linux.cpp
+LOCAL_SRC_FILES_linux := usb_linux.cpp
 LOCAL_STATIC_LIBRARIES_linux := libselinux
 
-LOCAL_SRC_FILES_darwin := usb_osx.cpp util_osx.cpp
+LOCAL_SRC_FILES_darwin := usb_osx.cpp
 LOCAL_STATIC_LIBRARIES_darwin := libselinux
 LOCAL_LDLIBS_darwin := -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
 LOCAL_CFLAGS_darwin := -Wno-unused-parameter
 
-LOCAL_SRC_FILES_windows := usb_windows.cpp util_windows.cpp
+LOCAL_SRC_FILES_windows := usb_windows.cpp
 LOCAL_STATIC_LIBRARIES_windows := AdbWinApi
 LOCAL_REQUIRED_MODULES_windows := AdbWinApi
 LOCAL_LDLIBS_windows := -lws2_32
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index df0f651..987ba83 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -47,6 +47,7 @@
 #include <utility>
 #include <vector>
 
+#include <android-base/file.h>
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
 #include <android-base/parsenetaddress.h>
@@ -116,7 +117,7 @@
 
 static std::string find_item_given_name(const char* img_name, const char* product) {
     if(product) {
-        std::string path = get_my_path();
+        std::string path = android::base::GetExecutablePath();
         path.erase(path.find_last_of('/'));
         return android::base::StringPrintf("%s/../../../target/product/%s/%s",
                                            path.c_str(), product, img_name);
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index c2ea551..6699b6a 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -72,8 +72,6 @@
 char *mkmsg(const char *fmt, ...);
 __attribute__((__noreturn__)) void die(const char *fmt, ...);
 
-std::string get_my_path();
-
 /* Current product */
 extern char cur_product[FB_RESPONSE_SZ + 1];
 
diff --git a/fastboot/util_linux.cpp b/fastboot/util_linux.cpp
deleted file mode 100644
index 2c6aedb..0000000
--- a/fastboot/util_linux.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "fastboot.h"
-
-#include <unistd.h>
-#include <limits.h>
-
-#include <android-base/stringprintf.h>
-
-std::string get_my_path() {
-    std::string proc = android::base::StringPrintf("/proc/%d/exe", getpid());
-    char path[PATH_MAX + 1];
-    int rc = readlink(proc.c_str(), path, sizeof(path) - 1);
-    if (rc == -1) return "";
-    path[rc] = '\0';
-    return path;
-}
diff --git a/fastboot/util_osx.cpp b/fastboot/util_osx.cpp
deleted file mode 100644
index 4bae7c4..0000000
--- a/fastboot/util_osx.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "fastboot.h"
-
-#import <Carbon/Carbon.h>
-#include <unistd.h>
-
-std::string get_my_path() {
-    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;
-}
diff --git a/fastboot/util_windows.cpp b/fastboot/util_windows.cpp
deleted file mode 100644
index 3b22c55..0000000
--- a/fastboot/util_windows.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "fastboot.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include <windows.h>
-
-std::string get_my_path() {
-    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;
-}