1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/build/BinaryPath.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,156 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef mozilla_BinaryPath_h 1.9 +#define mozilla_BinaryPath_h 1.10 + 1.11 +#include "nsXPCOMPrivate.h" // for MAXPATHLEN 1.12 +#ifdef XP_WIN 1.13 +#include <windows.h> 1.14 +#elif defined(XP_MACOSX) 1.15 +#include <CoreFoundation/CoreFoundation.h> 1.16 +#elif defined(XP_UNIX) 1.17 +#include <sys/stat.h> 1.18 +#include <string.h> 1.19 +#endif 1.20 + 1.21 +namespace mozilla { 1.22 + 1.23 +class BinaryPath { 1.24 +public: 1.25 +#ifdef XP_WIN 1.26 + static nsresult Get(const char *argv0, char aResult[MAXPATHLEN]) 1.27 + { 1.28 + wchar_t wide_path[MAXPATHLEN]; 1.29 + nsresult rv = GetW(argv0, wide_path); 1.30 + if (NS_FAILED(rv)) 1.31 + return rv; 1.32 + WideCharToMultiByte(CP_UTF8, 0, wide_path, -1, 1.33 + aResult, MAXPATHLEN, nullptr, nullptr); 1.34 + return NS_OK; 1.35 + } 1.36 + 1.37 +private: 1.38 + static nsresult GetW(const char *argv0, wchar_t aResult[MAXPATHLEN]) 1.39 + { 1.40 + if (::GetModuleFileNameW(0, aResult, MAXPATHLEN)) 1.41 + return NS_OK; 1.42 + return NS_ERROR_FAILURE; 1.43 + } 1.44 + 1.45 +#elif defined(XP_MACOSX) 1.46 + static nsresult Get(const char *argv0, char aResult[MAXPATHLEN]) 1.47 + { 1.48 + // Works even if we're not bundled. 1.49 + CFBundleRef appBundle = CFBundleGetMainBundle(); 1.50 + if (!appBundle) 1.51 + return NS_ERROR_FAILURE; 1.52 + 1.53 + CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle); 1.54 + if (!executableURL) 1.55 + return NS_ERROR_FAILURE; 1.56 + 1.57 + nsresult rv; 1.58 + if (CFURLGetFileSystemRepresentation(executableURL, false, (UInt8 *)aResult, MAXPATHLEN)) 1.59 + rv = NS_OK; 1.60 + else 1.61 + rv = NS_ERROR_FAILURE; 1.62 + CFRelease(executableURL); 1.63 + return rv; 1.64 + } 1.65 + 1.66 +#elif defined(ANDROID) 1.67 + static nsresult Get(const char *argv0, char aResult[MAXPATHLEN]) 1.68 + { 1.69 + // On Android, we use the GRE_HOME variable that is set by the Java 1.70 + // bootstrap code. 1.71 + const char *greHome = getenv("GRE_HOME"); 1.72 +#if defined(MOZ_WIDGET_GONK) 1.73 + if (!greHome) 1.74 + greHome = "/system/b2g"; 1.75 +#endif 1.76 + 1.77 + if (!greHome) 1.78 + return NS_ERROR_FAILURE; 1.79 + 1.80 + snprintf(aResult, MAXPATHLEN, "%s/%s", greHome, "dummy"); 1.81 + aResult[MAXPATHLEN-1] = '\0'; 1.82 + return NS_OK; 1.83 + } 1.84 + 1.85 +#elif defined(XP_UNIX) 1.86 + static nsresult Get(const char *argv0, char aResult[MAXPATHLEN]) 1.87 + { 1.88 + struct stat fileStat; 1.89 + // on unix, there is no official way to get the path of the current binary. 1.90 + // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to 1.91 + // multiple applications, we will try a series of techniques: 1.92 + // 1.93 + // 1) use realpath() on argv[0], which works unless we're loaded from the 1.94 + // PATH. Only do so if argv[0] looks like a path (contains a /). 1.95 + // 2) manually walk through the PATH and look for ourself 1.96 + // 3) give up 1.97 + if (strchr(argv0, '/') && realpath(argv0, aResult) && 1.98 + stat(aResult, &fileStat) == 0) 1.99 + return NS_OK; 1.100 + 1.101 + const char *path = getenv("PATH"); 1.102 + if (!path) 1.103 + return NS_ERROR_FAILURE; 1.104 + 1.105 + char *pathdup = strdup(path); 1.106 + if (!pathdup) 1.107 + return NS_ERROR_OUT_OF_MEMORY; 1.108 + 1.109 + bool found = false; 1.110 + char *token = strtok(pathdup, ":"); 1.111 + while (token) { 1.112 + char tmpPath[MAXPATHLEN]; 1.113 + sprintf(tmpPath, "%s/%s", token, argv0); 1.114 + if (realpath(tmpPath, aResult) && stat(aResult, &fileStat) == 0) { 1.115 + found = true; 1.116 + break; 1.117 + } 1.118 + token = strtok(nullptr, ":"); 1.119 + } 1.120 + free(pathdup); 1.121 + if (found) 1.122 + return NS_OK; 1.123 + return NS_ERROR_FAILURE; 1.124 + } 1.125 + 1.126 +#else 1.127 +#error Oops, you need platform-specific code here 1.128 +#endif 1.129 + 1.130 +public: 1.131 + static nsresult GetFile(const char *argv0, nsIFile* *aResult) 1.132 + { 1.133 + nsCOMPtr<nsIFile> lf; 1.134 +#ifdef XP_WIN 1.135 + wchar_t exePath[MAXPATHLEN]; 1.136 + nsresult rv = GetW(argv0, exePath); 1.137 +#else 1.138 + char exePath[MAXPATHLEN]; 1.139 + nsresult rv = Get(argv0, exePath); 1.140 +#endif 1.141 + if (NS_FAILED(rv)) 1.142 + return rv; 1.143 +#ifdef XP_WIN 1.144 + rv = NS_NewLocalFile(nsDependentString(exePath), true, 1.145 + getter_AddRefs(lf)); 1.146 +#else 1.147 + rv = NS_NewNativeLocalFile(nsDependentCString(exePath), true, 1.148 + getter_AddRefs(lf)); 1.149 +#endif 1.150 + if (NS_FAILED(rv)) 1.151 + return rv; 1.152 + NS_ADDREF(*aResult = lf); 1.153 + return NS_OK; 1.154 + } 1.155 +}; 1.156 + 1.157 +} 1.158 + 1.159 +#endif /* mozilla_BinaryPath_h */