diff --git a/src/env-inl.h b/src/env-inl.h index 2239412ccac9cb..4451080940628a 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -635,6 +635,10 @@ inline const std::vector& Environment::exec_argv() { return exec_argv_; } +inline const std::string& Environment::exec_path() const { + return exec_path_; +} + #if HAVE_INSPECTOR inline void Environment::set_coverage_directory(const char* dir) { coverage_directory_ = std::string(dir); diff --git a/src/env.cc b/src/env.cc index f0f4fc30688aad..9a251a93069742 100644 --- a/src/env.cc +++ b/src/env.cc @@ -261,6 +261,32 @@ void Environment::CreateProperties() { set_process_object(process_object); } +std::string GetExecPath(const std::vector& argv) { + char exec_path_buf[2 * PATH_MAX]; + size_t exec_path_len = sizeof(exec_path_buf); + std::string exec_path; + if (uv_exepath(exec_path_buf, &exec_path_len) == 0) { + exec_path = std::string(exec_path_buf, exec_path_len); + } else { + exec_path = argv[0]; + } + + // On OpenBSD process.execPath will be relative unless we + // get the full path before process.execPath is used. +#if defined(__OpenBSD__) + uv_fs_t req; + req.ptr = nullptr; + if (0 == + uv_fs_realpath(env->event_loop(), &req, exec_path.c_str(), nullptr)) { + CHECK_NOT_NULL(req.ptr); + exec_path = std::string(static_cast(req.ptr)); + } + uv_fs_req_cleanup(&req); +#endif + + return exec_path; +} + Environment::Environment(IsolateData* isolate_data, Local context, const std::vector& args, @@ -274,6 +300,7 @@ Environment::Environment(IsolateData* isolate_data, timer_base_(uv_now(isolate_data->event_loop())), exec_argv_(exec_args), argv_(args), + exec_path_(GetExecPath(args)), should_abort_on_uncaught_toggle_(isolate_, 1), stream_base_state_(isolate_, StreamBase::kNumStreamBaseStateFields), flags_(flags), diff --git a/src/env.h b/src/env.h index fb54f5ee995b75..59ad030f30ff9b 100644 --- a/src/env.h +++ b/src/env.h @@ -850,6 +850,7 @@ class Environment : public MemoryRetainer { void InitializeLibuv(bool start_profiler_idle_notifier); inline const std::vector& exec_argv(); inline const std::vector& argv(); + const std::string& exec_path() const; typedef void (*HandleCleanupCb)(Environment* env, uv_handle_t* handle, @@ -1239,6 +1240,7 @@ class Environment : public MemoryRetainer { std::shared_ptr inspector_host_port_; std::vector exec_argv_; std::vector argv_; + std::string exec_path_; uint32_t module_id_counter_ = 0; uint32_t script_id_counter_ = 0; diff --git a/src/node_process_object.cc b/src/node_process_object.cc index 45470254063418..54ae8e6a218072 100644 --- a/src/node_process_object.cc +++ b/src/node_process_object.cc @@ -180,37 +180,15 @@ void PatchProcessObject(const FunctionCallbackInfo& args) { #undef V // process.execPath - { - char exec_path_buf[2 * PATH_MAX]; - size_t exec_path_len = sizeof(exec_path_buf); - std::string exec_path; - if (uv_exepath(exec_path_buf, &exec_path_len) == 0) { - exec_path = std::string(exec_path_buf, exec_path_len); - } else { - exec_path = env->argv()[0]; - } - // On OpenBSD process.execPath will be relative unless we - // get the full path before process.execPath is used. -#if defined(__OpenBSD__) - uv_fs_t req; - req.ptr = nullptr; - if (0 == - uv_fs_realpath(env->event_loop(), &req, exec_path.c_str(), nullptr)) { - CHECK_NOT_NULL(req.ptr); - exec_path = std::string(static_cast(req.ptr)); - } - uv_fs_req_cleanup(&req); -#endif - process - ->Set(context, - FIXED_ONE_BYTE_STRING(isolate, "execPath"), - String::NewFromUtf8(isolate, - exec_path.c_str(), - NewStringType::kInternalized, - exec_path.size()) - .ToLocalChecked()) - .Check(); - } + process + ->Set(context, + FIXED_ONE_BYTE_STRING(isolate, "execPath"), + String::NewFromUtf8(isolate, + env->exec_path().c_str(), + NewStringType::kInternalized, + env->exec_path().size()) + .ToLocalChecked()) + .Check(); // process.debugPort CHECK(process