diff --git a/hphp/compiler/compiler.cpp b/hphp/compiler/compiler.cpp index e7ef500fa..1d1d5e8c0 100644 --- a/hphp/compiler/compiler.cpp +++ b/hphp/compiler/compiler.cpp @@ -34,6 +34,7 @@ #include "hphp/util/timer.h" #include "hphp/util/hdf.h" #include "hphp/util/async_func.h" +#include "hphp/util/current_executable.h" #include "hphp/runtime/base/program_functions.h" #include "hphp/runtime/base/smart_allocator.h" #include "hphp/runtime/base/externals.h" @@ -866,11 +867,11 @@ int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar, */ string exe = po.outputDir + '/' + po.program; string repo = "repo=" + exe + ".hhbc"; - char buf[PATH_MAX]; - if (!realpath("/proc/self/exe", buf)) return -1; + string buf = current_executable_path(); + if (buf.empty()) return -1; const char *argv[] = { "objcopy", "--add-section", repo.c_str(), - buf, exe.c_str(), 0 }; + buf.c_str(), exe.c_str(), 0 }; string out; ret = Process::Exec(argv[0], argv, nullptr, out, nullptr) ? 0 : 1; } @@ -909,8 +910,8 @@ int runTarget(const CompilerOptions &po) { // run the executable string cmd; if (po.format.find("exe") == string::npos) { - char buf[PATH_MAX]; - if (!realpath("/proc/self/exe", buf)) return -1; + string buf = current_executable_path(); + if (buf.empty()) return -1; cmd += buf; cmd += " -vRepo.Authoritative=true"; diff --git a/hphp/runtime/base/externals.h b/hphp/runtime/base/externals.h index bcb9af2a1..5411e49ad 100644 --- a/hphp/runtime/base/externals.h +++ b/hphp/runtime/base/externals.h @@ -72,9 +72,10 @@ struct EnvConstants { static void requestInit(EnvConstants* gt); static void requestExit(); Variant __lvalProxy; - Variant stgv_Variant[2]; + Variant stgv_Variant[3]; #define k_SID stgv_Variant[0] #define k_PHP_SAPI stgv_Variant[1] +#define k_PHP_BINARY stgv_Variant[2] }; extern EnvConstants* get_env_constants(); diff --git a/hphp/runtime/base/program_functions.cpp b/hphp/runtime/base/program_functions.cpp index 0d80b3b0e..68e6ca36c 100644 --- a/hphp/runtime/base/program_functions.cpp +++ b/hphp/runtime/base/program_functions.cpp @@ -40,6 +40,7 @@ #include "hphp/util/stack_trace.h" #include "hphp/util/light_process.h" #include "hphp/util/repo_schema.h" +#include "hphp/util/current_executable.h" #include "hphp/runtime/base/stat_cache.h" #include "hphp/runtime/ext/extension.h" #include "hphp/runtime/ext/ext_fb.h" @@ -1409,6 +1410,7 @@ void hphp_session_init() { EnvConstants *g = get_env_constants(); g->k_PHP_SAPI = StringData::GetStaticString(RuntimeOption::ExecutionMode); + g->k_PHP_BINARY = current_executable_path(); } bool hphp_is_warmup_enabled() { diff --git a/hphp/runtime/vm/jit/test/main.cpp b/hphp/runtime/vm/jit/test/main.cpp index fcbee1eff..1b7078f38 100644 --- a/hphp/runtime/vm/jit/test/main.cpp +++ b/hphp/runtime/vm/jit/test/main.cpp @@ -15,18 +15,19 @@ */ #include "gtest/gtest.h" #include "hphp/hhvm/process_init.h" +#include "hphp/util/current_executable.h" #include int main(int argc, char** argv) { - char buf[PATH_MAX]; - if (realpath("/proc/self/exe", buf)) { + std::string buf = HPHP::current_executable_path(); + if (!buf.empty()) { + size_t idx = buf.length(); for (int i = 0; i < 4; i++) { - char* p = strrchr(buf, '/'); - assert(p); - *p = 0; + idx = buf.find_last_of('/', idx - 1); + assert(idx != std::string::npos); } - std::string slib = buf; + std::string slib = buf.substr(0, idx); slib += "/ext_hhvm/systemlib.php"; setenv("HHVM_SYSTEMLIB", slib.c_str(), true); } diff --git a/hphp/system/idl/constants.idl.json b/hphp/system/idl/constants.idl.json index 9f6e66644..84726d83c 100644 --- a/hphp/system/idl/constants.idl.json +++ b/hphp/system/idl/constants.idl.json @@ -4765,7 +4765,7 @@ }, { "name": "OPENSSL_ALGO_RMD160", - "value": 10 + "value": 10 }, { "name": "OPENSSL_ALGO_SHA512", @@ -4773,11 +4773,11 @@ }, { "name": "OPENSSL_ALGO_SHA384", - "value": 8 + "value": 8 }, { "name": "OPENSSL_ALGO_SHA256", - "value": 7 + "value": 7 }, { "name": "OPENSSL_ALGO_SHA224", @@ -4931,6 +4931,10 @@ "name": "PEAR_INSTALL_DIR", "value": "" }, + { "name": "PHP_BINARY", + "type": "String", + "desc": "Dynamic constant - current_executable_path()" + }, { "name": "PHP_BINARY_READ", "value": 2 diff --git a/hphp/tools/bootstrap/gen-class-map.cpp b/hphp/tools/bootstrap/gen-class-map.cpp index 708760b85..5f1cb4e76 100644 --- a/hphp/tools/bootstrap/gen-class-map.cpp +++ b/hphp/tools/bootstrap/gen-class-map.cpp @@ -250,7 +250,7 @@ static void writeConstant(std::ostream& out, const PhpConst& cns) { if (cns.isSystem()) { // Special "magic" constants - if ((name == "SID") || (name == "PHP_SAPI")) { + if ((name == "SID") || (name == "PHP_SAPI") || (name == "PHP_BINARY")) { out << "(const char *)((offsetof(EnvConstants, k_" << name << ") - " << "offsetof(EnvConstants, stgv_Variant)) / sizeof(Variant)), " << castLong(1) << ",\n"; diff --git a/hphp/util/current_executable.cpp b/hphp/util/current_executable.cpp new file mode 100644 index 000000000..c13c0110a --- /dev/null +++ b/hphp/util/current_executable.cpp @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | HipHop for PHP | + +----------------------------------------------------------------------+ + | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "hphp/util/current_executable.h" +#include +#include + +namespace HPHP { + +std::string current_executable_path() { +#ifdef __linux__ + char result[PATH_MAX]; + ssize_t count = readlink("/proc/self/exe", result, PATH_MAX); + return std::string(result, (count > 0) ? count : 0); +#elif defined(__APPLE__) + char result[PATH_MAX]; + uint32_t size = sizeof(result); + uint32_t success = _NSGetExecutablePath(result, &size); + return std:string(result, (success == 0) ? size : 0); +#else + // Return empty string for all other platforms for now (e.g. FreeBSD) + return std::string(); +#endif +} + +} diff --git a/hphp/util/current_executable.h b/hphp/util/current_executable.h new file mode 100644 index 000000000..97626e1dd --- /dev/null +++ b/hphp/util/current_executable.h @@ -0,0 +1,28 @@ +/* + +----------------------------------------------------------------------+ + | HipHop for PHP | + +----------------------------------------------------------------------+ + | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef incl_HPHP_UTIL_CURRENT_EXECUTABLE_H_ +#define incl_HPHP_UTIL_CURRENT_EXECUTABLE_H_ + +#include + +namespace HPHP { + + std::string current_executable_path(); + +} + +#endif // incl_HPHP_UTIL_CURRENT_EXECUTABLE_H_ diff --git a/hphp/util/embedded_data.cpp b/hphp/util/embedded_data.cpp index 81787692b..6b16dc998 100644 --- a/hphp/util/embedded_data.cpp +++ b/hphp/util/embedded_data.cpp @@ -15,6 +15,7 @@ */ #include "hphp/util/embedded_data.h" +#include "hphp/util/current_executable.h" #include "folly/ScopeGuard.h" @@ -28,7 +29,6 @@ #include #ifdef __APPLE__ -#include #include #include #endif @@ -44,7 +44,7 @@ bool get_embedded_data(const char *section, embedded_data* desc) { if (elf_version(EV_CURRENT) == EV_NONE) return false; - int fd = open("/proc/self/exe", O_RDONLY, 0); + int fd = open(current_executable_path().c_str(), O_RDONLY, 0); if (fd < 0) return false; SCOPE_EXIT { close(fd); }; @@ -78,9 +78,8 @@ bool get_embedded_data(const char *section, embedded_data* desc) { #else // __APPLE__ const struct section_64 *sect = getsectbyname("__text", section); if (sect) { - char path[PATH_MAX]; - uint32_t size = sizeof(path); - if (_NSGetExecutablePath(path, &size) == 0) { + string path = current_executable(); + if (!path.empty()) { desc->m_filename = path; } else { return false;