blob: 7cc9131f98933983beb612309059ab5baddff805 [file] [log] [blame]
James M Snell98e54b02017-01-03 21:16:481// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
Ben Noordhuis02cab972013-07-31 21:16:0822#include "node_buffer.h"
23#include "node_constants.h"
Ben Noordhuis02cab972013-07-31 21:16:0824#include "node_javascript.h"
Matt Loring9e086952017-03-13 22:17:5725#include "node_platform.h"
Ben Noordhuis02cab972013-07-31 21:16:0826#include "node_version.h"
Trevor Norris63da0df2015-05-26 18:42:1427#include "node_internals.h"
James M Snelld3875912016-02-04 01:16:1028#include "node_revert.h"
Eugene Ostroukhovf9aadfb2016-11-18 21:52:2229#include "node_debug_options.h"
James M Snell67269fd2017-08-07 22:53:2430#include "node_perf.h"
Gus Caplancb5f3582018-02-26 20:29:4131#include "node_context_data.h"
Ben Noordhuis02cab972013-07-31 21:16:0832
33#if defined HAVE_PERFCTR
34#include "node_counters.h"
35#endif
36
37#if HAVE_OPENSSL
38#include "node_crypto.h"
39#endif
40
Steven R. Loomisac2857b2014-09-05 05:03:2441#if defined(NODE_HAVE_I18N_SUPPORT)
42#include "node_i18n.h"
43#endif
44
Ben Noordhuis399cb252017-05-27 11:31:0045#if HAVE_INSPECTOR
46#include "inspector_io.h"
47#endif
48
Ben Noordhuisc4def502013-10-28 19:18:5949#if defined HAVE_DTRACE || defined HAVE_ETW
Ben Noordhuis02cab972013-07-31 21:16:0850#include "node_dtrace.h"
51#endif
52
Bert Belder22d03c92012-08-06 23:48:1553#include "ares.h"
Daniel Bevenius78447662017-11-14 12:34:5254#include "async_wrap-inl.h"
Ben Noordhuis756b6222013-08-10 22:26:1155#include "env-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0856#include "handle_wrap.h"
Anna Henningsen6a1275d2017-04-17 12:49:3157#include "http_parser.h"
James M Snelle71e71b2017-07-17 17:17:1658#include "nghttp2/nghttp2ver.h"
Daniel Beveniusb58a1cd2017-11-14 12:34:5259#include "req_wrap-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0860#include "string_bytes.h"
misterpoeba4847e2016-08-05 21:04:2561#include "tracing/agent.h"
Timothy J Fontaine1a09da62014-06-10 23:36:0462#include "util.h"
Ben Noordhuisff4a9d32012-03-09 23:11:1163#include "uv.h"
Stefan Budeanu410296c2016-03-27 00:17:5564#if NODE_USE_V8_PLATFORM
Ben Noordhuis4a801c22015-04-02 21:51:0165#include "libplatform/libplatform.h"
Stefan Budeanu410296c2016-03-27 00:17:5566#endif // NODE_USE_V8_PLATFORM
Ben Noordhuis57231d52013-10-02 04:37:4467#include "v8-profiler.h"
Ben Noordhuis02cab972013-07-31 21:16:0868#include "zlib.h"
Ryan Dahl4635ed72010-03-11 20:40:1969
Chunyang Daia881b532015-10-21 16:24:1270#ifdef NODE_ENABLE_VTUNE_PROFILING
71#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
72#endif
73
Ben Noordhuis02cab972013-07-31 21:16:0874#include <errno.h>
Myles Borins9cc39ff2017-04-24 16:47:2675#include <fcntl.h> // _O_RDWR
Ben Noordhuis02cab972013-07-31 21:16:0876#include <limits.h> // PATH_MAX
Bert Beldere0f47be2011-01-17 23:22:3677#include <locale.h>
Bert Belder9cec08e2011-05-23 23:42:2278#include <signal.h>
Ryan19478ed2009-03-03 00:56:1579#include <stdio.h>
Ryan34a6f102009-05-28 12:47:1680#include <stdlib.h>
Ryan Dahlc90e44e2010-05-10 23:38:4781#include <string.h>
Ben Noordhuis02cab972013-07-31 21:16:0882#include <sys/types.h>
Ben Noordhuisc5c28c32015-10-10 13:01:4983
84#include <string>
Brian White2d356072015-10-13 21:18:1585#include <vector>
Ben Noordhuis02cab972013-07-31 21:16:0886
Evan Lucas30b8bb02015-09-27 15:59:0287#if defined(NODE_HAVE_I18N_SUPPORT)
88#include <unicode/uvernum.h>
89#endif
90
Karl Skomski6ed06032015-08-14 08:07:1891#if defined(LEAK_SANITIZER)
92#include <sanitizer/lsan_interface.h>
93#endif
94
Ben Noordhuis02cab972013-07-31 21:16:0895#if defined(_MSC_VER)
Peter Bright13d6a1f2011-08-06 04:23:2596#include <direct.h>
Peter Brightb9d77772011-08-11 01:45:5697#include <io.h>
98#define umask _umask
99typedef int mode_t;
Ben Noordhuis02cab972013-07-31 21:16:08100#else
Ben Noordhuis844f0a92016-03-25 16:59:07101#include <pthread.h>
Ben Noordhuis68200542013-10-02 10:17:57102#include <sys/resource.h> // getrlimit, setrlimit
Ben Noordhuis02cab972013-07-31 21:16:08103#include <unistd.h> // setuid, getuid
Peter Bright13d6a1f2011-08-06 04:23:25104#endif
Ryane02b71e2009-03-03 23:31:37105
Ed Schouten78dbcbe2017-10-30 10:58:13106#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ben Noordhuis02cab972013-07-31 21:16:08107#include <pwd.h> // getpwnam()
108#include <grp.h> // getgrnam()
Bert Beldera177d602010-11-25 00:02:55109#endif
110
Ezequiel Garcia5f223752017-04-29 20:06:22111#if defined(__POSIX__)
112#include <dlfcn.h>
113#endif
114
Fedor Indutny8e29ce92013-07-31 18:07:29115#ifdef __APPLE__
Ben Noordhuis02cab972013-07-31 21:16:08116#include <crt_externs.h>
117#define environ (*_NSGetEnviron())
Fedor Indutny8e29ce92013-07-31 18:07:29118#elif !defined(_MSC_VER)
Ryan3e4fc9f2009-09-10 14:48:38119extern char **environ;
Fedor Indutny8e29ce92013-07-31 18:07:29120#endif
Ryan3e4fc9f2009-09-10 14:48:38121
Yihong Wang8680bb92017-10-22 06:16:50122// This is used to load built-in modules. Instead of using
123// __attribute__((constructor)), we call the _register_<modname>
124// function for each built-in modules explicitly in
125// node::RegisterBuiltinModules(). This is only forward declaration.
126// The definitions are in each module's implementation when calling
127// the NODE_BUILTIN_MODULE_CONTEXT_AWARE.
128#define V(modname) void _register_##modname();
129 NODE_BUILTIN_MODULES(V)
130#undef V
131
Ryand6c9d312009-09-11 14:02:29132namespace node {
133
Ben Noordhuis110a9cd2013-07-03 02:23:44134using v8::Array;
Ben Noordhuis0693d222013-06-29 06:16:25135using v8::ArrayBuffer;
Ben Noordhuis110a9cd2013-07-03 02:23:44136using v8::Boolean;
137using v8::Context;
Fedor Indutnyce04c722014-03-13 16:38:14138using v8::EscapableHandleScope;
Ben Noordhuis110a9cd2013-07-03 02:23:44139using v8::Exception;
Patrick Mueller52cb4102016-04-05 13:17:48140using v8::Float64Array;
Ben Noordhuis110a9cd2013-07-03 02:23:44141using v8::Function;
142using v8::FunctionCallbackInfo;
Ben Noordhuis110a9cd2013-07-03 02:23:44143using v8::HandleScope;
144using v8::HeapStatistics;
145using v8::Integer;
146using v8::Isolate;
Anna Henningsenf3cd5372017-12-01 23:04:56147using v8::Just;
Ben Noordhuis511af4d2013-07-30 19:28:43148using v8::Local;
Ben Noordhuis110a9cd2013-07-03 02:23:44149using v8::Locker;
Anna Henningsenf3cd5372017-12-01 23:04:56150using v8::Maybe;
Michaël Zasso023c3172016-02-08 21:34:05151using v8::MaybeLocal;
Ben Noordhuis110a9cd2013-07-03 02:23:44152using v8::Message;
Ali Ijaz Sheikhc1649a72016-02-12 08:58:26153using v8::Name;
AnnaMagab194122016-10-06 20:50:41154using v8::NamedPropertyHandlerConfiguration;
Anna Henningsenf3cd5372017-12-01 23:04:56155using v8::Nothing;
Jeremiah Senkpiel21d66d62016-03-23 22:09:10156using v8::Null;
Ben Noordhuis110a9cd2013-07-03 02:23:44157using v8::Number;
158using v8::Object;
159using v8::ObjectTemplate;
Petka Antonov872702d2015-02-22 12:44:12160using v8::Promise;
Ben Noordhuis110a9cd2013-07-03 02:23:44161using v8::PropertyCallbackInfo;
Michaël Zasso023c3172016-02-08 21:34:05162using v8::ScriptOrigin;
Fedor Indutnya07c6912015-04-11 14:02:33163using v8::SealHandleScope;
Ben Noordhuis511af4d2013-07-30 19:28:43164using v8::String;
Ben Noordhuis110a9cd2013-07-03 02:23:44165using v8::TryCatch;
Michaël Zasso2fd248f2018-04-12 09:54:19166using v8::Uint32;
Ben Noordhuis70d1f322015-06-19 11:23:56167using v8::Uint32Array;
Anna Henningsen64616bb2017-08-08 18:02:55168using v8::Undefined;
Ben Noordhuis110a9cd2013-07-03 02:23:44169using v8::V8;
170using v8::Value;
Ben Noordhuis110a9cd2013-07-03 02:23:44171
Anna Henningsen2c52f652018-05-05 15:47:02172static Mutex process_mutex;
173static Mutex environ_mutex;
174
Evan Lucas5b6f5752015-06-01 14:15:10175static bool print_eval = false;
176static bool force_repl = false;
Dave Eddy2e6ece42015-08-17 21:33:13177static bool syntax_check_only = false;
Evan Lucas5b6f5752015-06-01 14:15:10178static bool trace_deprecation = false;
179static bool throw_deprecation = false;
Evan Lucas5b6f5752015-06-01 14:15:10180static bool trace_sync_io = false;
Andreas Madsen23a39112017-10-19 12:15:08181static bool no_force_async_hooks_checks = false;
Bradley Meckcf14a242015-07-09 16:15:26182static bool track_heap_objects = false;
Evan Lucas5b6f5752015-06-01 14:15:10183static const char* eval_string = nullptr;
Sam Robertscecdf7c2017-04-05 18:45:52184static std::vector<std::string> preload_modules;
Tom Gallacher03e07d32015-12-18 12:24:56185static const int v8_default_thread_pool_size = 4;
186static int v8_thread_pool_size = v8_default_thread_pool_size;
Matt Loring49440b72015-11-25 14:08:58187static bool prof_process = false;
Ben Noordhuis9566fe82013-10-03 08:45:32188static bool v8_is_profiling = false;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22189static bool node_is_initialized = false;
Keith M Wesolowski76b98462013-12-17 00:00:44190static node_module* modpending;
191static node_module* modlist_builtin;
Bradley Fariasa36aa042017-10-03 15:07:48192static node_module* modlist_internal;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22193static node_module* modlist_linked;
Keith M Wesolowski76b98462013-12-17 00:00:44194static node_module* modlist_addon;
Sam Roberts809ca2f2017-04-05 19:09:32195static std::string trace_enabled_categories; // NOLINT(runtime/string)
Andreas Madsen85212bb2018-01-31 16:12:09196static std::string trace_file_pattern = // NOLINT(runtime/string)
197 "node_trace.${rotation}.log";
Trevor Norrisc0bde732017-03-07 19:40:18198static bool abort_on_uncaught_exception = false;
Ben Noordhuis74a82152012-02-03 15:32:00199
James M Snell35f6e592017-08-16 16:34:37200// Bit flag used to track security reverts (see node_revert.h)
201unsigned int reverted = 0;
202
Evan Lucas5b6f5752015-06-01 14:15:10203#if defined(NODE_HAVE_I18N_SUPPORT)
204// Path to ICU data (for i18n / Intl)
Ben Noordhuis46345b92017-02-11 13:00:22205std::string icu_data_dir; // NOLINT(runtime/string)
Evan Lucas5b6f5752015-06-01 14:15:10206#endif
Steven R. Loomisac2857b2014-09-05 05:03:24207
isaacs48c3d202012-06-21 19:20:23208// used by C++ modules as well
209bool no_deprecation = false;
210
Fedor Indutnydb411cf2016-09-29 08:53:30211#if HAVE_OPENSSL
Adam Majer33012e92016-12-21 10:16:39212// use OpenSSL's cert store instead of bundled certs
213bool ssl_openssl_cert_store =
214#if defined(NODE_OPENSSL_CERT_STORE)
215 true;
216#else
217 false;
218#endif
219
Fedor Indutnydb411cf2016-09-29 08:53:30220# if NODE_FIPS_MODE
Stefan Budeanu7c48cb52016-01-22 23:10:09221// used by crypto module
222bool enable_fips_crypto = false;
223bool force_fips_crypto = false;
Fedor Indutnydb411cf2016-09-29 08:53:30224# endif // NODE_FIPS_MODE
Sam Roberts59afa272017-01-25 22:13:34225std::string openssl_config; // NOLINT(runtime/string)
Fedor Indutnydb411cf2016-09-29 08:53:30226#endif // HAVE_OPENSSL
Stefan Budeanu7c48cb52016-01-22 23:10:09227
James M Snellc6656db2016-01-20 19:38:35228// true if process warnings should be suppressed
229bool no_process_warnings = false;
230bool trace_warnings = false;
231
James M Snell5d38d542016-05-02 23:31:20232// Set in node.cc by ParseArgs when --preserve-symlinks is used.
233// Used in node_config.cc to set a constant on process.binding('config')
234// that is used by lib/module.js
235bool config_preserve_symlinks = false;
236
David Goldstein23659652018-04-10 07:40:56237// Set in node.cc by ParseArgs when --preserve-symlinks-main is used.
238// Used in node_config.cc to set a constant on process.binding('config')
239// that is used by lib/module.js
240bool config_preserve_symlinks_main = false;
241
Bradley Fariasc8a389e2017-06-06 00:44:56242// Set in node.cc by ParseArgs when --experimental-modules is used.
243// Used in node_config.cc to set a constant on process.binding('config')
244// that is used by lib/module.js
245bool config_experimental_modules = false;
246
Gus Caplan0993fbe2018-01-14 07:35:51247// Set in node.cc by ParseArgs when --experimental-vm-modules is used.
248// Used in node_config.cc to set a constant on process.binding('config')
249// that is used by lib/vm.js
250bool config_experimental_vm_modules = false;
251
Anna Henningsene7a23672017-09-05 20:38:32252// Set in node.cc by ParseArgs when --experimental-worker is used.
253// Used in node_config.cc to set a constant on process.binding('config')
254// that is used by lib/worker.js
255bool config_experimental_worker = false;
256
Timothy Gube92eab2018-03-26 03:13:54257// Set in node.cc by ParseArgs when --experimental-repl-await is used.
258// Used in node_config.cc to set a constant on process.binding('config')
259// that is used by lib/repl.js.
260bool config_experimental_repl_await = false;
261
guybedfordd21a11d2017-09-03 11:20:06262// Set in node.cc by ParseArgs when --loader is used.
263// Used in node_config.cc to set a constant on process.binding('config')
Joyee Cheung8484b402018-03-06 14:42:32264// that is used by lib/internal/bootstrap/node.js
guybedfordd21a11d2017-09-03 11:20:06265std::string config_userland_loader; // NOLINT(runtime/string)
266
James M Snella16b5702017-03-11 20:18:53267// Set by ParseArgs when --pending-deprecation or NODE_PENDING_DEPRECATION
268// is used.
269bool config_pending_deprecation = false;
270
James M Snell03e89b32016-12-04 18:38:35271// Set in node.cc by ParseArgs when --redirect-warnings= is used.
Ben Noordhuisa8734af2017-01-28 12:27:02272std::string config_warning_file; // NOLINT(runtime/string)
James M Snell03e89b32016-12-04 18:38:35273
Sam Roberts8086cb62017-04-05 21:06:52274// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
275// used.
276// Used in node_config.cc to set a constant on process.binding('config')
Joyee Cheung8484b402018-03-06 14:42:32277// that is used by lib/internal/bootstrap/node.js
Sam Roberts8086cb62017-04-05 21:06:52278bool config_expose_internals = false;
279
Anna Henningsen72c60e82016-09-10 16:21:20280bool v8_initialized = false;
281
Daniel Bevenius6caf1b02017-04-20 18:08:53282bool linux_at_secure = false;
283
Ben Noordhuis74a82152012-02-03 15:32:00284// process-relative uptime base, initialized at start-up
285static double prog_start_time;
Ben Noordhuis5d0816b2013-01-06 22:06:48286
Ben Noordhuisd7087df2016-06-17 23:39:05287static Mutex node_isolate_mutex;
Ben Noordhuis844f0a92016-03-25 16:59:07288static v8::Isolate* node_isolate;
Stefan Budeanu410296c2016-03-27 00:17:55289
Daniel Beveniuscae41822018-02-23 14:42:20290DebugOptions debug_options;
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22291
Stefan Budeanu410296c2016-03-27 00:17:55292static struct {
293#if NODE_USE_V8_PLATFORM
Anna Henningsenc7ad7292017-09-14 11:05:48294 void Initialize(int thread_pool_size) {
James M Snell5c27e442018-04-04 01:05:33295 tracing_agent_.reset(new tracing::Agent(trace_file_pattern));
Ali Ijaz Sheikh32873c52018-05-16 22:22:56296 auto controller = tracing_agent_->GetTracingController();
297 tracing::TraceEventHelper::SetTracingController(controller);
298 StartTracingAgent();
299 platform_ = new NodePlatform(thread_pool_size, controller);
James M Snell5c27e442018-04-04 01:05:33300 V8::InitializePlatform(platform_);
Stefan Budeanu410296c2016-03-27 00:17:55301 }
302
303 void Dispose() {
Matt Loring9e086952017-03-13 22:17:57304 platform_->Shutdown();
Stefan Budeanu410296c2016-03-27 00:17:55305 delete platform_;
306 platform_ = nullptr;
Franziska Hinkelmann787863d2017-11-12 21:16:10307 tracing_agent_.reset(nullptr);
Matt Loring9e086952017-03-13 22:17:57308 }
309
Anna Henningsenc7ad7292017-09-14 11:05:48310 void DrainVMTasks(Isolate* isolate) {
311 platform_->DrainBackgroundTasks(isolate);
Stefan Budeanu410296c2016-03-27 00:17:55312 }
313
Anna Henningsen2cedff92017-10-22 22:52:55314 void CancelVMTasks(Isolate* isolate) {
315 platform_->CancelPendingDelayedTasks(isolate);
316 }
317
Ben Noordhuisc5c28c32015-10-10 13:01:49318#if HAVE_INSPECTOR
Daniel Beveniuscbc3dd92018-05-16 09:50:48319 bool StartInspector(Environment* env, const char* script_path,
Daniel Beveniuscae41822018-02-23 14:42:20320 const DebugOptions& options) {
Sam Roberts2791b362017-05-26 02:00:24321 // Inspector agent can't fail to start, but if it was configured to listen
322 // right away on the websocket port and fails to bind/etc, this will return
323 // false.
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22324 return env->inspector_agent()->Start(platform_, script_path, options);
Ben Noordhuisc5c28c32015-10-10 13:01:49325 }
Eugene Ostroukhov5c263782017-05-01 20:31:14326
Daniel Beveniuscbc3dd92018-05-16 09:50:48327 bool InspectorStarted(Environment* env) {
Eugene Ostroukhov5c263782017-05-01 20:31:14328 return env->inspector_agent()->IsStarted();
329 }
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22330#endif // HAVE_INSPECTOR
Stefan Budeanu410296c2016-03-27 00:17:55331
Myk Melez046f66a2017-01-31 17:56:09332 void StartTracingAgent() {
James M Snell5c27e442018-04-04 01:05:33333 tracing_agent_->Enable(trace_enabled_categories);
Myk Melez046f66a2017-01-31 17:56:09334 }
335
336 void StopTracingAgent() {
Anna Henningsen5e6ca892018-05-09 17:52:53337 if (tracing_agent_)
338 tracing_agent_->Stop();
Myk Melez046f66a2017-01-31 17:56:09339 }
340
James M Snell5c27e442018-04-04 01:05:33341 tracing::Agent* GetTracingAgent() const {
342 return tracing_agent_.get();
343 }
344
Anna Henningsenc7ad7292017-09-14 11:05:48345 NodePlatform* Platform() {
346 return platform_;
347 }
348
Franziska Hinkelmann787863d2017-11-12 21:16:10349 std::unique_ptr<tracing::Agent> tracing_agent_;
Matt Loring9e086952017-03-13 22:17:57350 NodePlatform* platform_;
Stefan Budeanu410296c2016-03-27 00:17:55351#else // !NODE_USE_V8_PLATFORM
Anna Henningsenc7ad7292017-09-14 11:05:48352 void Initialize(int thread_pool_size) {}
Stefan Budeanu410296c2016-03-27 00:17:55353 void Dispose() {}
Anna Henningsenc7ad7292017-09-14 11:05:48354 void DrainVMTasks(Isolate* isolate) {}
Anna Henningsen2cedff92017-10-22 22:52:55355 void CancelVMTasks(Isolate* isolate) {}
Daniel Beveniuscbc3dd92018-05-16 09:50:48356 bool StartInspector(Environment* env, const char* script_path,
Daniel Beveniuscae41822018-02-23 14:42:20357 const DebugOptions& options) {
Stefan Budeanu410296c2016-03-27 00:17:55358 env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
Eugene Ostroukhov7599b0e2016-12-13 01:08:31359 return true;
Stefan Budeanu410296c2016-03-27 00:17:55360 }
Myk Melez046f66a2017-01-31 17:56:09361
362 void StartTracingAgent() {
James M Snell5c27e442018-04-04 01:05:33363 if (!trace_enabled_categories.empty()) {
364 fprintf(stderr, "Node compiled with NODE_USE_V8_PLATFORM=0, "
365 "so event tracing is not available.\n");
366 }
Myk Melez046f66a2017-01-31 17:56:09367 }
368 void StopTracingAgent() {}
Anna Henningsenc7ad7292017-09-14 11:05:48369
James M Snell5c27e442018-04-04 01:05:33370 tracing::Agent* GetTracingAgent() const { return nullptr; }
371
Anna Henningsenc7ad7292017-09-14 11:05:48372 NodePlatform* Platform() {
373 return nullptr;
374 }
Daniel Beveniusae5e65c2017-05-23 05:40:48375#endif // !NODE_USE_V8_PLATFORM
376
377#if !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
Daniel Beveniuscbc3dd92018-05-16 09:50:48378 bool InspectorStarted(Environment* env) {
Eugene Ostroukhov5c263782017-05-01 20:31:14379 return false;
380 }
Daniel Beveniusae5e65c2017-05-23 05:40:48381#endif // !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
Stefan Budeanu410296c2016-03-27 00:17:55382} v8_platform;
Ben Noordhuis5d0816b2013-01-06 22:06:48383
Ben Noordhuis844f0a92016-03-25 16:59:07384#ifdef __POSIX__
Eugene Ostroukhov66269192016-06-08 21:09:28385static const unsigned kMaxSignal = 32;
Ben Noordhuis844f0a92016-03-25 16:59:07386#endif
387
Brian White2d356072015-10-13 21:18:15388static void PrintErrorString(const char* format, ...) {
389 va_list ap;
390 va_start(ap, format);
391#ifdef _WIN32
392 HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
393
394 // Check if stderr is something other than a tty/console
395 if (stderr_handle == INVALID_HANDLE_VALUE ||
396 stderr_handle == nullptr ||
397 uv_guess_handle(_fileno(stderr)) != UV_TTY) {
398 vfprintf(stderr, format, ap);
Ömer Fadıl Usta44a298b2015-10-28 12:49:51399 va_end(ap);
Brian White2d356072015-10-13 21:18:15400 return;
401 }
402
403 // Fill in any placeholders
404 int n = _vscprintf(format, ap);
405 std::vector<char> out(n + 1);
406 vsprintf(out.data(), format, ap);
407
408 // Get required wide buffer size
409 n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
410
411 std::vector<wchar_t> wbuf(n);
412 MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
Nikolai Vavilov09f861f2016-07-16 17:06:47413
414 // Don't include the null character in the output
415 CHECK_GT(n, 0);
416 WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
Brian White2d356072015-10-13 21:18:15417#else
418 vfprintf(stderr, format, ap);
419#endif
420 va_end(ap);
421}
422
Daniel Beveniuscbc3dd92018-05-16 09:50:48423const char* signo_string(int signo) {
Felix Geisendörferf8a3cf92010-04-28 13:04:08424#define SIGNO_CASE(e) case e: return #e;
425 switch (signo) {
Felix Geisendörferf8a3cf92010-04-28 13:04:08426#ifdef SIGHUP
427 SIGNO_CASE(SIGHUP);
428#endif
429
430#ifdef SIGINT
431 SIGNO_CASE(SIGINT);
432#endif
433
434#ifdef SIGQUIT
435 SIGNO_CASE(SIGQUIT);
436#endif
437
438#ifdef SIGILL
439 SIGNO_CASE(SIGILL);
440#endif
441
442#ifdef SIGTRAP
443 SIGNO_CASE(SIGTRAP);
444#endif
445
446#ifdef SIGABRT
447 SIGNO_CASE(SIGABRT);
448#endif
449
450#ifdef SIGIOT
451# if SIGABRT != SIGIOT
452 SIGNO_CASE(SIGIOT);
453# endif
454#endif
455
456#ifdef SIGBUS
457 SIGNO_CASE(SIGBUS);
458#endif
459
460#ifdef SIGFPE
461 SIGNO_CASE(SIGFPE);
462#endif
463
464#ifdef SIGKILL
465 SIGNO_CASE(SIGKILL);
466#endif
467
468#ifdef SIGUSR1
469 SIGNO_CASE(SIGUSR1);
470#endif
471
472#ifdef SIGSEGV
473 SIGNO_CASE(SIGSEGV);
474#endif
475
476#ifdef SIGUSR2
477 SIGNO_CASE(SIGUSR2);
478#endif
479
480#ifdef SIGPIPE
481 SIGNO_CASE(SIGPIPE);
482#endif
483
484#ifdef SIGALRM
485 SIGNO_CASE(SIGALRM);
486#endif
487
488 SIGNO_CASE(SIGTERM);
Bert Belderdcc35082010-11-25 00:04:31489
490#ifdef SIGCHLD
Felix Geisendörferf8a3cf92010-04-28 13:04:08491 SIGNO_CASE(SIGCHLD);
Bert Belderdcc35082010-11-25 00:04:31492#endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08493
494#ifdef SIGSTKFLT
495 SIGNO_CASE(SIGSTKFLT);
496#endif
497
498
499#ifdef SIGCONT
500 SIGNO_CASE(SIGCONT);
501#endif
502
503#ifdef SIGSTOP
504 SIGNO_CASE(SIGSTOP);
505#endif
506
507#ifdef SIGTSTP
508 SIGNO_CASE(SIGTSTP);
509#endif
510
Bert Belder600a6462012-08-20 21:59:21511#ifdef SIGBREAK
512 SIGNO_CASE(SIGBREAK);
513#endif
514
Felix Geisendörferf8a3cf92010-04-28 13:04:08515#ifdef SIGTTIN
516 SIGNO_CASE(SIGTTIN);
517#endif
518
519#ifdef SIGTTOU
520 SIGNO_CASE(SIGTTOU);
521#endif
522
523#ifdef SIGURG
524 SIGNO_CASE(SIGURG);
525#endif
526
527#ifdef SIGXCPU
528 SIGNO_CASE(SIGXCPU);
529#endif
530
531#ifdef SIGXFSZ
532 SIGNO_CASE(SIGXFSZ);
533#endif
534
535#ifdef SIGVTALRM
536 SIGNO_CASE(SIGVTALRM);
537#endif
538
539#ifdef SIGPROF
540 SIGNO_CASE(SIGPROF);
541#endif
542
543#ifdef SIGWINCH
544 SIGNO_CASE(SIGWINCH);
545#endif
546
547#ifdef SIGIO
548 SIGNO_CASE(SIGIO);
549#endif
550
551#ifdef SIGPOLL
Ryan Dahl3bb21b52010-04-28 22:07:15552# if SIGPOLL != SIGIO
Felix Geisendörferf8a3cf92010-04-28 13:04:08553 SIGNO_CASE(SIGPOLL);
Ryan Dahl3bb21b52010-04-28 22:07:15554# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08555#endif
556
557#ifdef SIGLOST
Michael Dawson2a17c7f2015-08-12 15:53:33558# if SIGLOST != SIGABRT
Felix Geisendörferf8a3cf92010-04-28 13:04:08559 SIGNO_CASE(SIGLOST);
Michael Dawson2a17c7f2015-08-12 15:53:33560# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08561#endif
562
563#ifdef SIGPWR
Raffaele Senab3b81d62010-06-09 04:08:05564# if SIGPWR != SIGLOST
Felix Geisendörferf8a3cf92010-04-28 13:04:08565 SIGNO_CASE(SIGPWR);
Raffaele Senab3b81d62010-06-09 04:08:05566# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08567#endif
568
James Reggiofb5f66a2016-04-07 01:00:04569#ifdef SIGINFO
570# if !defined(SIGPWR) || SIGINFO != SIGPWR
571 SIGNO_CASE(SIGINFO);
572# endif
573#endif
574
Felix Geisendörferf8a3cf92010-04-28 13:04:08575#ifdef SIGSYS
576 SIGNO_CASE(SIGSYS);
577#endif
578
Felix Geisendörferf8a3cf92010-04-28 13:04:08579 default: return "";
580 }
581}
582
Ben Noordhuis8f6c5872014-10-11 19:48:25583// Look up environment variable unless running as setuid root.
Sam Roberts901e9262017-01-27 19:49:14584bool SafeGetenv(const char* key, std::string* text) {
Ed Schouten78dbcbe2017-10-30 10:58:13585#if !defined(__CloudABI__) && !defined(_WIN32)
cjihrig88fe7e82017-05-25 17:32:37586 if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
587 goto fail;
Ben Noordhuis8f6c5872014-10-11 19:48:25588#endif
cjihrig88fe7e82017-05-25 17:32:37589
Anna Henningsen2c52f652018-05-05 15:47:02590 {
591 Mutex::ScopedLock lock(environ_mutex);
592 if (const char* value = getenv(key)) {
593 *text = value;
594 return true;
595 }
Ben Noordhuisa8734af2017-01-28 12:27:02596 }
cjihrig88fe7e82017-05-25 17:32:37597
598fail:
Ben Noordhuisa8734af2017-01-28 12:27:02599 text->clear();
600 return false;
Ben Noordhuis8f6c5872014-10-11 19:48:25601}
602
603
Trevor Norris74178a52015-09-14 22:31:10604void* ArrayBufferAllocator::Allocate(size_t size) {
Ben Noordhuis27e84dd2016-05-31 18:58:31605 if (zero_fill_field_ || zero_fill_all_buffers)
Daniel Beveniuscae41822018-02-23 14:42:20606 return UncheckedCalloc(size);
Ben Noordhuis3a399632016-06-01 13:53:01607 else
Daniel Beveniuscae41822018-02-23 14:42:20608 return UncheckedMalloc(size);
Trevor Norris74178a52015-09-14 22:31:10609}
610
Anna Henningsen9d522222017-04-12 17:17:24611namespace {
612
Anna Henningsen9d522222017-04-12 17:17:24613bool ShouldAbortOnUncaughtException(Isolate* isolate) {
Jeremy Whitlock77a10ed2015-10-05 20:08:53614 HandleScope scope(isolate);
Jeremy Whitlock77a10ed2015-10-05 20:08:53615 Environment* env = Environment::GetCurrent(isolate);
Anna Henningsenb73e66e2017-11-29 19:55:43616 return env->should_abort_on_uncaught_toggle()[0] &&
617 !env->inside_should_not_abort_on_uncaught_scope();
Jeremy Whitlock77a10ed2015-10-05 20:08:53618}
619
Anna Henningsen9d522222017-04-12 17:17:24620} // anonymous namespace
621
Trevor Norris3f5d5842013-08-07 00:01:44622
Anna Henningsene5a25cb2017-04-21 21:06:21623void AddPromiseHook(v8::Isolate* isolate, promise_hook_func fn, void* arg) {
624 Environment* env = Environment::GetCurrent(isolate);
625 env->AddPromiseHook(fn, arg);
626}
627
Anna Henningsen5c6cf302017-09-09 20:28:02628void AddEnvironmentCleanupHook(v8::Isolate* isolate,
629 void (*fun)(void* arg),
630 void* arg) {
631 Environment* env = Environment::GetCurrent(isolate);
632 env->AddCleanupHook(fun, arg);
633}
634
635
636void RemoveEnvironmentCleanupHook(v8::Isolate* isolate,
637 void (*fun)(void* arg),
638 void* arg) {
639 Environment* env = Environment::GetCurrent(isolate);
640 env->RemoveCleanupHook(fun, arg);
641}
642
Anna Henningsen64616bb2017-08-08 18:02:55643MaybeLocal<Value> InternalMakeCallback(Environment* env,
644 Local<Object> recv,
645 const Local<Function> callback,
646 int argc,
647 Local<Value> argv[],
648 async_context asyncContext) {
Anna Henningsenf27b5e42017-09-15 13:03:48649 CHECK(!recv.IsEmpty());
Anna Henningsen64616bb2017-08-08 18:02:55650 InternalCallbackScope scope(env, recv, asyncContext);
651 if (scope.Failed()) {
652 return Undefined(env->isolate());
Anna Henningsena86323d2017-05-21 17:39:52653 }
654
Anatoli Papirovskieeede3b2018-01-19 20:42:59655 Local<Function> domain_cb = env->domain_callback();
656 MaybeLocal<Value> ret;
657 if (asyncContext.async_id != 0 || domain_cb.IsEmpty() || recv.IsEmpty()) {
658 ret = callback->Call(env->context(), recv, argc, argv);
659 } else {
660 std::vector<Local<Value>> args(1 + argc);
661 args[0] = callback;
Anatoli Papirovski332b56c2018-01-30 18:34:57662 std::copy(&argv[0], &argv[argc], args.begin() + 1);
Anatoli Papirovskieeede3b2018-01-19 20:42:59663 ret = domain_cb->Call(env->context(), recv, args.size(), &args[0]);
664 }
Anna Henningsena86323d2017-05-21 17:39:52665
Anatoli Papirovski7d3a3022018-01-21 15:34:36666 if (ret.IsEmpty()) {
667 // NOTE: For backwards compatibility with public API we return Undefined()
668 // if the top level call threw.
669 scope.MarkAsFailed();
670 return scope.IsInnerMakeCallback() ? ret : Undefined(env->isolate());
Trevor Norrisa1da0242014-12-09 04:24:59671 }
Trevor Norrisefa62fd2013-09-24 21:12:11672
Anna Henningsen64616bb2017-08-08 18:02:55673 scope.Close();
674 if (scope.Failed()) {
Fedor Indutny75adde02014-02-21 13:02:42675 return Undefined(env->isolate());
Trevor Norris95afe282016-02-11 20:57:26676 }
Trevor Norris86c07452013-02-07 01:26:18677
Trevor Norrisa0867e12013-03-17 04:59:47678 return ret;
679}
680
681
Anna Henningsena86323d2017-05-21 17:39:52682// Public MakeCallback()s
683
684
685MaybeLocal<Value> MakeCallback(Isolate* isolate,
686 Local<Object> recv,
687 const char* method,
688 int argc,
689 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:03690 async_context asyncContext) {
Anna Henningsena86323d2017-05-21 17:39:52691 Local<String> method_string =
692 String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
693 .ToLocalChecked();
Andreas Madsenc6ce5002017-07-06 06:20:03694 return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
Trevor Norris86c07452013-02-07 01:26:18695}
696
697
Anna Henningsena86323d2017-05-21 17:39:52698MaybeLocal<Value> MakeCallback(Isolate* isolate,
699 Local<Object> recv,
700 Local<String> symbol,
701 int argc,
702 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:03703 async_context asyncContext) {
Ben Noordhuis921d2b02016-10-21 09:57:20704 Local<Value> callback_v = recv->Get(symbol);
705 if (callback_v.IsEmpty()) return Local<Value>();
706 if (!callback_v->IsFunction()) return Local<Value>();
707 Local<Function> callback = callback_v.As<Function>();
Andreas Madsenc6ce5002017-07-06 06:20:03708 return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
Ben Noordhuis756b6222013-08-10 22:26:11709}
710
711
Anna Henningsena86323d2017-05-21 17:39:52712MaybeLocal<Value> MakeCallback(Isolate* isolate,
713 Local<Object> recv,
714 Local<Function> callback,
715 int argc,
716 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:03717 async_context asyncContext) {
Ben Noordhuis921d2b02016-10-21 09:57:20718 // Observe the following two subtleties:
719 //
720 // 1. The environment is retrieved from the callback function's context.
721 // 2. The context to enter is retrieved from the environment.
722 //
723 // Because of the AssignToContext() call in src/node_contextify.cc,
724 // the two contexts need not be the same.
Ben Noordhuis921d2b02016-10-21 09:57:20725 Environment* env = Environment::GetCurrent(callback->CreationContext());
726 Context::Scope context_scope(env->context());
Anna Henningsen64616bb2017-08-08 18:02:55727 return InternalMakeCallback(env, recv, callback,
728 argc, argv, asyncContext);
Anna Henningsena86323d2017-05-21 17:39:52729}
730
731
732// Legacy MakeCallback()s
733
734Local<Value> MakeCallback(Isolate* isolate,
735 Local<Object> recv,
736 const char* method,
737 int argc,
738 Local<Value>* argv) {
739 EscapableHandleScope handle_scope(isolate);
Ben Noordhuis921d2b02016-10-21 09:57:20740 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:03741 MakeCallback(isolate, recv, method, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:52742 .FromMaybe(Local<Value>()));
743}
744
745
746Local<Value> MakeCallback(Isolate* isolate,
747 Local<Object> recv,
748 Local<String> symbol,
749 int argc,
750 Local<Value>* argv) {
751 EscapableHandleScope handle_scope(isolate);
752 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:03753 MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:52754 .FromMaybe(Local<Value>()));
755}
756
757
758Local<Value> MakeCallback(Isolate* isolate,
759 Local<Object> recv,
760 Local<Function> callback,
761 int argc,
762 Local<Value>* argv) {
763 EscapableHandleScope handle_scope(isolate);
764 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:03765 MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:52766 .FromMaybe(Local<Value>()));
Ben Noordhuis1f2f3fa2014-01-27 02:58:16767}
768
Brian White18490d32015-12-15 08:55:35769bool IsExceptionDecorated(Environment* env, Local<Value> er) {
770 if (!er.IsEmpty() && er->IsObject()) {
771 Local<Object> err_obj = er.As<Object>();
Ben Noordhuis924cc6c2016-02-02 22:50:07772 auto maybe_value =
773 err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
774 Local<Value> decorated;
775 return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
Brian White18490d32015-12-15 08:55:35776 }
777 return false;
778}
779
Fedor Indutnyf1de13b2014-02-05 16:38:33780void AppendExceptionLine(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:16781 Local<Value> er,
Anna Henningsen3cac6162016-06-24 03:50:00782 Local<Message> message,
783 enum ErrorHandlingMode mode) {
Fedor Indutnyf1de13b2014-02-05 16:38:33784 if (message.IsEmpty())
Fedor Indutny2bc30f22013-10-16 16:57:26785 return;
isaacsb3cf3f32012-07-28 21:00:27786
Fedor Indutnyf1de13b2014-02-05 16:38:33787 HandleScope scope(env->isolate());
788 Local<Object> err_obj;
789 if (!er.IsEmpty() && er->IsObject()) {
790 err_obj = er.As<Object>();
Ryan Dahl8e6dd522010-01-15 18:45:04791 }
Fedor Indutnyf1de13b2014-02-05 16:38:33792
Fedor Indutnyf1de13b2014-02-05 16:38:33793 // Print (filename):(line number): (message).
Timothy Gu3aea4c82017-10-04 03:51:12794 ScriptOrigin origin = message->GetScriptOrigin();
Trevor Norriscbf76c12015-01-07 22:13:35795 node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
Fedor Indutnyf1de13b2014-02-05 16:38:33796 const char* filename_string = *filename;
Sarat Addepallic6c957d2018-03-20 17:59:17797 int linenum = message->GetLineNumber(env->context()).FromJust();
Fedor Indutnyf1de13b2014-02-05 16:38:33798 // Print line of source code.
Sarat Addepallic6c957d2018-03-20 17:59:17799 MaybeLocal<String> source_line_maybe = message->GetSourceLine(env->context());
800 node::Utf8Value sourceline(env->isolate(),
801 source_line_maybe.ToLocalChecked());
Fedor Indutnyf1de13b2014-02-05 16:38:33802 const char* sourceline_string = *sourceline;
Anna Henningsenb73e66e2017-11-29 19:55:43803 if (strstr(sourceline_string, "node-do-not-add-exception-line") != nullptr)
804 return;
Fedor Indutnyf1de13b2014-02-05 16:38:33805
806 // Because of how node modules work, all scripts are wrapped with a
807 // "function (module, exports, __filename, ...) {"
808 // to provide script local variables.
809 //
810 // When reporting errors on the first line of a script, this wrapper
811 // function is leaked to the user. There used to be a hack here to
812 // truncate off the first 62 characters, but it caused numerous other
813 // problems when vm.runIn*Context() methods were used for non-module
814 // code.
815 //
816 // If we ever decide to re-instate such a hack, the following steps
817 // must be taken:
818 //
819 // 1. Pass a flag around to say "this code was wrapped"
820 // 2. Update the stack frame output so that it is also correct.
821 //
822 // It would probably be simpler to add a line rather than add some
823 // number of characters to the first line, since V8 truncates the
824 // sourceline to 78 characters, and we end up not providing very much
825 // useful debugging info to the user if we remove 62 characters.
826
Timothy Gu3aea4c82017-10-04 03:51:12827 int script_start =
828 (linenum - origin.ResourceLineOffset()->Value()) == 1 ?
829 origin.ResourceColumnOffset()->Value() : 0;
Anna Henningsen4bd410b2016-05-20 20:55:37830 int start = message->GetStartColumn(env->context()).FromMaybe(0);
831 int end = message->GetEndColumn(env->context()).FromMaybe(0);
Timothy Gu3aea4c82017-10-04 03:51:12832 if (start >= script_start) {
833 CHECK_GE(end, start);
834 start -= script_start;
835 end -= script_start;
836 }
Fedor Indutnyf1de13b2014-02-05 16:38:33837
Karl Skomski3bb92372015-09-03 08:10:29838 char arrow[1024];
839 int max_off = sizeof(arrow) - 2;
840
Fedor Indutnyf1de13b2014-02-05 16:38:33841 int off = snprintf(arrow,
842 sizeof(arrow),
843 "%s:%i\n%s\n",
844 filename_string,
845 linenum,
846 sourceline_string);
Ben Noordhuis5fdff382014-10-11 14:52:07847 CHECK_GE(off, 0);
Karl Skomski3bb92372015-09-03 08:10:29848 if (off > max_off) {
849 off = max_off;
850 }
Fedor Indutnyf1de13b2014-02-05 16:38:33851
852 // Print wavy underline (GetUnderline is deprecated).
853 for (int i = 0; i < start; i++) {
Karl Skomski3bb92372015-09-03 08:10:29854 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:50855 break;
856 }
Karl Skomski3bb92372015-09-03 08:10:29857 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:33858 arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
859 }
860 for (int i = start; i < end; i++) {
Karl Skomski3bb92372015-09-03 08:10:29861 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:50862 break;
863 }
Karl Skomski3bb92372015-09-03 08:10:29864 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:33865 arrow[off++] = '^';
866 }
Karl Skomski3bb92372015-09-03 08:10:29867 CHECK_LE(off, max_off);
868 arrow[off] = '\n';
869 arrow[off + 1] = '\0';
Fedor Indutnyf1de13b2014-02-05 16:38:33870
871 Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
Fedor Indutnyf1de13b2014-02-05 16:38:33872
Anna Henningsen3cac6162016-06-24 03:50:00873 const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
874 // If allocating arrow_str failed, print it out. There's not much else to do.
875 // If it's not an error, but something needs to be printed out because
876 // it's a fatal exception, also print it out from here.
877 // Otherwise, the arrow property will be attached to the object and handled
878 // by the caller.
879 if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
880 if (env->printed_error())
881 return;
Anna Henningsen2c52f652018-05-05 15:47:02882 Mutex::ScopedLock lock(process_mutex);
Anna Henningsen3cac6162016-06-24 03:50:00883 env->set_printed_error(true);
884
Evan Lucas14dc17d2018-06-11 14:20:50885 uv_tty_reset_mode();
Anna Henningsen3cac6162016-06-24 03:50:00886 PrintErrorString("\n%s", arrow);
Ben Noordhuis924cc6c2016-02-02 22:50:07887 return;
888 }
Fedor Indutnyf1de13b2014-02-05 16:38:33889
Anna Henningsen3cac6162016-06-24 03:50:00890 CHECK(err_obj->SetPrivate(
891 env->context(),
892 env->arrow_message_private_symbol(),
893 arrow_str).FromMaybe(false));
Ryan Dahlb57c1f52010-11-24 02:46:13894}
895
896
Anna Henningsen0df031a2017-09-01 15:03:41897void ReportException(Environment* env,
898 Local<Value> er,
899 Local<Message> message) {
Anna Henningsena0126722017-11-27 00:31:24900 CHECK(!er.IsEmpty());
Fedor Indutnyf1de13b2014-02-05 16:38:33901 HandleScope scope(env->isolate());
Ryan Dahlb57c1f52010-11-24 02:46:13902
Ben Noordhuisde4e0d72018-05-13 21:38:07903 if (message.IsEmpty())
904 message = Exception::CreateMessage(env->isolate(), er);
905
Anna Henningsen3cac6162016-06-24 03:50:00906 AppendExceptionLine(env, er, message, FATAL_ERROR);
Ryan Dahl53a841d2009-12-29 19:20:51907
Vladimir Kurchatkin259d4492013-12-06 11:56:37908 Local<Value> trace_value;
Fedor Indutnyef653212015-07-05 18:20:26909 Local<Value> arrow;
Brian White18490d32015-12-15 08:55:35910 const bool decorated = IsExceptionDecorated(env, er);
Vladimir Kurchatkin259d4492013-12-06 11:56:37911
Fedor Indutnyef653212015-07-05 18:20:26912 if (er->IsUndefined() || er->IsNull()) {
Fedor Indutnyf1de13b2014-02-05 16:38:33913 trace_value = Undefined(env->isolate());
Fedor Indutnyef653212015-07-05 18:20:26914 } else {
Leko19221d12017-11-27 07:16:32915 Local<Object> err_obj = er->ToObject(env->context()).ToLocalChecked();
Fedor Indutnyef653212015-07-05 18:20:26916
917 trace_value = err_obj->Get(env->stack_string());
Ben Noordhuis924cc6c2016-02-02 22:50:07918 arrow =
919 err_obj->GetPrivate(
920 env->context(),
921 env->arrow_message_private_symbol()).ToLocalChecked();
Fedor Indutnyef653212015-07-05 18:20:26922 }
Vladimir Kurchatkin259d4492013-12-06 11:56:37923
Trevor Norriscbf76c12015-01-07 22:13:35924 node::Utf8Value trace(env->isolate(), trace_value);
Ryan Dahlda932302010-05-14 18:48:14925
isaacs8df6f9e2011-04-25 19:22:18926 // range errors have a trace member set to undefined
Miroslav Bajtosc16963b2013-06-17 19:19:59927 if (trace.length() > 0 && !trace_value->IsUndefined()) {
Brian White18490d32015-12-15 08:55:35928 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:15929 PrintErrorString("%s\n", *trace);
Fedor Indutnyef653212015-07-05 18:20:26930 } else {
931 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:15932 PrintErrorString("%s\n%s\n", *arrow_string, *trace);
Fedor Indutnyef653212015-07-05 18:20:26933 }
isaacse9b6b0b2010-10-02 06:22:34934 } else {
935 // this really only happens for RangeErrors, since they're the only
isaacs8df6f9e2011-04-25 19:22:18936 // kind that won't have all this info in the trace, or when non-Error
937 // objects are thrown manually.
Ben Noordhuisf674b092013-08-07 19:50:41938 Local<Value> message;
939 Local<Value> name;
isaacs8df6f9e2011-04-25 19:22:18940
Ben Noordhuisf674b092013-08-07 19:50:41941 if (er->IsObject()) {
942 Local<Object> err_obj = er.As<Object>();
Fedor Indutnyf1de13b2014-02-05 16:38:33943 message = err_obj->Get(env->message_string());
944 name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
isaacs8df6f9e2011-04-25 19:22:18945 }
946
Ben Noordhuisf674b092013-08-07 19:50:41947 if (message.IsEmpty() ||
948 message->IsUndefined() ||
949 name.IsEmpty() ||
950 name->IsUndefined()) {
951 // Not an error object. Just print as-is.
Sarat Addepallic6c957d2018-03-20 17:59:17952 String::Utf8Value message(env->isolate(), er);
cjihrig1ec09b02015-12-02 01:34:45953
954 PrintErrorString("%s\n", *message ? *message :
955 "<toString() threw exception>");
Ben Noordhuisf674b092013-08-07 19:50:41956 } else {
Trevor Norriscbf76c12015-01-07 22:13:35957 node::Utf8Value name_string(env->isolate(), name);
958 node::Utf8Value message_string(env->isolate(), message);
Fedor Indutnyef653212015-07-05 18:20:26959
Brian White18490d32015-12-15 08:55:35960 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:15961 PrintErrorString("%s: %s\n", *name_string, *message_string);
Fedor Indutnyef653212015-07-05 18:20:26962 } else {
963 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:15964 PrintErrorString("%s\n%s: %s\n",
965 *arrow_string,
966 *name_string,
967 *message_string);
Fedor Indutnyef653212015-07-05 18:20:26968 }
Ben Noordhuisf674b092013-08-07 19:50:41969 }
Ryan5131e0a2009-03-09 00:23:41970 }
isaacse9b6b0b2010-10-02 06:22:34971
Ryand7e220c2009-09-09 20:35:40972 fflush(stderr);
Anna Henningsena0126722017-11-27 00:31:24973
974#if HAVE_INSPECTOR
975 env->inspector_agent()->FatalException(er, message);
976#endif
Ryan5131e0a2009-03-09 00:23:41977}
978
Miroslav Bajtosc16963b2013-06-17 19:19:59979
Fedor Indutnyf1de13b2014-02-05 16:38:33980static void ReportException(Environment* env, const TryCatch& try_catch) {
981 ReportException(env, try_catch.Exception(), try_catch.Message());
Miroslav Bajtosc16963b2013-06-17 19:19:59982}
983
984
Ryand6c9d312009-09-11 14:02:29985// Executes a str within the current v8 context.
Anna Henningsen0df031a2017-09-01 15:03:41986static MaybeLocal<Value> ExecuteString(Environment* env,
987 Local<String> source,
988 Local<String> filename) {
Fedor Indutnyce04c722014-03-13 16:38:14989 EscapableHandleScope scope(env->isolate());
Michaël Zasso79d74752016-01-26 08:06:43990 TryCatch try_catch(env->isolate());
Ryan408526a2009-04-21 11:52:21991
Miroslav Bajtosc16963b2013-06-17 19:19:59992 // try_catch must be nonverbose to disable FatalException() handler,
993 // we will handle exceptions ourself.
994 try_catch.SetVerbose(false);
995
Michaël Zasso023c3172016-02-08 21:34:05996 ScriptOrigin origin(filename);
997 MaybeLocal<v8::Script> script =
998 v8::Script::Compile(env->context(), source, &origin);
Ryan63a9cd32009-04-15 08:08:28999 if (script.IsEmpty()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331000 ReportException(env, try_catch);
Anna Henningsen0df031a2017-09-01 15:03:411001 env->Exit(3);
1002 return MaybeLocal<Value>();
Ryan63a9cd32009-04-15 08:08:281003 }
1004
Sarat Addepallic6c957d2018-03-20 17:59:171005 MaybeLocal<Value> result = script.ToLocalChecked()->Run(env->context());
Ryan63a9cd32009-04-15 08:08:281006 if (result.IsEmpty()) {
Anna Henningsen0df031a2017-09-01 15:03:411007 if (try_catch.HasTerminated()) {
1008 env->isolate()->CancelTerminateExecution();
1009 return MaybeLocal<Value>();
1010 }
Fedor Indutnyf1de13b2014-02-05 16:38:331011 ReportException(env, try_catch);
Anna Henningsen0df031a2017-09-01 15:03:411012 env->Exit(4);
1013 return MaybeLocal<Value>();
Ryan63a9cd32009-04-15 08:08:281014 }
1015
Sarat Addepallic6c957d2018-03-20 17:59:171016 return scope.Escape(result.ToLocalChecked());
Ryan63a9cd32009-04-15 08:08:281017}
1018
Felix Geisendörfer7371fcb2009-11-11 17:10:581019
Ben Noordhuis110a9cd2013-07-03 02:23:441020static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551021 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101022
Fedor Indutnyce04c722014-03-13 16:38:141023 Local<Array> ary = Array::New(args.GetIsolate());
Trevor Norris494227b2015-10-14 20:58:521024 Local<Context> ctx = env->context();
Trevor Norris83524b32015-11-10 09:58:511025 Local<Function> fn = env->push_values_to_array_function();
Trevor Norris946315f2015-11-11 00:04:561026 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1027 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101028
Trevor Norris494227b2015-10-14 20:58:521029 for (auto w : *env->req_wrap_queue()) {
Trevor Norris946315f2015-11-11 00:04:561030 if (w->persistent().IsEmpty())
1031 continue;
1032 argv[idx] = w->object();
Ben Noordhuisa7581d02016-03-31 10:47:061033 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561034 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1035 idx = 0;
Trevor Norris494227b2015-10-14 20:58:521036 }
1037 }
1038
Trevor Norris946315f2015-11-11 00:04:561039 if (idx > 0) {
1040 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Trevor Norris494227b2015-10-14 20:58:521041 }
Ben Noordhuis5f040652012-04-28 16:45:101042
Ben Noordhuis110a9cd2013-07-03 02:23:441043 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101044}
1045
1046
1047// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1048// implemented here for consistency with GetActiveRequests().
Ben Noordhuis110a9cd2013-07-03 02:23:441049void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551050 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101051
Fedor Indutnyce04c722014-03-13 16:38:141052 Local<Array> ary = Array::New(env->isolate());
Trevor Norris946315f2015-11-11 00:04:561053 Local<Context> ctx = env->context();
1054 Local<Function> fn = env->push_values_to_array_function();
1055 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1056 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101057
Fedor Indutny75adde02014-02-21 13:02:421058 Local<String> owner_sym = env->owner_string();
Ben Noordhuise813e342012-05-15 15:24:061059
Ben Noordhuis38dc0cd2015-01-30 11:54:531060 for (auto w : *env->handle_wrap_queue()) {
Ben Noordhuiscad1a622016-04-26 10:01:461061 if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
Fedor Indutny2bc30f22013-10-16 16:57:261062 continue;
Ben Noordhuis110a9cd2013-07-03 02:23:441063 Local<Object> object = w->object();
1064 Local<Value> owner = object->Get(owner_sym);
Fedor Indutny2bc30f22013-10-16 16:57:261065 if (owner->IsUndefined())
1066 owner = object;
Trevor Norris946315f2015-11-11 00:04:561067 argv[idx] = owner;
Ben Noordhuisa7581d02016-03-31 10:47:061068 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561069 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1070 idx = 0;
1071 }
1072 }
1073 if (idx > 0) {
1074 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Ben Noordhuis5f040652012-04-28 16:45:101075 }
1076
Ben Noordhuis110a9cd2013-07-03 02:23:441077 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101078}
1079
1080
Ben Noordhuisbe767cf2016-06-19 08:44:221081NO_RETURN void Abort() {
1082 DumpBacktrace(stderr);
1083 fflush(stderr);
1084 ABORT_NO_BACKTRACE();
1085}
1086
1087
Ben Noordhuis92dab4a2016-06-19 10:10:451088NO_RETURN void Assert(const char* const (*args)[4]) {
1089 auto filename = (*args)[0];
1090 auto linenum = (*args)[1];
1091 auto message = (*args)[2];
1092 auto function = (*args)[3];
1093
Ben Noordhuisf526deb2017-11-20 22:37:501094 char name[1024];
1095 GetHumanReadableProcessName(&name);
Ben Noordhuis92dab4a2016-06-19 10:10:451096
Ben Noordhuisf526deb2017-11-20 22:37:501097 fprintf(stderr, "%s: %s:%s:%s%s Assertion `%s' failed.\n",
1098 name, filename, linenum, function, *function ? ":" : "", message);
Ben Noordhuis92dab4a2016-06-19 10:10:451099 fflush(stderr);
1100
1101 Abort();
1102}
1103
1104
Ben Noordhuis110a9cd2013-07-03 02:23:441105static void Abort(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisbe767cf2016-06-19 08:44:221106 Abort();
Robert Mustacchi22404862011-12-15 01:02:151107}
1108
1109
James M Snellcb3d0492018-05-23 22:04:231110void Chdir(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551111 Environment* env = Environment::GetCurrent(args);
Anna Henningsen0df031a2017-09-01 15:03:411112 CHECK(env->is_main_thread());
Ryan Dahlb20c3432010-02-12 05:55:081113
Michaël Zasso2fd248f2018-04-12 09:54:191114 CHECK_EQ(args.Length(), 1);
1115 CHECK(args[0]->IsString());
Trevor Norriscbf76c12015-01-07 22:13:351116 node::Utf8Value path(args.GetIsolate(), args[0]);
Ben Noordhuisca9eb712013-07-18 21:18:501117 int err = uv_chdir(*path);
1118 if (err) {
Sarat Addepallib32bcf72018-03-02 15:31:511119 return env->ThrowUVException(err, "chdir", nullptr, *path, nullptr);
Brandon Beacher47fcf782009-11-03 18:13:381120 }
Brandon Beacher47fcf782009-11-03 18:13:381121}
1122
Bert Beldercbcf4fe2011-11-24 01:19:541123
Ben Noordhuis110a9cd2013-07-03 02:23:441124static void Cwd(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551125 Environment* env = Environment::GetCurrent(args);
Bert Beldere84edd22011-12-01 23:24:441126#ifdef _WIN32
1127 /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261128 char buf[MAX_PATH * 4];
Bert Beldere84edd22011-12-01 23:24:441129#else
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261130 char buf[PATH_MAX];
Bert Beldere84edd22011-12-01 23:24:441131#endif
Michael Carter8ea6adc2009-09-01 09:39:301132
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261133 size_t cwd_len = sizeof(buf);
1134 int err = uv_cwd(buf, &cwd_len);
Ben Noordhuisca9eb712013-07-18 21:18:501135 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421136 return env->ThrowUVException(err, "uv_cwd");
Michael Carter8ea6adc2009-09-01 09:39:301137 }
Peter Griess4e3c5d82010-07-12 15:47:451138
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261139 Local<String> cwd = String::NewFromUtf8(env->isolate(),
1140 buf,
1141 String::kNormalString,
Saúl Ibarra Corretgée46cbaa2014-10-17 07:31:591142 cwd_len);
Ben Noordhuis110a9cd2013-07-03 02:23:441143 args.GetReturnValue().Set(cwd);
Michael Carter8ea6adc2009-09-01 09:39:301144}
1145
Bert Beldere84edd22011-12-01 23:24:441146
James M Snellcb3d0492018-05-23 22:04:231147void Umask(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis110a9cd2013-07-03 02:23:441148 uint32_t old;
isaacs5f2e9092011-01-25 18:40:121149
Michaël Zasso2fd248f2018-04-12 09:54:191150 CHECK_EQ(args.Length(), 1);
1151 CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
1152
1153 if (args[0]->IsUndefined()) {
Rasmus Andersson374300c2010-02-27 17:18:411154 old = umask(0);
Ben Noordhuis110a9cd2013-07-03 02:23:441155 umask(static_cast<mode_t>(old));
isaacs5f2e9092011-01-25 18:40:121156 } else {
Michaël Zasso2fd248f2018-04-12 09:54:191157 int oct = args[0].As<Uint32>()->Value();
isaacs5f2e9092011-01-25 18:40:121158 old = umask(static_cast<mode_t>(oct));
Friedemann Altrock0433d822009-11-22 18:52:521159 }
isaacs5f2e9092011-01-25 18:40:121160
Ben Noordhuis110a9cd2013-07-03 02:23:441161 args.GetReturnValue().Set(old);
Friedemann Altrock0433d822009-11-22 18:52:521162}
1163
Michael Cartera3860762010-02-08 06:13:101164
Ed Schouten78dbcbe2017-10-30 10:58:131165#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ryan Dahlacc120a2011-08-09 20:53:561166
Ben Noordhuis3ece1302012-12-04 05:36:231167static const uid_t uid_not_found = static_cast<uid_t>(-1);
1168static const gid_t gid_not_found = static_cast<gid_t>(-1);
1169
1170
1171static uid_t uid_by_name(const char* name) {
1172 struct passwd pwd;
1173 struct passwd* pp;
1174 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231175
1176 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321177 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231178
Ben Noordhuis2d82cdf2014-10-22 01:29:321179 if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231180 return pp->pw_uid;
1181 }
1182
1183 return uid_not_found;
1184}
1185
1186
1187static char* name_by_uid(uid_t uid) {
1188 struct passwd pwd;
1189 struct passwd* pp;
1190 char buf[8192];
1191 int rc;
1192
1193 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321194 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231195
Ben Noordhuis2d82cdf2014-10-22 01:29:321196 if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1197 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231198 return strdup(pp->pw_name);
1199 }
1200
1201 if (rc == 0) {
1202 errno = ENOENT;
1203 }
1204
Ben Noordhuis2d82cdf2014-10-22 01:29:321205 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231206}
1207
1208
1209static gid_t gid_by_name(const char* name) {
1210 struct group pwd;
1211 struct group* pp;
1212 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231213
1214 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321215 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231216
Ben Noordhuis2d82cdf2014-10-22 01:29:321217 if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231218 return pp->gr_gid;
1219 }
1220
1221 return gid_not_found;
1222}
1223
1224
1225#if 0 // For future use.
1226static const char* name_by_gid(gid_t gid) {
1227 struct group pwd;
1228 struct group* pp;
1229 char buf[8192];
1230 int rc;
1231
1232 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321233 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231234
Ben Noordhuis2d82cdf2014-10-22 01:29:321235 if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1236 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231237 return strdup(pp->gr_name);
1238 }
1239
1240 if (rc == 0) {
1241 errno = ENOENT;
1242 }
1243
Ben Noordhuis2d82cdf2014-10-22 01:29:321244 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231245}
1246#endif
1247
1248
Michaël Zasso4abc8962015-07-18 09:34:161249static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:231250 if (value->IsUint32()) {
1251 return static_cast<uid_t>(value->Uint32Value());
1252 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141253 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:231254 return uid_by_name(*name);
1255 }
1256}
1257
1258
Michaël Zasso4abc8962015-07-18 09:34:161259static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:231260 if (value->IsUint32()) {
1261 return static_cast<gid_t>(value->Uint32Value());
1262 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141263 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:231264 return gid_by_name(*name);
1265 }
1266}
1267
Ben Noordhuis110a9cd2013-07-03 02:23:441268static void GetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:081269 // uid_t is an uint32_t on all supported platforms.
1270 args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
Michael Cartera3860762010-02-08 06:13:101271}
1272
Ryan Dahlacc120a2011-08-09 20:53:561273
Ben Noordhuis110a9cd2013-07-03 02:23:441274static void GetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:081275 // gid_t is an uint32_t on all supported platforms.
1276 args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
James Duncandf1c1e52010-02-23 22:45:021277}
1278
1279
Evan Lucas3c92ca22015-04-27 16:24:191280static void GetEUid(const FunctionCallbackInfo<Value>& args) {
1281 // uid_t is an uint32_t on all supported platforms.
1282 args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
1283}
1284
1285
1286static void GetEGid(const FunctionCallbackInfo<Value>& args) {
1287 // gid_t is an uint32_t on all supported platforms.
1288 args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
1289}
1290
1291
James M Snellcb3d0492018-05-23 22:04:231292void SetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551293 Environment* env = Environment::GetCurrent(args);
Anna Henningsen0df031a2017-09-01 15:03:411294 CHECK(env->is_main_thread());
Ryan Dahl39943402010-03-15 19:49:401295
Michaël Zasso2fd248f2018-04-12 09:54:191296 CHECK_EQ(args.Length(), 1);
1297 CHECK(args[0]->IsUint32() || args[0]->IsString());
James Duncandf1c1e52010-02-23 22:45:021298
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141299 gid_t gid = gid_by_name(env->isolate(), args[0]);
Blake Mizerany8c853402010-06-30 06:12:461300
Ben Noordhuis3ece1302012-12-04 05:36:231301 if (gid == gid_not_found) {
Michaël Zasso2fd248f2018-04-12 09:54:191302 // Tells JS to throw ERR_INVALID_CREDENTIAL
1303 args.GetReturnValue().Set(1);
1304 } else if (setgid(gid)) {
1305 env->ThrowErrnoException(errno, "setgid");
1306 } else {
1307 args.GetReturnValue().Set(0);
James Duncandf1c1e52010-02-23 22:45:021308 }
James Duncandf1c1e52010-02-23 22:45:021309}
Michael Cartera3860762010-02-08 06:13:101310
Ryan Dahlacc120a2011-08-09 20:53:561311
James M Snellcb3d0492018-05-23 22:04:231312void SetEGid(const FunctionCallbackInfo<Value>& args) {
Evan Lucas3c92ca22015-04-27 16:24:191313 Environment* env = Environment::GetCurrent(args);
Anna Henningsen0df031a2017-09-01 15:03:411314 CHECK(env->is_main_thread());
Evan Lucas3c92ca22015-04-27 16:24:191315
Michaël Zasso2fd248f2018-04-12 09:54:191316 CHECK_EQ(args.Length(), 1);
1317 CHECK(args[0]->IsUint32() || args[0]->IsString());
Evan Lucas3c92ca22015-04-27 16:24:191318
1319 gid_t gid = gid_by_name(env->isolate(), args[0]);
1320
1321 if (gid == gid_not_found) {
Michaël Zasso2fd248f2018-04-12 09:54:191322 // Tells JS to throw ERR_INVALID_CREDENTIAL
1323 args.GetReturnValue().Set(1);
1324 } else if (setegid(gid)) {
1325 env->ThrowErrnoException(errno, "setegid");
1326 } else {
1327 args.GetReturnValue().Set(0);
Evan Lucas3c92ca22015-04-27 16:24:191328 }
1329}
1330
1331
James M Snellcb3d0492018-05-23 22:04:231332void SetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551333 Environment* env = Environment::GetCurrent(args);
Anna Henningsen0df031a2017-09-01 15:03:411334 CHECK(env->is_main_thread());
Michael Cartera3860762010-02-08 06:13:101335
Michaël Zasso2fd248f2018-04-12 09:54:191336 CHECK_EQ(args.Length(), 1);
1337 CHECK(args[0]->IsUint32() || args[0]->IsString());
Michael Cartera3860762010-02-08 06:13:101338
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141339 uid_t uid = uid_by_name(env->isolate(), args[0]);
Peter Griess2420f072010-05-19 00:40:441340
Ben Noordhuis3ece1302012-12-04 05:36:231341 if (uid == uid_not_found) {
Michaël Zasso2fd248f2018-04-12 09:54:191342 // Tells JS to throw ERR_INVALID_CREDENTIAL
1343 args.GetReturnValue().Set(1);
1344 } else if (setuid(uid)) {
1345 env->ThrowErrnoException(errno, "setuid");
1346 } else {
1347 args.GetReturnValue().Set(0);
Michael Cartera3860762010-02-08 06:13:101348 }
Michael Cartera3860762010-02-08 06:13:101349}
1350
Ryan Dahlacc120a2011-08-09 20:53:561351
James M Snellcb3d0492018-05-23 22:04:231352void SetEUid(const FunctionCallbackInfo<Value>& args) {
Evan Lucas3c92ca22015-04-27 16:24:191353 Environment* env = Environment::GetCurrent(args);
Anna Henningsen0df031a2017-09-01 15:03:411354 CHECK(env->is_main_thread());
Evan Lucas3c92ca22015-04-27 16:24:191355
Michaël Zasso2fd248f2018-04-12 09:54:191356 CHECK_EQ(args.Length(), 1);
1357 CHECK(args[0]->IsUint32() || args[0]->IsString());
Evan Lucas3c92ca22015-04-27 16:24:191358
1359 uid_t uid = uid_by_name(env->isolate(), args[0]);
1360
1361 if (uid == uid_not_found) {
Michaël Zasso2fd248f2018-04-12 09:54:191362 // Tells JS to throw ERR_INVALID_CREDENTIAL
1363 args.GetReturnValue().Set(1);
1364 } else if (seteuid(uid)) {
1365 env->ThrowErrnoException(errno, "seteuid");
1366 } else {
1367 args.GetReturnValue().Set(0);
Evan Lucas3c92ca22015-04-27 16:24:191368 }
1369}
1370
1371
Ben Noordhuis110a9cd2013-07-03 02:23:441372static void GetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551373 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231374
Ben Noordhuis2d82cdf2014-10-22 01:29:321375 int ngroups = getgroups(0, nullptr);
Ben Noordhuis3ece1302012-12-04 05:36:231376
1377 if (ngroups == -1) {
Fedor Indutny75adde02014-02-21 13:02:421378 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231379 }
1380
1381 gid_t* groups = new gid_t[ngroups];
1382
1383 ngroups = getgroups(ngroups, groups);
1384
1385 if (ngroups == -1) {
1386 delete[] groups;
Fedor Indutny75adde02014-02-21 13:02:421387 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231388 }
1389
Fedor Indutnyce04c722014-03-13 16:38:141390 Local<Array> groups_list = Array::New(env->isolate(), ngroups);
Ben Noordhuis3ece1302012-12-04 05:36:231391 bool seen_egid = false;
1392 gid_t egid = getegid();
1393
1394 for (int i = 0; i < ngroups; i++) {
Fedor Indutnyce04c722014-03-13 16:38:141395 groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
Fedor Indutny2bc30f22013-10-16 16:57:261396 if (groups[i] == egid)
1397 seen_egid = true;
Ben Noordhuis3ece1302012-12-04 05:36:231398 }
1399
1400 delete[] groups;
1401
1402 if (seen_egid == false) {
Fedor Indutnyce04c722014-03-13 16:38:141403 groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
Ben Noordhuis3ece1302012-12-04 05:36:231404 }
1405
Ben Noordhuis110a9cd2013-07-03 02:23:441406 args.GetReturnValue().Set(groups_list);
Ben Noordhuis3ece1302012-12-04 05:36:231407}
1408
1409
James M Snellcb3d0492018-05-23 22:04:231410void SetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551411 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231412
Michaël Zasso2fd248f2018-04-12 09:54:191413 CHECK_EQ(args.Length(), 1);
1414 CHECK(args[0]->IsArray());
Ben Noordhuis3ece1302012-12-04 05:36:231415
1416 Local<Array> groups_list = args[0].As<Array>();
1417 size_t size = groups_list->Length();
1418 gid_t* groups = new gid_t[size];
1419
1420 for (size_t i = 0; i < size; i++) {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141421 gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
Ben Noordhuis3ece1302012-12-04 05:36:231422
1423 if (gid == gid_not_found) {
1424 delete[] groups;
Michaël Zasso2fd248f2018-04-12 09:54:191425 // Tells JS to throw ERR_INVALID_CREDENTIAL
1426 args.GetReturnValue().Set(static_cast<uint32_t>(i + 1));
1427 return;
Ben Noordhuis3ece1302012-12-04 05:36:231428 }
1429
1430 groups[i] = gid;
1431 }
1432
1433 int rc = setgroups(size, groups);
1434 delete[] groups;
1435
1436 if (rc == -1) {
Fedor Indutny75adde02014-02-21 13:02:421437 return env->ThrowErrnoException(errno, "setgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231438 }
Michaël Zasso2fd248f2018-04-12 09:54:191439
1440 args.GetReturnValue().Set(0);
Ben Noordhuis3ece1302012-12-04 05:36:231441}
1442
1443
James M Snellcb3d0492018-05-23 22:04:231444void InitGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551445 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231446
Michaël Zasso2fd248f2018-04-12 09:54:191447 CHECK_EQ(args.Length(), 2);
1448 CHECK(args[0]->IsUint32() || args[0]->IsString());
1449 CHECK(args[1]->IsUint32() || args[1]->IsString());
Ben Noordhuis3ece1302012-12-04 05:36:231450
Trevor Norriscbf76c12015-01-07 22:13:351451 node::Utf8Value arg0(env->isolate(), args[0]);
Ben Noordhuis3ece1302012-12-04 05:36:231452 gid_t extra_group;
1453 bool must_free;
1454 char* user;
1455
1456 if (args[0]->IsUint32()) {
1457 user = name_by_uid(args[0]->Uint32Value());
1458 must_free = true;
1459 } else {
1460 user = *arg0;
1461 must_free = false;
1462 }
1463
Ben Noordhuis2d82cdf2014-10-22 01:29:321464 if (user == nullptr) {
Michaël Zasso2fd248f2018-04-12 09:54:191465 // Tells JS to throw ERR_INVALID_CREDENTIAL
1466 return args.GetReturnValue().Set(1);
Ben Noordhuis3ece1302012-12-04 05:36:231467 }
1468
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141469 extra_group = gid_by_name(env->isolate(), args[1]);
Ben Noordhuis3ece1302012-12-04 05:36:231470
1471 if (extra_group == gid_not_found) {
Fedor Indutny2bc30f22013-10-16 16:57:261472 if (must_free)
1473 free(user);
Michaël Zasso2fd248f2018-04-12 09:54:191474 // Tells JS to throw ERR_INVALID_CREDENTIAL
1475 return args.GetReturnValue().Set(2);
Ben Noordhuis3ece1302012-12-04 05:36:231476 }
1477
1478 int rc = initgroups(user, extra_group);
1479
1480 if (must_free) {
1481 free(user);
1482 }
1483
1484 if (rc) {
Fedor Indutny75adde02014-02-21 13:02:421485 return env->ThrowErrnoException(errno, "initgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231486 }
Michaël Zasso2fd248f2018-04-12 09:54:191487
1488 args.GetReturnValue().Set(0);
Ben Noordhuis3ece1302012-12-04 05:36:231489}
1490
Ed Schouten78dbcbe2017-10-30 10:58:131491#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
Bert Belder30bab522010-11-25 00:09:061492
Michael Cartera3860762010-02-08 06:13:101493
Eugene Ostroukhov66269192016-06-08 21:09:281494static void WaitForInspectorDisconnect(Environment* env) {
1495#if HAVE_INSPECTOR
Eugene Ostroukhov13001032018-04-24 18:16:551496 if (env->inspector_agent()->HasConnectedSessions()) {
Eugene Ostroukhov66269192016-06-08 21:09:281497 // Restore signal dispositions, the app is done and is no longer
1498 // capable of handling signals.
Stewart X Addison0f0f3d32016-12-30 12:44:461499#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
Eugene Ostroukhov66269192016-06-08 21:09:281500 struct sigaction act;
1501 memset(&act, 0, sizeof(act));
1502 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
1503 if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
1504 continue;
1505 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
1506 CHECK_EQ(0, sigaction(nr, &act, nullptr));
1507 }
1508#endif
1509 env->inspector_agent()->WaitForDisconnect();
1510 }
1511#endif
1512}
1513
1514
Anna Henningsen9d522222017-04-12 17:17:241515static void Exit(const FunctionCallbackInfo<Value>& args) {
Anna Henningsen0df031a2017-09-01 15:03:411516 Environment* env = Environment::GetCurrent(args);
1517 WaitForInspectorDisconnect(env);
James M Snell5c27e442018-04-04 01:05:331518 v8_platform.StopTracingAgent();
Anna Henningsen0df031a2017-09-01 15:03:411519 env->Exit(args[0]->Int32Value());
Ryan0f517032009-04-29 09:09:321520}
1521
Ryan Dahl3ac6dee2010-05-08 02:05:591522
Ben Noordhuis110a9cd2013-07-03 02:23:441523static void Uptime(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551524 Environment* env = Environment::GetCurrent(args);
Igor Zinkovsky500c8f42011-12-15 20:36:051525 double uptime;
Tom Hughescf78ce52011-03-04 23:57:541526
Fedor Indutny6a610a02014-10-04 14:44:391527 uv_update_time(env->event_loop());
1528 uptime = uv_now(env->event_loop()) - prog_start_time;
Tom Hughescf78ce52011-03-04 23:57:541529
Timothy J Fontaineb19b60a2014-05-01 20:54:231530 args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
Tom Hughescf78ce52011-03-04 23:57:541531}
Ryan Dahl3ac6dee2010-05-08 02:05:591532
Ryan Dahlc344fbc2011-10-06 21:59:381533
James M Snellcb3d0492018-05-23 22:04:231534void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551535 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb3b3cfe2009-11-03 12:00:421536
Ryan Dahl5783a522011-10-18 21:30:311537 size_t rss;
Ben Noordhuisca9eb712013-07-18 21:18:501538 int err = uv_resident_set_memory(&rss);
1539 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421540 return env->ThrowUVException(err, "uv_resident_set_memory");
Ryan Dahl3a701292009-11-03 00:30:011541 }
1542
Brian Whitef385f772017-02-22 07:03:491543 Isolate* isolate = env->isolate();
Ryan Dahl38e425d2009-11-28 15:31:291544 // V8 memory usage
1545 HeapStatistics v8_heap_stats;
Brian Whitef385f772017-02-22 07:03:491546 isolate->GetHeapStatistics(&v8_heap_stats);
Ben Noordhuis756b6222013-08-10 22:26:111547
Brian Whitef385f772017-02-22 07:03:491548 // Get the double array pointer from the Float64Array argument.
1549 CHECK(args[0]->IsFloat64Array());
1550 Local<Float64Array> array = args[0].As<Float64Array>();
1551 CHECK_EQ(array->Length(), 4);
1552 Local<ArrayBuffer> ab = array->Buffer();
1553 double* fields = static_cast<double*>(ab->GetContents().Data());
Ben Noordhuis756b6222013-08-10 22:26:111554
Brian Whitef385f772017-02-22 07:03:491555 fields[0] = rss;
1556 fields[1] = v8_heap_stats.total_heap_size();
1557 fields[2] = v8_heap_stats.used_heap_size();
1558 fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
Ryan Dahl3a701292009-11-03 00:30:011559}
Ryan Dahlb3b3cfe2009-11-03 12:00:421560
Bert Belder4a2cb072010-11-29 17:40:141561
Anna Henningsen9d522222017-04-12 17:17:241562static void Kill(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551563 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb20c3432010-02-12 05:55:081564
Ryan Dahl4227e9d2010-12-21 23:40:101565 if (args.Length() != 2) {
Fedor Indutny75adde02014-02-21 13:02:421566 return env->ThrowError("Bad argument.");
Brandon Beacher334d56d2009-10-14 21:56:121567 }
Ryan Dahlb20c3432010-02-12 05:55:081568
Rasmus Christian Pedersen734fb492014-09-18 12:10:531569 int pid = args[0]->Int32Value();
Ryan Dahl6eca9482010-09-17 06:13:031570 int sig = args[1]->Int32Value();
Ben Noordhuisca9eb712013-07-18 21:18:501571 int err = uv_kill(pid, sig);
1572 args.GetReturnValue().Set(err);
Brandon Beacher334d56d2009-10-14 21:56:121573}
1574
Nathan Rajlich07c886f2012-03-05 16:51:581575// used in Hrtime() below
1576#define NANOS_PER_SEC 1000000000
1577
1578// Hrtime exposes libuv's uv_hrtime() high-resolution timer.
1579// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
Joyee Cheunga647d822017-01-12 12:03:291580// so this function instead fills in an Uint32Array with 3 entries,
1581// to avoid any integer overflow possibility.
1582// The first two entries contain the second part of the value
1583// broken into the upper/lower 32 bits to be converted back in JS,
1584// because there is no Uint64Array in JS.
1585// The third entry contains the remaining nanosecond part of the value.
James M Snellcb3d0492018-05-23 22:04:231586void Hrtime(const FunctionCallbackInfo<Value>& args) {
Nathan Rajlich07c886f2012-03-05 16:51:581587 uint64_t t = uv_hrtime();
1588
Trevor Norris36e8a2c2015-11-11 07:15:151589 Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
1590 uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
1591
Trevor Norris36e8a2c2015-11-11 07:15:151592 fields[0] = (t / NANOS_PER_SEC) >> 32;
1593 fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
1594 fields[2] = t % NANOS_PER_SEC;
Nathan Rajlich07c886f2012-03-05 16:51:581595}
1596
Patrick Mueller52cb4102016-04-05 13:17:481597// Microseconds in a second, as a float, used in CPUUsage() below
1598#define MICROS_PER_SEC 1e6
1599
1600// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
1601// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
1602// which are uv_timeval_t structs (long tv_sec, long tv_usec).
1603// Returns those values as Float64 microseconds in the elements of the array
1604// passed to the function.
James M Snellcb3d0492018-05-23 22:04:231605void CPUUsage(const FunctionCallbackInfo<Value>& args) {
Patrick Mueller52cb4102016-04-05 13:17:481606 uv_rusage_t rusage;
1607
1608 // Call libuv to get the values we'll return.
1609 int err = uv_getrusage(&rusage);
1610 if (err) {
1611 // On error, return the strerror version of the error code.
1612 Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
1613 args.GetReturnValue().Set(errmsg);
1614 return;
1615 }
1616
1617 // Get the double array pointer from the Float64Array argument.
1618 CHECK(args[0]->IsFloat64Array());
1619 Local<Float64Array> array = args[0].As<Float64Array>();
1620 CHECK_EQ(array->Length(), 2);
1621 Local<ArrayBuffer> ab = array->Buffer();
1622 double* fields = static_cast<double*>(ab->GetContents().Data());
1623
1624 // Set the Float64Array elements to be user / system values in microseconds.
1625 fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
1626 fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
1627}
1628
Keith M Wesolowski76b98462013-12-17 00:00:441629extern "C" void node_module_register(void* m) {
1630 struct node_module* mp = reinterpret_cast<struct node_module*>(m);
1631
1632 if (mp->nm_flags & NM_F_BUILTIN) {
1633 mp->nm_link = modlist_builtin;
1634 modlist_builtin = mp;
Bradley Fariasa36aa042017-10-03 15:07:481635 } else if (mp->nm_flags & NM_F_INTERNAL) {
1636 mp->nm_link = modlist_internal;
1637 modlist_internal = mp;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:221638 } else if (!node_is_initialized) {
1639 // "Linked" modules are included as part of the node project.
1640 // Like builtins they are registered *before* node::Init runs.
1641 mp->nm_flags = NM_F_LINKED;
1642 mp->nm_link = modlist_linked;
1643 modlist_linked = mp;
Keith M Wesolowski76b98462013-12-17 00:00:441644 } else {
Keith M Wesolowski76b98462013-12-17 00:00:441645 modpending = mp;
1646 }
1647}
1648
Bradley Fariasa36aa042017-10-03 15:07:481649inline struct node_module* FindModule(struct node_module* list,
1650 const char* name,
1651 int flag) {
Keith M Wesolowski76b98462013-12-17 00:00:441652 struct node_module* mp;
1653
Bradley Fariasa36aa042017-10-03 15:07:481654 for (mp = list; mp != nullptr; mp = mp->nm_link) {
Keith M Wesolowski76b98462013-12-17 00:00:441655 if (strcmp(mp->nm_modname, name) == 0)
1656 break;
1657 }
1658
Bradley Fariasa36aa042017-10-03 15:07:481659 CHECK(mp == nullptr || (mp->nm_flags & flag) != 0);
1660 return mp;
Keith M Wesolowski76b98462013-12-17 00:00:441661}
Bert Belderdd93c532011-10-28 10:05:091662
Bradley Fariasa36aa042017-10-03 15:07:481663node_module* get_builtin_module(const char* name) {
1664 return FindModule(modlist_builtin, name, NM_F_BUILTIN);
1665}
1666node_module* get_internal_module(const char* name) {
1667 return FindModule(modlist_internal, name, NM_F_INTERNAL);
1668}
1669node_module* get_linked_module(const char* name) {
1670 return FindModule(modlist_linked, name, NM_F_LINKED);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:221671}
1672
James M Snellc68e6e12018-05-16 20:21:001673class DLib {
1674 public:
Ezequiel Garcia5f223752017-04-29 20:06:221675#ifdef __POSIX__
1676 static const int kDefaultFlags = RTLD_LAZY;
Ben Noordhuis66315222018-02-22 12:35:261677#else
Ezequiel Garcia5f223752017-04-29 20:06:221678 static const int kDefaultFlags = 0;
Ben Noordhuis66315222018-02-22 12:35:261679#endif
1680
1681 inline DLib(const char* filename, int flags)
1682 : filename_(filename), flags_(flags), handle_(nullptr) {}
1683
1684 inline bool Open();
1685 inline void Close();
Ben Noordhuis3828fc62018-02-22 12:35:261686 inline void* GetSymbolAddress(const char* name);
Ben Noordhuis66315222018-02-22 12:35:261687
1688 const std::string filename_;
1689 const int flags_;
1690 std::string errmsg_;
1691 void* handle_;
1692#ifndef __POSIX__
Ezequiel Garcia5f223752017-04-29 20:06:221693 uv_lib_t lib_;
Ben Noordhuis66315222018-02-22 12:35:261694#endif
James M Snellc68e6e12018-05-16 20:21:001695 private:
Ben Noordhuis66315222018-02-22 12:35:261696 DISALLOW_COPY_AND_ASSIGN(DLib);
Ezequiel Garcia5f223752017-04-29 20:06:221697};
1698
Ben Noordhuis66315222018-02-22 12:35:261699
1700#ifdef __POSIX__
1701bool DLib::Open() {
1702 handle_ = dlopen(filename_.c_str(), flags_);
1703 if (handle_ != nullptr)
1704 return true;
1705 errmsg_ = dlerror();
1706 return false;
1707}
1708
1709void DLib::Close() {
1710 if (handle_ == nullptr) return;
1711 dlclose(handle_);
1712 handle_ = nullptr;
1713}
Ben Noordhuis3828fc62018-02-22 12:35:261714
1715void* DLib::GetSymbolAddress(const char* name) {
1716 return dlsym(handle_, name);
1717}
Ben Noordhuis66315222018-02-22 12:35:261718#else // !__POSIX__
1719bool DLib::Open() {
1720 int ret = uv_dlopen(filename_.c_str(), &lib_);
1721 if (ret == 0) {
1722 handle_ = static_cast<void*>(lib_.handle);
1723 return true;
1724 }
1725 errmsg_ = uv_dlerror(&lib_);
1726 uv_dlclose(&lib_);
1727 return false;
1728}
1729
1730void DLib::Close() {
1731 if (handle_ == nullptr) return;
1732 uv_dlclose(&lib_);
1733 handle_ = nullptr;
1734}
Ben Noordhuis3828fc62018-02-22 12:35:261735
1736void* DLib::GetSymbolAddress(const char* name) {
1737 void* address;
1738 if (0 == uv_dlsym(&lib_, name, &address)) return address;
1739 return nullptr;
1740}
Ben Noordhuis66315222018-02-22 12:35:261741#endif // !__POSIX__
1742
Ben Noordhuis3828fc62018-02-22 12:35:261743using InitializerCallback = void (*)(Local<Object> exports,
1744 Local<Value> module,
1745 Local<Context> context);
1746
1747inline InitializerCallback GetInitializerCallback(DLib* dlib) {
1748 const char* name = "node_register_module_v" STRINGIFY(NODE_MODULE_VERSION);
1749 return reinterpret_cast<InitializerCallback>(dlib->GetSymbolAddress(name));
1750}
1751
Gabriel Schulhof0f8caf22018-04-21 02:57:331752inline napi_addon_register_func GetNapiInitializerCallback(DLib* dlib) {
1753 const char* name =
1754 STRINGIFY(NAPI_MODULE_INITIALIZER_BASE) STRINGIFY(NAPI_MODULE_VERSION);
1755 return
1756 reinterpret_cast<napi_addon_register_func>(dlib->GetSymbolAddress(name));
1757}
1758
Ezequiel Garcia5f223752017-04-29 20:06:221759// DLOpen is process.dlopen(module, filename, flags).
isaacs15508582013-01-24 23:40:581760// Used to load 'module.node' dynamically shared objects.
Ben Noordhuis756b6222013-08-10 22:26:111761//
1762// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
1763// when two contexts try to load the same shared object. Maybe have a shadow
1764// cache that's a plain C list or hash table that's shared across contexts?
Anna Henningsen9d522222017-04-12 17:17:241765static void DLOpen(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551766 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis66315222018-02-22 12:35:261767 auto context = env->context();
Ryan2b6d7242009-06-20 13:07:101768
Tobias Nießen39f20962018-05-20 15:44:061769 CHECK_NULL(modpending);
Ben Noordhuisa60056d2014-12-11 14:29:521770
Ezequiel Garcia5f223752017-04-29 20:06:221771 if (args.Length() < 2) {
1772 env->ThrowError("process.dlopen needs at least 2 arguments.");
Keith M Wesolowski76b98462013-12-17 00:00:441773 return;
Bert Belderdd93c532011-10-28 10:05:091774 }
Ryana97dce72009-08-31 09:14:341775
Ezequiel Garcia5f223752017-04-29 20:06:221776 int32_t flags = DLib::kDefaultFlags;
Ben Noordhuis66315222018-02-22 12:35:261777 if (args.Length() > 2 && !args[2]->Int32Value(context).To(&flags)) {
Ezequiel Garcia5f223752017-04-29 20:06:221778 return env->ThrowTypeError("flag argument must be an integer.");
1779 }
1780
Ben Noordhuis66315222018-02-22 12:35:261781 Local<Object> module;
1782 Local<Object> exports;
1783 Local<Value> exports_v;
1784 if (!args[0]->ToObject(context).ToLocal(&module) ||
1785 !module->Get(context, env->exports_string()).ToLocal(&exports_v) ||
1786 !exports_v->ToObject(context).ToLocal(&exports)) {
1787 return; // Exception pending.
1788 }
1789
Trevor Norriscbf76c12015-01-07 22:13:351790 node::Utf8Value filename(env->isolate(), args[1]); // Cast
Ben Noordhuis66315222018-02-22 12:35:261791 DLib dlib(*filename, flags);
Ezequiel Garcia5f223752017-04-29 20:06:221792 bool is_opened = dlib.Open();
isaacs15508582013-01-24 23:40:581793
Ben Noordhuisa60056d2014-12-11 14:29:521794 // Objects containing v14 or later modules will have registered themselves
1795 // on the pending list. Activate all of them now. At present, only one
1796 // module per object is supported.
1797 node_module* const mp = modpending;
1798 modpending = nullptr;
Ryan2b6d7242009-06-20 13:07:101799
Ezequiel Garcia5f223752017-04-29 20:06:221800 if (!is_opened) {
1801 Local<String> errmsg = OneByteString(env->isolate(), dlib.errmsg_.c_str());
1802 dlib.Close();
Ben Noordhuis039fac62012-05-17 05:13:291803#ifdef _WIN32
1804 // Windows needs to add the filename into the error message
Leko19221d12017-11-27 07:16:321805 errmsg = String::Concat(errmsg,
Ben Noordhuis66315222018-02-22 12:35:261806 args[1]->ToString(context).ToLocalChecked());
Fedor Indutny8e29ce92013-07-31 18:07:291807#endif // _WIN32
Fedor Indutny75adde02014-02-21 13:02:421808 env->isolate()->ThrowException(Exception::Error(errmsg));
Ben Noordhuis110a9cd2013-07-03 02:23:441809 return;
Ryan2b6d7242009-06-20 13:07:101810 }
1811
Ben Noordhuis2d82cdf2014-10-22 01:29:321812 if (mp == nullptr) {
Ben Noordhuis3828fc62018-02-22 12:35:261813 if (auto callback = GetInitializerCallback(&dlib)) {
1814 callback(exports, module, context);
Gabriel Schulhof0f8caf22018-04-21 02:57:331815 } else if (auto napi_callback = GetNapiInitializerCallback(&dlib)) {
1816 napi_module_register_by_symbol(exports, module, context, napi_callback);
Ben Noordhuis3828fc62018-02-22 12:35:261817 } else {
1818 dlib.Close();
1819 env->ThrowError("Module did not self-register.");
1820 }
Keith M Wesolowski76b98462013-12-17 00:00:441821 return;
Paul Querna367b87d2010-07-13 08:33:511822 }
Ben Noordhuis3828fc62018-02-22 12:35:261823
Michael Dawsoncd7d7b12018-03-09 17:07:371824 // -1 is used for N-API modules
1825 if ((mp->nm_version != -1) && (mp->nm_version != NODE_MODULE_VERSION)) {
Gabriel Schulhofc1078c42018-04-21 02:27:431826 // Even if the module did self-register, it may have done so with the wrong
1827 // version. We must only give up after having checked to see if it has an
1828 // appropriate initializer callback.
1829 if (auto callback = GetInitializerCallback(&dlib)) {
1830 callback(exports, module, context);
1831 return;
1832 }
Gabriel Schulhofa8c0a432017-08-18 10:30:051833 char errmsg[1024];
1834 snprintf(errmsg,
1835 sizeof(errmsg),
1836 "The module '%s'"
1837 "\nwas compiled against a different Node.js version using"
1838 "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
1839 "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
1840 "re-installing\nthe module (for instance, using `npm rebuild` "
1841 "or `npm install`).",
1842 *filename, mp->nm_version, NODE_MODULE_VERSION);
Fedor Indutnya6d674d2015-09-10 11:01:201843
1844 // NOTE: `mp` is allocated inside of the shared library's memory, calling
Ezequiel Garcia5f223752017-04-29 20:06:221845 // `dlclose` will deallocate it
1846 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:421847 env->ThrowError(errmsg);
Keith M Wesolowski76b98462013-12-17 00:00:441848 return;
1849 }
1850 if (mp->nm_flags & NM_F_BUILTIN) {
Ezequiel Garcia5f223752017-04-29 20:06:221851 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:421852 env->ThrowError("Built-in module self-registered.");
Keith M Wesolowski76b98462013-12-17 00:00:441853 return;
Ryan2b6d7242009-06-20 13:07:101854 }
Ryan2b6d7242009-06-20 13:07:101855
Ezequiel Garcia5f223752017-04-29 20:06:221856 mp->nm_dso_handle = dlib.handle_;
Keith M Wesolowski76b98462013-12-17 00:00:441857 mp->nm_link = modlist_addon;
1858 modlist_addon = mp;
1859
Ben Noordhuis2d82cdf2014-10-22 01:29:321860 if (mp->nm_context_register_func != nullptr) {
Ben Noordhuis66315222018-02-22 12:35:261861 mp->nm_context_register_func(exports, module, context, mp->nm_priv);
Ben Noordhuis2d82cdf2014-10-22 01:29:321862 } else if (mp->nm_register_func != nullptr) {
Keith M Wesolowski76b98462013-12-17 00:00:441863 mp->nm_register_func(exports, module, mp->nm_priv);
Ben Noordhuis756b6222013-08-10 22:26:111864 } else {
Ezequiel Garcia5f223752017-04-29 20:06:221865 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:421866 env->ThrowError("Module has no declared entry point.");
Keith M Wesolowski76b98462013-12-17 00:00:441867 return;
Ben Noordhuis756b6222013-08-10 22:26:111868 }
Ryan2b6d7242009-06-20 13:07:101869
Peter Griess4e3c5d82010-07-12 15:47:451870 // Tell coverity that 'handle' should not be freed when we return.
1871 // coverity[leaked_storage]
Ryan2b6d7242009-06-20 13:07:101872}
1873
Tim-Smartae10a482010-03-12 08:36:001874
Ryand6c9d312009-09-11 14:02:291875static void OnFatalError(const char* location, const char* message) {
Ryan Dahl53a841d2009-12-29 19:20:511876 if (location) {
Brian White2d356072015-10-13 21:18:151877 PrintErrorString("FATAL ERROR: %s %s\n", location, message);
Ryan Dahl53a841d2009-12-29 19:20:511878 } else {
Brian White2d356072015-10-13 21:18:151879 PrintErrorString("FATAL ERROR: %s\n", message);
Ryan Dahl53a841d2009-12-29 19:20:511880 }
Ben Noordhuisc56a96c2013-06-29 05:30:111881 fflush(stderr);
Evan Lucas870229e2015-09-16 15:12:411882 ABORT();
Ryan63a9cd32009-04-15 08:08:281883}
1884
Miroslav Bajtosc16963b2013-06-17 19:19:591885
Trevor Norrisfa10b752013-06-20 23:44:021886NO_RETURN void FatalError(const char* location, const char* message) {
1887 OnFatalError(location, message);
James M Snell936c9ff2015-06-24 03:42:491888 // to suppress compiler warning
Evan Lucas870229e2015-09-16 15:12:411889 ABORT();
Trevor Norrisfa10b752013-06-20 23:44:021890}
1891
1892
Anna Henningsena0126722017-11-27 00:31:241893FatalTryCatch::~FatalTryCatch() {
1894 if (HasCaught()) {
1895 HandleScope scope(env_->isolate());
1896 ReportException(env_, *this);
1897 exit(7);
1898 }
1899}
1900
1901
Fedor Indutny75adde02014-02-21 13:02:421902void FatalException(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:161903 Local<Value> error,
1904 Local<Message> message) {
Fedor Indutny75adde02014-02-21 13:02:421905 HandleScope scope(isolate);
Felix Geisendörfer2b252ac2009-11-14 22:07:541906
Fedor Indutny75adde02014-02-21 13:02:421907 Environment* env = Environment::GetCurrent(isolate);
Ben Noordhuis756b6222013-08-10 22:26:111908 Local<Object> process_object = env->process_object();
1909 Local<String> fatal_exception_string = env->fatal_exception_string();
1910 Local<Function> fatal_exception_function =
1911 process_object->Get(fatal_exception_string).As<Function>();
Ryan Dahl45a806a2009-12-09 08:02:211912
Ben Noordhuis756b6222013-08-10 22:26:111913 if (!fatal_exception_function->IsFunction()) {
Ruben Bridgewaterb87ef182018-04-25 15:50:431914 // Failed before the process._fatalException function was added!
isaacs4401bb42012-12-26 20:28:331915 // this is probably pretty bad. Nothing to do but report and exit.
Fedor Indutnyf1de13b2014-02-05 16:38:331916 ReportException(env, error, message);
Ruben Bridgewaterb87ef182018-04-25 15:50:431917 exit(6);
1918 } else {
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471919 TryCatch fatal_try_catch(isolate);
isaacs07be9fc2012-05-09 22:12:131920
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471921 // Do not call FatalException when _fatalException handler throws
1922 fatal_try_catch.SetVerbose(false);
Miroslav Bajtosc16963b2013-06-17 19:19:591923
Ruben Bridgewaterb87ef182018-04-25 15:50:431924 // This will return true if the JS layer handled it, false otherwise
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471925 Local<Value> caught =
1926 fatal_exception_function->Call(process_object, 1, &error);
isaacs4401bb42012-12-26 20:28:331927
Anna Henningsen0df031a2017-09-01 15:03:411928 if (fatal_try_catch.HasTerminated())
1929 return;
1930
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471931 if (fatal_try_catch.HasCaught()) {
Ruben Bridgewaterb87ef182018-04-25 15:50:431932 // The fatal exception function threw, so we must exit
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471933 ReportException(env, fatal_try_catch);
Ruben Bridgewaterb87ef182018-04-25 15:50:431934 exit(7);
1935 } else if (caught->IsFalse()) {
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471936 ReportException(env, error, message);
Ruben Bridgewaterb87ef182018-04-25 15:50:431937 exit(1);
Aleksei Koziatinskii26cd48f2016-08-10 02:03:471938 }
isaacs4401bb42012-12-26 20:28:331939 }
Ryane78917b2009-03-09 13:08:311940}
1941
Ryan0e9e9272009-04-04 14:53:431942
Fedor Indutny75adde02014-02-21 13:02:421943void FatalException(Isolate* isolate, const TryCatch& try_catch) {
Anna Henningsen0df031a2017-09-01 15:03:411944 // If we try to print out a termination exception, we'd just get 'null',
1945 // so just crashing here with that information seems like a better idea,
1946 // and in particular it seems like we should handle terminations at the call
1947 // site for this function rather than by printing them out somewhere.
1948 CHECK(!try_catch.HasTerminated());
1949
Fedor Indutny75adde02014-02-21 13:02:421950 HandleScope scope(isolate);
Daniel Beveniusfefab902017-05-03 17:17:221951 if (!try_catch.IsVerbose()) {
1952 FatalException(isolate, try_catch.Exception(), try_catch.Message());
1953 }
Miroslav Bajtosc16963b2013-06-17 19:19:591954}
1955
1956
Anna Henningsen9d522222017-04-12 17:17:241957static void OnMessage(Local<Message> message, Local<Value> error) {
Miroslav Bajtosc16963b2013-06-17 19:19:591958 // The current version of V8 sends messages for errors only
1959 // (thus `error` is always set).
Fedor Indutny75adde02014-02-21 13:02:421960 FatalException(Isolate::GetCurrent(), error, message);
Miroslav Bajtosc16963b2013-06-17 19:19:591961}
1962
Anna Henningsenf3cd5372017-12-01 23:04:561963static Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
1964 const char* warning,
1965 const char* type = nullptr,
1966 const char* code = nullptr) {
1967 HandleScope handle_scope(env->isolate());
1968 Context::Scope context_scope(env->context());
1969
1970 Local<Object> process = env->process_object();
1971 Local<Value> emit_warning;
1972 if (!process->Get(env->context(),
1973 env->emit_warning_string()).ToLocal(&emit_warning)) {
1974 return Nothing<bool>();
1975 }
1976
1977 if (!emit_warning->IsFunction()) return Just(false);
1978
1979 int argc = 0;
1980 Local<Value> args[3]; // warning, type, code
1981
1982 // The caller has to be able to handle a failure anyway, so we might as well
1983 // do proper error checking for string creation.
1984 if (!String::NewFromUtf8(env->isolate(),
1985 warning,
1986 v8::NewStringType::kNormal).ToLocal(&args[argc++])) {
1987 return Nothing<bool>();
1988 }
1989 if (type != nullptr) {
1990 if (!String::NewFromOneByte(env->isolate(),
1991 reinterpret_cast<const uint8_t*>(type),
1992 v8::NewStringType::kNormal)
1993 .ToLocal(&args[argc++])) {
1994 return Nothing<bool>();
1995 }
1996 if (code != nullptr &&
1997 !String::NewFromOneByte(env->isolate(),
1998 reinterpret_cast<const uint8_t*>(code),
1999 v8::NewStringType::kNormal)
2000 .ToLocal(&args[argc++])) {
2001 return Nothing<bool>();
2002 }
2003 }
2004
2005 // MakeCallback() unneeded because emitWarning is internal code, it calls
2006 // process.emit('warning', ...), but does so on the nextTick.
2007 if (emit_warning.As<Function>()->Call(env->context(),
2008 process,
2009 argc,
2010 args).IsEmpty()) {
2011 return Nothing<bool>();
2012 }
2013 return Just(true);
2014}
2015
2016
Sam Roberts213134f2016-11-07 21:18:232017// Call process.emitWarning(str), fmt is a snprintf() format string
Anna Henningsenf3cd5372017-12-01 23:04:562018Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
Sam Roberts213134f2016-11-07 21:18:232019 char warning[1024];
2020 va_list ap;
2021
2022 va_start(ap, fmt);
2023 vsnprintf(warning, sizeof(warning), fmt, ap);
2024 va_end(ap);
2025
Anna Henningsenf3cd5372017-12-01 23:04:562026 return ProcessEmitWarningGeneric(env, warning);
Sam Roberts213134f2016-11-07 21:18:232027}
2028
Anna Henningsenf3cd5372017-12-01 23:04:562029
2030Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
2031 const char* warning,
2032 const char* deprecation_code) {
2033 return ProcessEmitWarningGeneric(env,
2034 warning,
2035 "DeprecationWarning",
2036 deprecation_code);
2037}
2038
2039
Bradley Fariasa36aa042017-10-03 15:07:482040static Local<Object> InitModule(Environment* env,
2041 node_module* mod,
2042 Local<String> module) {
2043 Local<Object> exports = Object::New(env->isolate());
2044 // Internal bindings don't have a "module" object, only exports.
Tobias Nießen39f20962018-05-20 15:44:062045 CHECK_NULL(mod->nm_register_func);
2046 CHECK_NOT_NULL(mod->nm_context_register_func);
Bradley Fariasa36aa042017-10-03 15:07:482047 Local<Value> unused = Undefined(env->isolate());
2048 mod->nm_context_register_func(exports,
2049 unused,
2050 env->context(),
2051 mod->nm_priv);
2052 return exports;
2053}
2054
2055static void ThrowIfNoSuchModule(Environment* env, const char* module_v) {
2056 char errmsg[1024];
2057 snprintf(errmsg,
2058 sizeof(errmsg),
2059 "No such module: %s",
2060 module_v);
2061 env->ThrowError(errmsg);
2062}
Trevor Norrisa17200b2016-03-14 18:35:222063
Joyee Cheung2a9eb312018-03-03 20:55:452064static void GetBinding(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552065 Environment* env = Environment::GetCurrent(args);
Ryan Dahl627fb5a2010-03-15 20:48:032066
Anatoli Papirovskibb27bfe2018-01-25 04:25:202067 CHECK(args[0]->IsString());
Ryan Dahl627fb5a2010-03-15 20:48:032068
Anatoli Papirovskibb27bfe2018-01-25 04:25:202069 Local<String> module = args[0].As<String>();
Bradley Fariasa36aa042017-10-03 15:07:482070 node::Utf8Value module_v(env->isolate(), module);
Ryan Dahlea9ee1f2011-07-28 02:30:322071
Keith M Wesolowski76b98462013-12-17 00:00:442072 node_module* mod = get_builtin_module(*module_v);
Bradley Fariasa36aa042017-10-03 15:07:482073 Local<Object> exports;
Ben Noordhuis2d82cdf2014-10-22 01:29:322074 if (mod != nullptr) {
Bradley Fariasa36aa042017-10-03 15:07:482075 exports = InitModule(env, mod, module);
Ryan Dahl6eca9482010-09-17 06:13:032076 } else if (!strcmp(*module_v, "constants")) {
Fedor Indutnyce04c722014-03-13 16:38:142077 exports = Object::New(env->isolate());
Sakthipriyan Vairamani (thefourtheye)caf9ae72016-12-26 11:12:092078 CHECK(exports->SetPrototype(env->context(),
2079 Null(env->isolate())).FromJust());
James M Snelldcccbfd2016-05-02 17:27:122080 DefineConstants(env->isolate(), exports);
Ryan Dahlc90546f2010-03-15 21:22:502081 } else if (!strcmp(*module_v, "natives")) {
Fedor Indutnyce04c722014-03-13 16:38:142082 exports = Object::New(env->isolate());
Fedor Indutny75adde02014-02-21 13:02:422083 DefineJavaScript(env, exports);
Ryan Dahl627fb5a2010-03-15 20:48:032084 } else {
Bradley Fariasa36aa042017-10-03 15:07:482085 return ThrowIfNoSuchModule(env, *module_v);
Ryan Dahl627fb5a2010-03-15 20:48:032086 }
Bradley Fariasa36aa042017-10-03 15:07:482087
2088 args.GetReturnValue().Set(exports);
2089}
2090
Joyee Cheung2a9eb312018-03-03 20:55:452091static void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
Bradley Fariasa36aa042017-10-03 15:07:482092 Environment* env = Environment::GetCurrent(args);
2093
Anatoli Papirovskibb27bfe2018-01-25 04:25:202094 CHECK(args[0]->IsString());
Bradley Fariasa36aa042017-10-03 15:07:482095
Anatoli Papirovskibb27bfe2018-01-25 04:25:202096 Local<String> module = args[0].As<String>();
Bradley Fariasa36aa042017-10-03 15:07:482097 node::Utf8Value module_v(env->isolate(), module);
Bradley Fariasa36aa042017-10-03 15:07:482098
2099 node_module* mod = get_internal_module(*module_v);
2100 if (mod == nullptr) return ThrowIfNoSuchModule(env, *module_v);
2101 Local<Object> exports = InitModule(env, mod, module);
Ryan Dahl627fb5a2010-03-15 20:48:032102
Ben Noordhuis110a9cd2013-07-03 02:23:442103 args.GetReturnValue().Set(exports);
Ryan Dahl627fb5a2010-03-15 20:48:032104}
2105
Joyee Cheung2a9eb312018-03-03 20:55:452106static void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222107 Environment* env = Environment::GetCurrent(args.GetIsolate());
2108
Anatoli Papirovskibb27bfe2018-01-25 04:25:202109 CHECK(args[0]->IsString());
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222110
Anatoli Papirovskibb27bfe2018-01-25 04:25:202111 Local<String> module_name = args[0].As<String>();
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222112
Phillip Kovalev71470a82016-01-19 21:52:162113 node::Utf8Value module_name_v(env->isolate(), module_name);
2114 node_module* mod = get_linked_module(*module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222115
Bert Belder9483bfe2014-12-09 04:57:172116 if (mod == nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222117 char errmsg[1024];
2118 snprintf(errmsg,
2119 sizeof(errmsg),
2120 "No such module was linked: %s",
Phillip Kovalev71470a82016-01-19 21:52:162121 *module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222122 return env->ThrowError(errmsg);
2123 }
2124
Phillip Kovalev71470a82016-01-19 21:52:162125 Local<Object> module = Object::New(env->isolate());
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222126 Local<Object> exports = Object::New(env->isolate());
Phillip Kovalev71470a82016-01-19 21:52:162127 Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
2128 module->Set(exports_prop, exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222129
Bert Belder9483bfe2014-12-09 04:57:172130 if (mod->nm_context_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222131 mod->nm_context_register_func(exports,
2132 module,
2133 env->context(),
2134 mod->nm_priv);
Bert Belder9483bfe2014-12-09 04:57:172135 } else if (mod->nm_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222136 mod->nm_register_func(exports, module, mod->nm_priv);
2137 } else {
2138 return env->ThrowError("Linked module has no declared entry point.");
2139 }
2140
Phillip Kovalev5c14efb2016-02-20 08:30:432141 auto effective_exports = module->Get(exports_prop);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222142
Phillip Kovalev5c14efb2016-02-20 08:30:432143 args.GetReturnValue().Set(effective_exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222144}
Ryan Dahle742d072009-10-09 11:25:042145
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262146static void ProcessTitleGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442147 const PropertyCallbackInfo<Value>& info) {
Igor Zinkovsky500c8f42011-12-15 20:36:052148 char buffer[512];
2149 uv_get_process_title(buffer, sizeof(buffer));
Ben Noordhuis2e5b87a2015-03-22 23:38:422150 info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
Ryan Dahl5185c152010-06-18 07:26:492151}
2152
2153
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262154static void ProcessTitleSetter(Local<Name> property,
Ryan Dahl5185c152010-06-18 07:26:492155 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:442156 const PropertyCallbackInfo<void>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422157 node::Utf8Value title(info.GetIsolate(), value);
Igor Zinkovsky500c8f42011-12-15 20:36:052158 uv_set_process_title(*title);
Ryan Dahl5185c152010-06-18 07:26:492159}
2160
2161
AnnaMagab194122016-10-06 20:50:412162static void EnvGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442163 const PropertyCallbackInfo<Value>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422164 Isolate* isolate = info.GetIsolate();
Anna Henningsen3295a7f2016-11-16 01:27:142165 if (property->IsSymbol()) {
2166 return info.GetReturnValue().SetUndefined();
2167 }
Anna Henningsen2c52f652018-05-05 15:47:022168 Mutex::ScopedLock lock(environ_mutex);
Bert Belder077f9d72012-02-15 22:34:182169#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422170 node::Utf8Value key(isolate, property);
Ben Noordhuisb4def482010-10-15 13:48:342171 const char* val = getenv(*key);
2172 if (val) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422173 return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
Ben Noordhuisb4def482010-10-15 13:48:342174 }
Bert Belder077f9d72012-02-15 22:34:182175#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542176 node::TwoByteValue key(isolate, property);
Fedor Indutny8e29ce92013-07-31 18:07:292177 WCHAR buffer[32767]; // The maximum size allowed for environment variables.
Anna Henningsen6acb1a32018-01-30 19:27:172178 SetLastError(ERROR_SUCCESS);
Bert Belder077f9d72012-02-15 22:34:182179 DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2180 buffer,
Ben Noordhuisa7581d02016-03-31 10:47:062181 arraysize(buffer));
Bert Belder077f9d72012-02-15 22:34:182182 // If result >= sizeof buffer the buffer was too small. That should never
2183 // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
Tobias Nießene3166552018-05-20 10:13:032184 // found.
Bert Belder077f9d72012-02-15 22:34:182185 if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
Ben Noordhuisa7581d02016-03-31 10:47:062186 result < arraysize(buffer)) {
Ben Noordhuisf674b092013-08-07 19:50:412187 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
Ben Noordhuis2e5b87a2015-03-22 23:38:422188 Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
Ben Noordhuisf674b092013-08-07 19:50:412189 return info.GetReturnValue().Set(rc);
Bert Belder077f9d72012-02-15 22:34:182190 }
2191#endif
Ben Noordhuisb4def482010-10-15 13:48:342192}
2193
2194
AnnaMagab194122016-10-06 20:50:412195static void EnvSetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442196 Local<Value> value,
2197 const PropertyCallbackInfo<Value>& info) {
Timothy Gu5826fe42018-02-25 21:42:102198 Environment* env = Environment::GetCurrent(info);
2199 if (config_pending_deprecation && env->EmitProcessEnvWarning() &&
2200 !value->IsString() && !value->IsNumber() && !value->IsBoolean()) {
2201 if (ProcessEmitDeprecationWarning(
2202 env,
2203 "Assigning any value other than a string, number, or boolean to a "
2204 "process.env property is deprecated. Please make sure to convert the "
2205 "value to a string before setting process.env with it.",
Sakthipriyan Vairamani (thefourtheye)50b1cb32018-03-07 19:12:412206 "DEP0104").IsNothing())
Timothy Gu5826fe42018-02-25 21:42:102207 return;
2208 }
Anna Henningsen2c52f652018-05-05 15:47:022209
2210 Mutex::ScopedLock lock(environ_mutex);
Bert Belder077f9d72012-02-15 22:34:182211#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422212 node::Utf8Value key(info.GetIsolate(), property);
2213 node::Utf8Value val(info.GetIsolate(), value);
Ben Noordhuisb4def482010-10-15 13:48:342214 setenv(*key, *val, 1);
Bert Belder077f9d72012-02-15 22:34:182215#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542216 node::TwoByteValue key(info.GetIsolate(), property);
2217 node::TwoByteValue val(info.GetIsolate(), value);
Bert Belder077f9d72012-02-15 22:34:182218 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2219 // Environment variables that start with '=' are read-only.
2220 if (key_ptr[0] != L'=') {
2221 SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
Ryan Dahle6b06bc2011-08-11 00:14:232222 }
Bert Belder30bab522010-11-25 00:09:062223#endif
Miguel Angel Asencio Hurtado88323e82016-10-11 08:19:162224 // Whether it worked or not, always return value.
Ben Noordhuis110a9cd2013-07-03 02:23:442225 info.GetReturnValue().Set(value);
Ben Noordhuisb4def482010-10-15 13:48:342226}
2227
2228
AnnaMagab194122016-10-06 20:50:412229static void EnvQuery(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442230 const PropertyCallbackInfo<Integer>& info) {
Anna Henningsen2c52f652018-05-05 15:47:022231 Mutex::ScopedLock lock(environ_mutex);
Ben Noordhuis110a9cd2013-07-03 02:23:442232 int32_t rc = -1; // Not found unless proven otherwise.
Timothy Gue2f151f2017-03-06 06:45:192233 if (property->IsString()) {
Bert Belder077f9d72012-02-15 22:34:182234#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192235 node::Utf8Value key(info.GetIsolate(), property);
2236 if (getenv(*key))
2237 rc = 0;
Bert Belder077f9d72012-02-15 22:34:182238#else // _WIN32
Timothy Gue2f151f2017-03-06 06:45:192239 node::TwoByteValue key(info.GetIsolate(), property);
2240 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
Anna Henningsen6acb1a32018-01-30 19:27:172241 SetLastError(ERROR_SUCCESS);
Timothy Gue2f151f2017-03-06 06:45:192242 if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2243 GetLastError() == ERROR_SUCCESS) {
2244 rc = 0;
2245 if (key_ptr[0] == L'=') {
2246 // Environment variables that start with '=' are hidden and read-only.
2247 rc = static_cast<int32_t>(v8::ReadOnly) |
2248 static_cast<int32_t>(v8::DontDelete) |
2249 static_cast<int32_t>(v8::DontEnum);
2250 }
Bert Belder077f9d72012-02-15 22:34:182251 }
Bert Belder077f9d72012-02-15 22:34:182252#endif
Timothy Gue2f151f2017-03-06 06:45:192253 }
Fedor Indutny2bc30f22013-10-16 16:57:262254 if (rc != -1)
2255 info.GetReturnValue().Set(rc);
Ben Noordhuisb4def482010-10-15 13:48:342256}
2257
2258
AnnaMagab194122016-10-06 20:50:412259static void EnvDeleter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442260 const PropertyCallbackInfo<Boolean>& info) {
Anna Henningsen2c52f652018-05-05 15:47:022261 Mutex::ScopedLock lock(environ_mutex);
Timothy Gue2f151f2017-03-06 06:45:192262 if (property->IsString()) {
Bert Belder30bab522010-11-25 00:09:062263#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192264 node::Utf8Value key(info.GetIsolate(), property);
2265 unsetenv(*key);
Bert Belder30bab522010-11-25 00:09:062266#else
Timothy Gue2f151f2017-03-06 06:45:192267 node::TwoByteValue key(info.GetIsolate(), property);
2268 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2269 SetEnvironmentVariableW(key_ptr, nullptr);
Bert Belder077f9d72012-02-15 22:34:182270#endif
Timothy Gue2f151f2017-03-06 06:45:192271 }
Franziska Hinkelmannff7a8412016-08-04 07:36:502272
2273 // process.env never has non-configurable properties, so always
2274 // return true like the tc39 delete operator.
2275 info.GetReturnValue().Set(true);
Ben Noordhuisb4def482010-10-15 13:48:342276}
2277
2278
Ben Noordhuis110a9cd2013-07-03 02:23:442279static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
Trevor Norris56985ca2015-11-11 19:28:412280 Environment* env = Environment::GetCurrent(info);
2281 Isolate* isolate = env->isolate();
2282 Local<Context> ctx = env->context();
2283 Local<Function> fn = env->push_values_to_array_function();
2284 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2285 size_t idx = 0;
2286
Anna Henningsen2c52f652018-05-05 15:47:022287 Mutex::ScopedLock lock(environ_mutex);
Bert Belder077f9d72012-02-15 22:34:182288#ifdef __POSIX__
Ben Noordhuisb4def482010-10-15 13:48:342289 int size = 0;
Fedor Indutny2bc30f22013-10-16 16:57:262290 while (environ[size])
2291 size++;
Ben Noordhuisb4def482010-10-15 13:48:342292
Trevor Norris56985ca2015-11-11 19:28:412293 Local<Array> envarr = Array::New(isolate);
Ben Noordhuisb4def482010-10-15 13:48:342294
2295 for (int i = 0; i < size; ++i) {
2296 const char* var = environ[i];
2297 const char* s = strchr(var, '=');
2298 const int length = s ? s - var : strlen(var);
Trevor Norris56985ca2015-11-11 19:28:412299 argv[idx] = String::NewFromUtf8(isolate,
2300 var,
2301 String::kNormalString,
2302 length);
Ben Noordhuisa7581d02016-03-31 10:47:062303 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412304 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2305 idx = 0;
2306 }
2307 }
2308 if (idx > 0) {
2309 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
Ben Noordhuisb4def482010-10-15 13:48:342310 }
Bert Belder077f9d72012-02-15 22:34:182311#else // _WIN32
2312 WCHAR* environment = GetEnvironmentStringsW();
Ben Noordhuis2d82cdf2014-10-22 01:29:322313 if (environment == nullptr)
Fedor Indutny2bc30f22013-10-16 16:57:262314 return; // This should not happen.
Ben Noordhuis2e5b87a2015-03-22 23:38:422315 Local<Array> envarr = Array::New(isolate);
Bert Belder077f9d72012-02-15 22:34:182316 WCHAR* p = environment;
Nikolai Vavilovb105f6f2014-10-24 22:36:592317 while (*p) {
Daniel Beveniuscbc3dd92018-05-16 09:50:482318 WCHAR* s;
Bert Belder077f9d72012-02-15 22:34:182319 if (*p == L'=') {
2320 // If the key starts with '=' it is a hidden environment variable.
2321 p += wcslen(p) + 1;
2322 continue;
2323 } else {
2324 s = wcschr(p, L'=');
2325 }
2326 if (!s) {
2327 s = p + wcslen(p);
2328 }
Ben Noordhuisf674b092013-08-07 19:50:412329 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
Ben Noordhuis78f709d2013-08-09 15:43:102330 const size_t two_byte_buffer_len = s - p;
Trevor Norris56985ca2015-11-11 19:28:412331 argv[idx] = String::NewFromTwoByte(isolate,
2332 two_byte_buffer,
2333 String::kNormalString,
2334 two_byte_buffer_len);
Ben Noordhuisa7581d02016-03-31 10:47:062335 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412336 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2337 idx = 0;
2338 }
Bert Belder077f9d72012-02-15 22:34:182339 p = s + wcslen(s) + 1;
2340 }
Trevor Norris56985ca2015-11-11 19:28:412341 if (idx > 0) {
2342 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2343 }
Bert Belder077f9d72012-02-15 22:34:182344 FreeEnvironmentStringsW(environment);
2345#endif
Ben Noordhuis110a9cd2013-07-03 02:23:442346
Fedor Indutny75adde02014-02-21 13:02:422347 info.GetReturnValue().Set(envarr);
Ben Noordhuisb4def482010-10-15 13:48:342348}
2349
2350
cjihrig3cacd342017-10-30 20:14:152351static void GetParentProcessId(Local<Name> property,
2352 const PropertyCallbackInfo<Value>& info) {
2353 info.GetReturnValue().Set(Integer::New(info.GetIsolate(), uv_os_getppid()));
2354}
2355
2356
Michaël Zasso4abc8962015-07-18 09:34:162357static Local<Object> GetFeatures(Environment* env) {
Fedor Indutnyce04c722014-03-13 16:38:142358 EscapableHandleScope scope(env->isolate());
Ben Noordhuisaa0308d2011-07-23 21:16:482359
Fedor Indutnyce04c722014-03-13 16:38:142360 Local<Object> obj = Object::New(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352361#if defined(DEBUG) && DEBUG
Fedor Indutny75adde02014-02-21 13:02:422362 Local<Value> debug = True(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352363#else
Fedor Indutny75adde02014-02-21 13:02:422364 Local<Value> debug = False(env->isolate());
Fedor Indutny8e29ce92013-07-31 18:07:292365#endif // defined(DEBUG) && DEBUG
2366
Ben Noordhuisb4ea3a02016-08-21 10:31:202367 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
2368 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
Fedor Indutny8e29ce92013-07-31 18:07:292369 // TODO(bnoordhuis) ping libuv
Ben Noordhuisb4ea3a02016-08-21 10:31:202370 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
Ben Noordhuisf674b092013-08-07 19:50:412371
Ben Noordhuisa76f0292018-06-02 08:52:592372#ifdef HAVE_OPENSSL
2373 Local<Boolean> have_openssl = True(env->isolate());
Shigeki Ohtsu802a2e72015-04-23 06:25:152374#else
Ben Noordhuisa76f0292018-06-02 08:52:592375 Local<Boolean> have_openssl = False(env->isolate());
Shigeki Ohtsu802a2e72015-04-23 06:25:152376#endif
Shigeki Ohtsu802a2e72015-04-23 06:25:152377
Ben Noordhuisa76f0292018-06-02 08:52:592378 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), have_openssl);
2379 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), have_openssl);
2380 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), have_openssl);
2381 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"), have_openssl);
Ben Noordhuisaa0308d2011-07-23 21:16:482382
Fedor Indutnyce04c722014-03-13 16:38:142383 return scope.Escape(obj);
Ben Noordhuisaa0308d2011-07-23 21:16:482384}
2385
2386
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262387static void DebugPortGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442388 const PropertyCallbackInfo<Value>& info) {
Anna Henningsen2c52f652018-05-05 15:47:022389 Mutex::ScopedLock lock(process_mutex);
Ben Noordhuis399cb252017-05-27 11:31:002390 int port = debug_options.port();
2391#if HAVE_INSPECTOR
2392 if (port == 0) {
2393 Environment* env = Environment::GetCurrent(info);
Sam Robertsc4a61b32017-06-06 18:21:222394 if (auto io = env->inspector_agent()->io())
2395 port = io->port();
Ben Noordhuis399cb252017-05-27 11:31:002396 }
2397#endif // HAVE_INSPECTOR
2398 info.GetReturnValue().Set(port);
Fedor Indutny3f43b1c2012-02-12 15:53:432399}
2400
2401
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262402static void DebugPortSetter(Local<Name> property,
Fedor Indutny3f43b1c2012-02-12 15:53:432403 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:442404 const PropertyCallbackInfo<void>& info) {
Anna Henningsen2c52f652018-05-05 15:47:022405 Mutex::ScopedLock lock(process_mutex);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:222406 debug_options.set_port(value->Int32Value());
Fedor Indutny3f43b1c2012-02-12 15:53:432407}
2408
2409
Ben Noordhuis110a9cd2013-07-03 02:23:442410static void DebugProcess(const FunctionCallbackInfo<Value>& args);
Ben Noordhuis110a9cd2013-07-03 02:23:442411static void DebugEnd(const FunctionCallbackInfo<Value>& args);
Bert Belder829735e2011-11-04 15:23:022412
Anna Henningsen9d522222017-04-12 17:17:242413namespace {
Shigeki Ohtsucd372512013-02-06 02:13:022414
Ben Noordhuisf6496262013-10-03 09:03:462415void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552416 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:422417 env->StartProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:462418}
2419
2420
2421void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552422 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:422423 env->StopProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:462424}
2425
2426
Trevor Norrisc80f8fa2013-08-01 21:53:522427#define READONLY_PROPERTY(obj, str, var) \
2428 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:382429 obj->DefineOwnProperty(env->context(), \
2430 OneByteString(env->isolate(), str), \
2431 var, \
2432 v8::ReadOnly).FromJust(); \
Trevor Norrisc80f8fa2013-08-01 21:53:522433 } while (0)
2434
Petka Antonov872702d2015-02-22 12:44:122435#define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \
2436 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:382437 obj->DefineOwnProperty(env->context(), \
2438 OneByteString(env->isolate(), str), \
2439 var, \
2440 static_cast<v8::PropertyAttribute>(v8::ReadOnly | \
2441 v8::DontEnum)) \
2442 .FromJust(); \
Petka Antonov872702d2015-02-22 12:44:122443 } while (0)
2444
Anna Henningsen9d522222017-04-12 17:17:242445} // anonymous namespace
Trevor Norrisc80f8fa2013-08-01 21:53:522446
Ben Noordhuis756b6222013-08-10 22:26:112447void SetupProcessObject(Environment* env,
2448 int argc,
2449 const char* const* argv,
2450 int exec_argc,
2451 const char* const* exec_argv) {
Fedor Indutny75adde02014-02-21 13:02:422452 HandleScope scope(env->isolate());
Ryan Dahlcd1ec272011-01-02 09:44:422453
Ben Noordhuis756b6222013-08-10 22:26:112454 Local<Object> process = env->process_object();
Ben Noordhuis74a82152012-02-03 15:32:002455
Ben Noordhuisb4ea3a02016-08-21 10:31:202456 auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
Anna Henningsen0df031a2017-09-01 15:03:412457 CHECK(process->SetAccessor(
2458 env->context(),
2459 title_string,
2460 ProcessTitleGetter,
2461 env->is_main_thread() ? ProcessTitleSetter : nullptr,
2462 env->as_external()).FromJust());
Ryan Dahl5185c152010-06-18 07:26:492463
Ryan Dahlf4811832009-11-02 23:21:002464 // process.version
Ben Noordhuisf674b092013-08-07 19:50:412465 READONLY_PROPERTY(process,
2466 "version",
Fedor Indutny75adde02014-02-21 13:02:422467 FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
Ryan Dahl39b432e2010-08-17 18:24:102468
Nathan Rajlich35043ad2012-03-13 23:04:172469 // process.versions
Fedor Indutnyce04c722014-03-13 16:38:142470 Local<Object> versions = Object::New(env->isolate());
Trevor Norrisc80f8fa2013-08-01 21:53:522471 READONLY_PROPERTY(process, "versions", versions);
Ben Noordhuisf674b092013-08-07 19:50:412472
2473 const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
2474 "."
Johan Bergströmc0a9d1b2015-01-26 23:08:442475 NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
2476 "."
2477 NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
Ben Noordhuisf674b092013-08-07 19:50:412478 READONLY_PROPERTY(versions,
2479 "http_parser",
Fedor Indutny75adde02014-02-21 13:02:422480 FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
Ben Noordhuisf674b092013-08-07 19:50:412481
Ryan Dahl39b432e2010-08-17 18:24:102482 // +1 to get rid of the leading 'v'
Ben Noordhuisf674b092013-08-07 19:50:412483 READONLY_PROPERTY(versions,
2484 "node",
Fedor Indutny75adde02014-02-21 13:02:422485 OneByteString(env->isolate(), NODE_VERSION + 1));
Ben Noordhuisf674b092013-08-07 19:50:412486 READONLY_PROPERTY(versions,
2487 "v8",
Fedor Indutny75adde02014-02-21 13:02:422488 OneByteString(env->isolate(), V8::GetVersion()));
Ben Noordhuisf674b092013-08-07 19:50:412489 READONLY_PROPERTY(versions,
2490 "uv",
Fedor Indutny75adde02014-02-21 13:02:422491 OneByteString(env->isolate(), uv_version_string()));
Ben Noordhuisf674b092013-08-07 19:50:412492 READONLY_PROPERTY(versions,
2493 "zlib",
Fedor Indutny75adde02014-02-21 13:02:422494 FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
Johan Bergström01736dd2015-01-14 00:12:052495 READONLY_PROPERTY(versions,
2496 "ares",
2497 FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
Ben Noordhuisf674b092013-08-07 19:50:412498
2499 const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
Fedor Indutny75adde02014-02-21 13:02:422500 READONLY_PROPERTY(
2501 versions,
2502 "modules",
2503 FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
Ben Noordhuisf674b092013-08-07 19:50:412504
James M Snelle71e71b2017-07-17 17:17:162505 READONLY_PROPERTY(versions,
2506 "nghttp2",
2507 FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
2508
Michael Dawson8938c4c2018-01-09 20:06:282509 const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
2510 READONLY_PROPERTY(
2511 versions,
2512 "napi",
2513 FIXED_ONE_BYTE_STRING(env->isolate(), node_napi_version));
2514
Peter Bright13d6a1f2011-08-06 04:23:252515#if HAVE_OPENSSL
Ryan Dahlcd1ec272011-01-02 09:44:422516 // Stupid code to slice out the version string.
Ben Noordhuis7acdabb2013-11-04 21:42:482517 { // NOLINT(whitespace/braces)
Ben Noordhuis962686b2013-11-03 20:00:372518 size_t i, j, k;
2519 int c;
2520 for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
2521 c = OPENSSL_VERSION_TEXT[i];
2522 if ('0' <= c && c <= '9') {
2523 for (j = i + 1; j < k; ++j) {
2524 c = OPENSSL_VERSION_TEXT[j];
2525 if (c == ' ')
2526 break;
2527 }
2528 break;
Ryan Dahlcd1ec272011-01-02 09:44:422529 }
Ryan Dahlcd1ec272011-01-02 09:44:422530 }
Ben Noordhuis962686b2013-11-03 20:00:372531 READONLY_PROPERTY(
2532 versions,
2533 "openssl",
Fedor Indutny75adde02014-02-21 13:02:422534 OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
Ryan Dahlcd1ec272011-01-02 09:44:422535 }
Ryan Dahlcd1ec272011-01-02 09:44:422536#endif
Ryan Dahl39b432e2010-08-17 18:24:102537
Nathan Rajlichb1be5402011-04-26 03:24:512538 // process.arch
Bert Beldere1fe2702015-01-08 12:05:512539 READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
Nathan Rajlichb1be5402011-04-26 03:24:512540
Ryan Dahlf4811832009-11-02 23:21:002541 // process.platform
Vladimir Kurchatkin9f457992015-01-09 12:38:092542 READONLY_PROPERTY(process,
2543 "platform",
2544 OneByteString(env->isolate(), NODE_PLATFORM));
Ryan Dahlf4811832009-11-02 23:21:002545
Rod Vagg04fd4fa2015-01-18 06:41:372546 // process.release
2547 Local<Object> release = Object::New(env->isolate());
2548 READONLY_PROPERTY(process, "release", release);
Anna Henningsen835c3832017-08-08 17:09:282549 READONLY_PROPERTY(release, "name",
2550 OneByteString(env->isolate(), NODE_RELEASE));
Rod Vagg04fd4fa2015-01-18 06:41:372551
Rod Vagg905cd432015-10-06 12:31:142552#if NODE_VERSION_IS_LTS
2553 READONLY_PROPERTY(release, "lts",
2554 OneByteString(env->isolate(), NODE_VERSION_LTS_CODENAME));
2555#endif
2556
Rod Vagg04fd4fa2015-01-18 06:41:372557// if this is a release build and no explicit base has been set
2558// substitute the standard release download URL
2559#ifndef NODE_RELEASE_URLBASE
2560# if NODE_VERSION_IS_RELEASE
cjihriga69ab272015-08-13 16:14:342561# define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
Rod Vagg04fd4fa2015-01-18 06:41:372562# endif
2563#endif
2564
2565#if defined(NODE_RELEASE_URLBASE)
Rod Vagg278a9262015-09-05 04:41:342566# define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
2567# define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
Rod Vagg04fd4fa2015-01-18 06:41:372568
2569 READONLY_PROPERTY(release,
2570 "sourceUrl",
2571 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:342572 NODE_RELEASE_URLFPFX ".tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:372573 READONLY_PROPERTY(release,
2574 "headersUrl",
2575 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:342576 NODE_RELEASE_URLFPFX "-headers.tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:372577# ifdef _WIN32
2578 READONLY_PROPERTY(release,
2579 "libUrl",
2580 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:342581 strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
2582 NODE_ARCH "/node.lib"
2583 : NODE_RELEASE_URLPFX
2584 "win-x86/node.lib"));
Rod Vagg04fd4fa2015-01-18 06:41:372585# endif
2586#endif
2587
Ryan Dahlf3ad6352010-02-03 20:19:082588 // process.argv
Fedor Indutnyce04c722014-03-13 16:38:142589 Local<Array> arguments = Array::New(env->isolate(), argc);
Ben Noordhuis185c5152013-09-02 14:42:012590 for (int i = 0; i < argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:422591 arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
Ryan27b268b2009-06-17 13:05:442592 }
Ben Noordhuisb4ea3a02016-08-21 10:31:202593 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
Ryan27b268b2009-06-17 13:05:442594
Micheil Smith19fd5302012-03-05 17:53:152595 // process.execArgv
Fedor Indutnyce04c722014-03-13 16:38:142596 Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
Ben Noordhuis185c5152013-09-02 14:42:012597 for (int i = 0; i < exec_argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:422598 exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
Micheil Smith19fd5302012-03-05 17:53:152599 }
Ben Noordhuisb4ea3a02016-08-21 10:31:202600 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
2601 exec_arguments);
Micheil Smith19fd5302012-03-05 17:53:152602
Ryan Dahlf3ad6352010-02-03 20:19:082603 // create process.env
Fedor Indutnyce04c722014-03-13 16:38:142604 Local<ObjectTemplate> process_env_template =
2605 ObjectTemplate::New(env->isolate());
AnnaMagab194122016-10-06 20:50:412606 process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
2607 EnvGetter,
2608 EnvSetter,
2609 EnvQuery,
2610 EnvDeleter,
2611 EnvEnumerator,
cjihrig1aa595e2016-11-03 16:16:542612 env->as_external()));
AnnaMagab194122016-10-06 20:50:412613
Michaël Zassoad0ce572016-01-26 08:41:292614 Local<Object> process_env =
2615 process_env_template->NewInstance(env->context()).ToLocalChecked();
Ben Noordhuis63c47e72016-10-20 20:36:172616 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
Ryan Dahlf3ad6352010-02-03 20:19:082617
Ben Noordhuis7dc35e92017-11-20 22:37:502618 READONLY_PROPERTY(process, "pid",
cjihriga803bca2017-12-01 14:57:072619 Integer::New(env->isolate(), uv_os_getpid()));
Fedor Indutny75adde02014-02-21 13:02:422620 READONLY_PROPERTY(process, "features", GetFeatures(env));
Ben Noordhuisb4ea3a02016-08-21 10:31:202621
cjihrig2b931512017-11-12 02:10:132622 CHECK(process->SetAccessor(env->context(),
2623 FIXED_ONE_BYTE_STRING(env->isolate(), "ppid"),
2624 GetParentProcessId).FromJust());
cjihrig3cacd342017-10-30 20:14:152625
TJ Holowaychuk9481bc12010-10-07 02:05:012626 // -e, --eval
Evan Lucas5b6f5752015-06-01 14:15:102627 if (eval_string) {
Ben Noordhuisf674b092013-08-07 19:50:412628 READONLY_PROPERTY(process,
2629 "_eval",
Evan Lucas5b6f5752015-06-01 14:15:102630 String::NewFromUtf8(env->isolate(), eval_string));
Nathan Rajlichef3a8742012-04-24 08:24:132631 }
2632
2633 // -p, --print
Evan Lucas5b6f5752015-06-01 14:15:102634 if (print_eval) {
Fedor Indutny75adde02014-02-21 13:02:422635 READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
TJ Holowaychuk9481bc12010-10-07 02:05:012636 }
2637
Dave Eddy2e6ece42015-08-17 21:33:132638 // -c, --check
2639 if (syntax_check_only) {
2640 READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
2641 }
2642
Nathan Rajlich6292df62012-04-24 08:32:332643 // -i, --interactive
Evan Lucas5b6f5752015-06-01 14:15:102644 if (force_repl) {
Fedor Indutny75adde02014-02-21 13:02:422645 READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
Nathan Rajlichfeaa8a42012-03-21 07:05:252646 }
2647
Sam Robertse505c072017-04-05 21:04:442648 // -r, --require
Sam Robertscecdf7c2017-04-05 18:45:522649 if (!preload_modules.empty()) {
Ali Ijaz Sheikh1514b822015-02-17 22:37:372650 Local<Array> array = Array::New(env->isolate());
Sam Robertscecdf7c2017-04-05 18:45:522651 for (unsigned int i = 0; i < preload_modules.size(); ++i) {
Evan Lucas5b6f5752015-06-01 14:15:102652 Local<String> module = String::NewFromUtf8(env->isolate(),
Sam Robertscecdf7c2017-04-05 18:45:522653 preload_modules[i].c_str());
Ali Ijaz Sheikh1514b822015-02-17 22:37:372654 array->Set(i, module);
2655 }
2656 READONLY_PROPERTY(process,
2657 "_preload_modules",
2658 array);
Ali Ijaz Sheikhf06b16f2015-03-25 19:19:462659
Sam Robertscecdf7c2017-04-05 18:45:522660 preload_modules.clear();
Ali Ijaz Sheikh1514b822015-02-17 22:37:372661 }
2662
isaacs5b399292012-06-21 18:42:332663 // --no-deprecation
Evan Lucas5b6f5752015-06-01 14:15:102664 if (no_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:422665 READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:332666 }
2667
Sam Robertse505c072017-04-05 21:04:442668 // --no-warnings
James M Snellc6656db2016-01-20 19:38:352669 if (no_process_warnings) {
2670 READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
2671 }
2672
Sam Robertse505c072017-04-05 21:04:442673 // --trace-warnings
James M Snellc6656db2016-01-20 19:38:352674 if (trace_warnings) {
2675 READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate()));
2676 }
2677
isaacs5038f402013-03-06 01:46:372678 // --throw-deprecation
Evan Lucas5b6f5752015-06-01 14:15:102679 if (throw_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:422680 READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
isaacs5038f402013-03-06 01:46:372681 }
2682
Fedor Indutny8363ede2016-03-23 01:05:542683#ifdef NODE_NO_BROWSER_GLOBALS
2684 // configure --no-browser-globals
2685 READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate()));
2686#endif // NODE_NO_BROWSER_GLOBALS
2687
Matt Loring49440b72015-11-25 14:08:582688 // --prof-process
2689 if (prof_process) {
2690 READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
2691 }
2692
isaacs5b399292012-06-21 18:42:332693 // --trace-deprecation
Evan Lucas5b6f5752015-06-01 14:15:102694 if (trace_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:422695 READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:332696 }
2697
cjihrigdf5d8e02017-06-05 02:06:572698 // TODO(refack): move the following 3 to `node_config`
Ben Noordhuise0b076a2017-04-18 20:10:352699 // --inspect-brk
Eugene Ostroukhovf9aadfb2016-11-18 21:52:222700 if (debug_options.wait_for_connect()) {
Refael Ackermann16689e32017-05-29 03:28:012701 READONLY_DONT_ENUM_PROPERTY(process,
2702 "_breakFirstLine", True(env->isolate()));
2703 }
2704
2705 // --inspect --debug-brk
2706 if (debug_options.deprecated_invocation()) {
2707 READONLY_DONT_ENUM_PROPERTY(process,
2708 "_deprecatedDebugBrk", True(env->isolate()));
2709 }
2710
2711 // --debug or, --debug-brk without --inspect
2712 if (debug_options.invalid_invocation()) {
2713 READONLY_DONT_ENUM_PROPERTY(process,
2714 "_invalidDebug", True(env->isolate()));
Ali Ijaz Sheikh4d4cfb22016-05-05 15:31:342715 }
2716
James M Snelld3875912016-02-04 01:16:102717 // --security-revert flags
2718#define V(code, _, __) \
2719 do { \
James M Snell35f6e592017-08-16 16:34:372720 if (IsReverted(SECURITY_REVERT_ ## code)) { \
James M Snelld3875912016-02-04 01:16:102721 READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate())); \
2722 } \
2723 } while (0);
James M Snell35f6e592017-08-16 16:34:372724 SECURITY_REVERSIONS(V)
James M Snelld3875912016-02-04 01:16:102725#undef V
2726
Ben Noordhuisf674b092013-08-07 19:50:412727 size_t exec_path_len = 2 * PATH_MAX;
2728 char* exec_path = new char[exec_path_len];
2729 Local<String> exec_path_value;
2730 if (uv_exepath(exec_path, &exec_path_len) == 0) {
Fedor Indutny75adde02014-02-21 13:02:422731 exec_path_value = String::NewFromUtf8(env->isolate(),
Ben Noordhuisf674b092013-08-07 19:50:412732 exec_path,
2733 String::kNormalString,
2734 exec_path_len);
Marshall Culpepperca35ba62010-06-22 06:31:192735 } else {
Fedor Indutny75adde02014-02-21 13:02:422736 exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
Marshall Culpepperca35ba62010-06-22 06:31:192737 }
Ben Noordhuisb4ea3a02016-08-21 10:31:202738 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"),
2739 exec_path_value);
Ben Noordhuisf674b092013-08-07 19:50:412740 delete[] exec_path;
Marshall Culpepperca35ba62010-06-22 06:31:192741
Ben Noordhuisb4ea3a02016-08-21 10:31:202742 auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort");
2743 CHECK(process->SetAccessor(env->context(),
2744 debug_port_string,
2745 DebugPortGetter,
Anna Henningsen0df031a2017-09-01 15:03:412746 env->is_main_thread() ? DebugPortSetter : nullptr,
Ben Noordhuisb4ea3a02016-08-21 10:31:202747 env->as_external()).FromJust());
Fedor Indutny3f43b1c2012-02-12 15:53:432748
Ryan Dahl38814552009-10-09 15:15:472749 // define various internal methods
Anna Henningsen0df031a2017-09-01 15:03:412750 if (env->is_main_thread()) {
2751 env->SetMethod(process,
2752 "_startProfilerIdleNotifier",
2753 StartProfilerIdleNotifier);
2754 env->SetMethod(process,
2755 "_stopProfilerIdleNotifier",
2756 StopProfilerIdleNotifier);
2757 env->SetMethod(process, "abort", Abort);
2758 env->SetMethod(process, "chdir", Chdir);
2759 env->SetMethod(process, "umask", Umask);
2760 }
2761
Ben Noordhuisd3c317e2014-10-13 13:19:552762 env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
2763 env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
2764 env->SetMethod(process, "reallyExit", Exit);
Ben Noordhuisd3c317e2014-10-13 13:19:552765 env->SetMethod(process, "cwd", Cwd);
Bert Belder30bab522010-11-25 00:09:062766
Ed Schouten78dbcbe2017-10-30 10:58:132767#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ben Noordhuisd3c317e2014-10-13 13:19:552768 env->SetMethod(process, "getuid", GetUid);
Evan Lucas3c92ca22015-04-27 16:24:192769 env->SetMethod(process, "geteuid", GetEUid);
Ben Noordhuisd3c317e2014-10-13 13:19:552770 env->SetMethod(process, "getgid", GetGid);
Evan Lucas3c92ca22015-04-27 16:24:192771 env->SetMethod(process, "getegid", GetEGid);
Ben Noordhuisd3c317e2014-10-13 13:19:552772 env->SetMethod(process, "getgroups", GetGroups);
Ed Schouten78dbcbe2017-10-30 10:58:132773#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
James Duncandf1c1e52010-02-23 22:45:022774
Ben Noordhuisd3c317e2014-10-13 13:19:552775 env->SetMethod(process, "_kill", Kill);
Anna Henningsen0df031a2017-09-01 15:03:412776 env->SetMethod(process, "dlopen", DLOpen);
Bert Belder30bab522010-11-25 00:09:062777
Anna Henningsen0df031a2017-09-01 15:03:412778 if (env->is_main_thread()) {
2779 env->SetMethod(process, "_debugProcess", DebugProcess);
2780 env->SetMethod(process, "_debugEnd", DebugEnd);
2781 }
Bert Belder829735e2011-11-04 15:23:022782
Ben Noordhuisd3c317e2014-10-13 13:19:552783 env->SetMethod(process, "hrtime", Hrtime);
Nathan Rajlich07c886f2012-03-05 16:51:582784
Patrick Mueller52cb4102016-04-05 13:17:482785 env->SetMethod(process, "cpuUsage", CPUUsage);
2786
Ben Noordhuisd3c317e2014-10-13 13:19:552787 env->SetMethod(process, "uptime", Uptime);
2788 env->SetMethod(process, "memoryUsage", MemoryUsage);
Dean McNameef67e8f22011-03-15 22:39:162789}
2790
2791
Trevor Norrisc80f8fa2013-08-01 21:53:522792#undef READONLY_PROPERTY
2793
2794
Anna Henningsen0815b942016-05-08 01:28:472795void SignalExit(int signo) {
Evan Lucas14dc17d2018-06-11 14:20:502796 uv_tty_reset_mode();
James M Snell5c27e442018-04-04 01:05:332797 v8_platform.StopTracingAgent();
Fedor Indutnyb64983d2015-03-20 05:03:342798#ifdef __FreeBSD__
2799 // FreeBSD has a nasty bug, see RegisterSignalHandler for details
2800 struct sigaction sa;
2801 memset(&sa, 0, sizeof(sa));
2802 sa.sa_handler = SIG_DFL;
2803 CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
2804#endif
Geir Haugec61b0e92014-03-31 07:52:032805 raise(signo);
Dean McNameef67e8f22011-03-15 22:39:162806}
2807
2808
isaacs906a1752013-08-21 22:36:502809// Most of the time, it's best to use `console.error` to write
2810// to the process.stderr stream. However, in some cases, such as
2811// when debugging the stream.Writable class or the process.nextTick
2812// function, it is useful to bypass JavaScript entirely.
James M Snellcb3d0492018-05-23 22:04:232813void RawDebug(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis5fdff382014-10-11 14:52:072814 CHECK(args.Length() == 1 && args[0]->IsString() &&
2815 "must be called with a single string");
Trevor Norriscbf76c12015-01-07 22:13:352816 node::Utf8Value message(args.GetIsolate(), args[0]);
Brian White2d356072015-10-13 21:18:152817 PrintErrorString("%s\n", *message);
isaacs906a1752013-08-21 22:36:502818 fflush(stderr);
2819}
2820
Joyee Cheung2a9eb312018-03-03 20:55:452821
Anna Henningsen0df031a2017-09-01 15:03:412822static MaybeLocal<Function> GetBootstrapper(
2823 Environment* env,
2824 Local<String> source,
2825 Local<String> script_name) {
Joyee Cheung2a9eb312018-03-03 20:55:452826 EscapableHandleScope scope(env->isolate());
Ben Noordhuis34b0a362013-07-29 03:07:072827
Michaël Zasso79d74752016-01-26 08:06:432828 TryCatch try_catch(env->isolate());
Ryan Dahl9f5643f2010-01-31 07:22:342829
Miroslav Bajtosc16963b2013-06-17 19:19:592830 // Disable verbose mode to stop FatalException() handler from trying
2831 // to handle the exception. Errors this early in the start-up phase
2832 // are not safe to ignore.
2833 try_catch.SetVerbose(false);
2834
Joyee Cheung8484b402018-03-06 14:42:322835 // Execute the bootstrapper javascript file
Anna Henningsen0df031a2017-09-01 15:03:412836 MaybeLocal<Value> bootstrapper_v = ExecuteString(env, source, script_name);
2837 if (bootstrapper_v.IsEmpty()) // This happens when execution was interrupted.
2838 return MaybeLocal<Function>();
2839
Ryan Dahl9f5643f2010-01-31 07:22:342840 if (try_catch.HasCaught()) {
Fedor Indutnyf1de13b2014-02-05 16:38:332841 ReportException(env, try_catch);
Ryan Dahl9f5643f2010-01-31 07:22:342842 exit(10);
2843 }
guybedfordd21a11d2017-09-03 11:20:062844
Anna Henningsen0df031a2017-09-01 15:03:412845 CHECK(bootstrapper_v.ToLocalChecked()->IsFunction());
2846 return scope.Escape(bootstrapper_v.ToLocalChecked().As<Function>());
Joyee Cheung2a9eb312018-03-03 20:55:452847}
2848
Joyee Cheung8484b402018-03-06 14:42:322849static bool ExecuteBootstrapper(Environment* env, Local<Function> bootstrapper,
Joyee Cheung2a9eb312018-03-03 20:55:452850 int argc, Local<Value> argv[],
2851 Local<Value>* out) {
Joyee Cheung8484b402018-03-06 14:42:322852 bool ret = bootstrapper->Call(
Joyee Cheung2a9eb312018-03-03 20:55:452853 env->context(), Null(env->isolate()), argc, argv).ToLocal(out);
2854
2855 // If there was an error during bootstrap then it was either handled by the
2856 // FatalException handler or it's unrecoverable (e.g. max call stack
2857 // exceeded). Either way, clear the stack so that the AsyncCallbackScope
2858 // destructor doesn't fail on the id check.
2859 // There are only two ways to have a stack size > 1: 1) the user manually
2860 // called MakeCallback or 2) user awaited during bootstrap, which triggered
2861 // _tickCallback().
2862 if (!ret) {
2863 env->async_hooks()->clear_async_id_stack();
2864 }
2865
2866 return ret;
2867}
2868
2869
2870void LoadEnvironment(Environment* env) {
2871 HandleScope handle_scope(env->isolate());
2872
2873 TryCatch try_catch(env->isolate());
2874 // Disable verbose mode to stop FatalException() handler from trying
2875 // to handle the exception. Errors this early in the start-up phase
2876 // are not safe to ignore.
2877 try_catch.SetVerbose(false);
2878
Joyee Cheung8484b402018-03-06 14:42:322879 // The bootstrapper scripts are lib/internal/bootstrap/loaders.js and
2880 // lib/internal/bootstrap/node.js, each included as a static C string
Joyee Cheung2a9eb312018-03-03 20:55:452881 // defined in node_javascript.h, generated in node_javascript.cc by
2882 // node_js2c.
Joyee Cheung8484b402018-03-06 14:42:322883 Local<String> loaders_name =
2884 FIXED_ONE_BYTE_STRING(env->isolate(), "internal/bootstrap/loaders.js");
Anna Henningsen0df031a2017-09-01 15:03:412885 MaybeLocal<Function> loaders_bootstrapper =
Joyee Cheung8484b402018-03-06 14:42:322886 GetBootstrapper(env, LoadersBootstrapperSource(env), loaders_name);
2887 Local<String> node_name =
2888 FIXED_ONE_BYTE_STRING(env->isolate(), "internal/bootstrap/node.js");
Anna Henningsen0df031a2017-09-01 15:03:412889 MaybeLocal<Function> node_bootstrapper =
Joyee Cheung8484b402018-03-06 14:42:322890 GetBootstrapper(env, NodeBootstrapperSource(env), node_name);
Ryan Dahl9f5643f2010-01-31 07:22:342891
Anna Henningsen0df031a2017-09-01 15:03:412892 if (loaders_bootstrapper.IsEmpty() || node_bootstrapper.IsEmpty()) {
2893 // Execution was interrupted.
2894 return;
2895 }
2896
Ryan Dahlf8ce8482010-09-17 07:01:072897 // Add a reference to the global object
Ben Noordhuis756b6222013-08-10 22:26:112898 Local<Object> global = env->context()->Global();
Zoran Tomicicd98ea702010-02-22 05:15:442899
Ben Noordhuisc4def502013-10-28 19:18:592900#if defined HAVE_DTRACE || defined HAVE_ETW
Fedor Indutny75adde02014-02-21 13:02:422901 InitDTrace(env, global);
Ryan Dahle9257b82011-02-10 02:50:262902#endif
Ryan Dahl068b7332011-01-25 01:50:102903
Scott Blomquistf657ce62012-11-20 23:27:222904#if defined HAVE_PERFCTR
Fedor Indutny75adde02014-02-21 13:02:422905 InitPerfCounters(env, global);
Scott Blomquistf657ce62012-11-20 23:27:222906#endif
2907
Miroslav Bajtosc16963b2013-06-17 19:19:592908 // Enable handling of uncaught exceptions
2909 // (FatalException(), break on uncaught exception in debugger)
2910 //
2911 // This is not strictly necessary since it's almost impossible
Benjamin Fleischer4897ae22017-02-06 01:18:462912 // to attach the debugger fast enough to break on exception
Miroslav Bajtosc16963b2013-06-17 19:19:592913 // thrown during process startup.
2914 try_catch.SetVerbose(true);
Ryan Dahl9f5643f2010-01-31 07:22:342915
Ben Noordhuisd3c317e2014-10-13 13:19:552916 env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
isaacs906a1752013-08-21 22:36:502917
Jeremiah Senkpiel21d66d62016-03-23 22:09:102918 // Expose the global object as a property on itself
2919 // (Allows you to set stuff on `global` from anywhere in JavaScript.)
2920 global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
2921
Joyee Cheung2a9eb312018-03-03 20:55:452922 // Create binding loaders
2923 v8::Local<v8::Function> get_binding_fn =
2924 env->NewFunctionTemplate(GetBinding)->GetFunction(env->context())
2925 .ToLocalChecked();
Daniel Beveniusa01e8bc2016-09-04 18:49:092926
Joyee Cheung2a9eb312018-03-03 20:55:452927 v8::Local<v8::Function> get_linked_binding_fn =
2928 env->NewFunctionTemplate(GetLinkedBinding)->GetFunction(env->context())
2929 .ToLocalChecked();
guybedfordd21a11d2017-09-03 11:20:062930
Joyee Cheung2a9eb312018-03-03 20:55:452931 v8::Local<v8::Function> get_internal_binding_fn =
2932 env->NewFunctionTemplate(GetInternalBinding)->GetFunction(env->context())
2933 .ToLocalChecked();
2934
2935 Local<Value> loaders_bootstrapper_args[] = {
2936 env->process_object(),
2937 get_binding_fn,
2938 get_linked_binding_fn,
2939 get_internal_binding_fn
2940 };
2941
2942 // Bootstrap internal loaders
2943 Local<Value> bootstrapped_loaders;
Anna Henningsen0df031a2017-09-01 15:03:412944 if (!ExecuteBootstrapper(env, loaders_bootstrapper.ToLocalChecked(),
Joyee Cheung2a9eb312018-03-03 20:55:452945 arraysize(loaders_bootstrapper_args),
2946 loaders_bootstrapper_args,
2947 &bootstrapped_loaders)) {
2948 return;
2949 }
2950
2951 // Bootstrap Node.js
James M Snellcb3d0492018-05-23 22:04:232952 Local<Object> bootstrapper = Object::New(env->isolate());
2953 SetupBootstrapObject(env, bootstrapper);
Joyee Cheung2a9eb312018-03-03 20:55:452954 Local<Value> bootstrapped_node;
2955 Local<Value> node_bootstrapper_args[] = {
2956 env->process_object(),
James M Snellcb3d0492018-05-23 22:04:232957 bootstrapper,
Joyee Cheung2a9eb312018-03-03 20:55:452958 bootstrapped_loaders
2959 };
Anna Henningsen0df031a2017-09-01 15:03:412960 if (!ExecuteBootstrapper(env, node_bootstrapper.ToLocalChecked(),
Joyee Cheung2a9eb312018-03-03 20:55:452961 arraysize(node_bootstrapper_args),
2962 node_bootstrapper_args,
2963 &bootstrapped_node)) {
2964 return;
2965 }
Ryan27b268b2009-06-17 13:05:442966}
2967
Evan Lucas5b6f5752015-06-01 14:15:102968static void PrintHelp() {
Jeremiah Senkpiel91cf55b2016-03-18 17:26:412969 // XXX: If you add an option here, please also add it to doc/node.1 and
Robert Jefe Lindstaedt0800c0a2016-04-20 22:12:402970 // doc/api/cli.md
Ebrahim Byagowi594b5d72017-05-13 07:58:182971 printf("Usage: node [options] [ -e script | script.js | - ] [arguments]\n"
Ali Ijaz Sheikha235ccd2017-03-14 21:20:382972 " node inspect script.js [arguments]\n"
Evan Lucas5b6f5752015-06-01 14:15:102973 "\n"
2974 "Options:\n"
willhaysletta43e8892018-04-08 06:33:192975 " - script read from stdin (default; \n"
2976 " interactive mode if a tty)\n"
2977 " -- indicate the end of node options\n"
2978 " --abort-on-uncaught-exception\n"
2979 " aborting instead of exiting causes a\n"
2980 " core file to be generated for analysis\n"
2981#if HAVE_OPENSSL && NODE_FIPS_MODE
2982 " --enable-fips enable FIPS crypto at startup\n"
2983#endif // NODE_FIPS_MODE && NODE_FIPS_MODE
2984#if defined(NODE_HAVE_I18N_SUPPORT)
2985 " --experimental-modules experimental ES Module support\n"
2986 " and caching modules\n"
Timothy Gube92eab2018-03-26 03:13:542987#endif // defined(NODE_HAVE_I18N_SUPPORT)
2988 " --experimental-repl-await experimental await keyword support\n"
2989 " in REPL\n"
2990#if defined(NODE_HAVE_I18N_SUPPORT)
willhaysletta43e8892018-04-08 06:33:192991 " --experimental-vm-modules experimental ES Module support\n"
2992 " in vm module\n"
2993#endif // defined(NODE_HAVE_I18N_SUPPORT)
Anna Henningsene7a23672017-09-05 20:38:322994 " --experimental-worker experimental threaded Worker support\n"
willhaysletta43e8892018-04-08 06:33:192995#if HAVE_OPENSSL && NODE_FIPS_MODE
2996 " --force-fips force FIPS crypto (cannot be disabled)\n"
2997#endif // HAVE_OPENSSL && NODE_FIPS_MODE
2998#if defined(NODE_HAVE_I18N_SUPPORT)
2999 " --icu-data-dir=dir set ICU data load path to dir\n"
3000 " (overrides NODE_ICU_DATA)\n"
3001#if !defined(NODE_HAVE_SMALL_ICU)
3002 " note: linked-in ICU data is present\n"
3003#endif
3004#endif // defined(NODE_HAVE_I18N_SUPPORT)
Josh Gavant6ff3b032016-12-15 04:18:153005#if HAVE_INSPECTOR
Gibson Fahnestock2d2970e2017-03-28 15:54:303006 " --inspect-brk[=[host:]port]\n"
3007 " activate inspector on host:port\n"
Josh Gavant6ff3b032016-12-15 04:18:153008 " and break at start of user script\n"
Sam Roberts3954ea92017-04-22 03:34:543009 " --inspect-port=[host:]port\n"
3010 " set host:port for inspector\n"
willhaysletta43e8892018-04-08 06:33:193011 " --inspect[=[host:]port] activate inspector on host:port\n"
3012 " (default: 127.0.0.1:9229)\n"
3013#endif // HAVE_INSPECTOR
Gabriel Schulhofa8c0a432017-08-18 10:30:053014 " --napi-modules load N-API modules (no-op - option\n"
3015 " kept for compatibility)\n"
willhaysletta43e8892018-04-08 06:33:193016 " --no-deprecation silence deprecation warnings\n"
3017 " --no-force-async-hooks-checks\n"
3018 " disable checks for async_hooks\n"
3019 " --no-warnings silence all process warnings\n"
3020#if HAVE_OPENSSL
3021 " --openssl-config=file load OpenSSL configuration from the\n"
3022 " specified file (overrides\n"
3023 " OPENSSL_CONF)\n"
3024#endif // HAVE_OPENSSL
3025 " --pending-deprecation emit pending deprecation warnings\n"
3026#if defined(NODE_HAVE_I18N_SUPPORT)
3027 " --preserve-symlinks preserve symbolic links when resolving\n"
David Goldstein23659652018-04-10 07:40:563028 " --preserve-symlinks-main preserve symbolic links when resolving\n"
3029 " the main module\n"
willhaysletta43e8892018-04-08 06:33:193030#endif
ohbarye9461f322018-05-20 10:05:083031 " --prof generate V8 profiler output\n"
3032 " --prof-process process V8 profiler output generated\n"
willhaysletta43e8892018-04-08 06:33:193033 " using --prof\n"
Sam Robertsa886b172017-05-19 17:53:383034 " --redirect-warnings=file\n"
3035 " write warnings to file instead of\n"
James M Snell03e89b32016-12-04 18:38:353036 " stderr\n"
willhaysletta43e8892018-04-08 06:33:193037 " --throw-deprecation throw an exception on deprecations\n"
3038#if HAVE_OPENSSL
3039 " --tls-cipher-list=val use an alternative default TLS cipher "
3040 "list\n"
3041#endif // HAVE_OPENSSL
3042 " --trace-deprecation show stack traces on deprecations\n"
Aashil Patel5d27cc12017-01-21 22:44:293043 " --trace-event-categories comma separated list of trace event\n"
3044 " categories to record\n"
Andreas Madsen85212bb2018-01-31 16:12:093045 " --trace-event-file-pattern Template string specifying the\n"
3046 " filepath for the trace-events data, it\n"
3047 " supports ${rotation} and ${pid}\n"
3048 " log-rotation id. %%2$u is the pid.\n"
willhaysletta43e8892018-04-08 06:33:193049 " --trace-events-enabled track trace events\n"
3050 " --trace-sync-io show stack trace when use of sync IO\n"
3051 " is detected after the first tick\n"
3052 " --trace-warnings show stack traces on process warnings\n"
Aashil Patel5d27cc12017-01-21 22:44:293053 " --track-heap-objects track heap object allocations for heap "
Bradley Meckcf14a242015-07-09 16:15:263054 "snapshots\n"
James M Snell5ba868f2015-08-17 22:51:513055#if HAVE_OPENSSL
Aashil Patel5d27cc12017-01-21 22:44:293056 " --use-bundled-ca use bundled CA store"
Adam Majer33012e92016-12-21 10:16:393057#if !defined(NODE_OPENSSL_CERT_STORE)
3058 " (default)"
3059#endif
3060 "\n"
Aashil Patel5d27cc12017-01-21 22:44:293061 " --use-openssl-ca use OpenSSL's default CA store"
Adam Majer33012e92016-12-21 10:16:393062#if defined(NODE_OPENSSL_CERT_STORE)
3063 " (default)"
3064#endif
willhaysletta43e8892018-04-08 06:33:193065#endif // HAVE_OPENSSL
Adam Majer33012e92016-12-21 10:16:393066 "\n"
willhaysletta43e8892018-04-08 06:33:193067 " --v8-options print v8 command line options\n"
3068 " --v8-pool-size=num set v8's thread pool size\n"
3069 " --zero-fill-buffers automatically zero-fill all newly "
3070 "allocated\n"
3071 " Buffer and SlowBuffer instances\n"
3072 " -c, --check syntax check script without executing\n"
3073 " -e, --eval script evaluate script\n"
3074 " -h, --help print node command line options\n"
3075 " -i, --interactive always enter the REPL even if stdin\n"
3076 " does not appear to be a terminal\n"
3077 " -p, --print evaluate script and print result\n"
3078 " -r, --require module to preload (option can be "
3079 "repeated)\n"
3080 " -v, --version print Node.js version\n"
Evan Lucas5b6f5752015-06-01 14:15:103081 "\n"
3082 "Environment variables:\n"
Aashil Patel5d27cc12017-01-21 22:44:293083 "NODE_DEBUG ','-separated list of core modules\n"
3084 " that should print debug information\n"
Anna Henningsenbd858442018-05-27 14:37:303085 "NODE_DEBUG_NATIVE ','-separated list of C++ core debug\n"
3086 " categories that should print debug\n"
3087 " output\n"
Aashil Patel5d27cc12017-01-21 22:44:293088 "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n"
3089 "NODE_EXTRA_CA_CERTS path to additional CA certificates\n"
3090 " file\n"
Evan Lucas5b6f5752015-06-01 14:15:103091#if defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293092 "NODE_ICU_DATA data path for ICU (Intl object) data\n"
Evan Lucas5b6f5752015-06-01 14:15:103093#if !defined(NODE_HAVE_SMALL_ICU)
Aashil Patel5d27cc12017-01-21 22:44:293094 " (will extend linked-in data)\n"
Evan Lucas5b6f5752015-06-01 14:15:103095#endif
willhaysletta43e8892018-04-08 06:33:193096#endif // defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293097 "NODE_NO_WARNINGS set to 1 to silence process warnings\n"
Sam Robertsf2282bb2017-02-20 14:18:433098#if !defined(NODE_WITHOUT_NODE_OPTIONS)
3099 "NODE_OPTIONS set CLI options in the environment\n"
Gabriel Schulhof6fe72c82017-08-09 06:58:003100 " via a space-separated list\n"
willhaysletta43e8892018-04-08 06:33:193101#endif // !defined(NODE_WITHOUT_NODE_OPTIONS)
Roman Reiss2d235622016-12-22 06:10:223102#ifdef _WIN32
Aashil Patel5d27cc12017-01-21 22:44:293103 "NODE_PATH ';'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223104#else
Aashil Patel5d27cc12017-01-21 22:44:293105 "NODE_PATH ':'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223106#endif
Aashil Patel5d27cc12017-01-21 22:44:293107 " prefixed to the module search path\n"
Thomas Corbière28a0af32017-09-25 12:45:433108 "NODE_PENDING_DEPRECATION set to 1 to emit pending deprecation\n"
3109 " warnings\n"
willhaysletta43e8892018-04-08 06:33:193110#if defined(NODE_HAVE_I18N_SUPPORT)
3111 "NODE_PRESERVE_SYMLINKS set to 1 to preserve symbolic links\n"
3112 " when resolving and caching modules\n"
3113#endif
James M Snell03e89b32016-12-04 18:38:353114 "NODE_REDIRECT_WARNINGS write warnings to path instead of\n"
3115 " stderr\n"
willhaysletta43e8892018-04-08 06:33:193116 "NODE_REPL_HISTORY path to the persistent REPL history\n"
3117 " file\n"
Sam Roberts59afa272017-01-25 22:13:343118 "OPENSSL_CONF load OpenSSL configuration from file\n"
3119 "\n"
cjihriga69ab272015-08-13 16:14:343120 "Documentation can be found at https://nodejs.org/\n");
Evan Lucas5b6f5752015-06-01 14:15:103121}
3122
3123
Sam Roberts97a6aa92017-07-05 21:25:553124static bool ArgIsAllowed(const char* arg, const char* allowed) {
3125 for (; *arg && *allowed; arg++, allowed++) {
3126 // Like normal strcmp(), except that a '_' in `allowed` matches either a '-'
3127 // or '_' in `arg`.
3128 if (*allowed == '_') {
3129 if (!(*arg == '_' || *arg == '-'))
3130 return false;
3131 } else {
3132 if (*arg != *allowed)
3133 return false;
3134 }
3135 }
3136
3137 // "--some-arg=val" is allowed for "--some-arg"
3138 if (*arg == '=')
3139 return true;
3140
3141 // Both must be null, or one string is just a prefix of the other, not a
3142 // match.
3143 return !*arg && !*allowed;
3144}
3145
3146
Sam Robertsf2282bb2017-02-20 14:18:433147static void CheckIfAllowedInEnv(const char* exe, bool is_env,
3148 const char* arg) {
3149 if (!is_env)
3150 return;
3151
Sam Robertsf2282bb2017-02-20 14:18:433152 static const char* whitelist[] = {
Sam Robertsb6593852017-05-23 16:02:073153 // Node options, sorted in `node --help` order for ease of comparison.
willhaysletta43e8892018-04-08 06:33:193154 "--enable-fips",
3155 "--experimental-modules",
Timothy Gube92eab2018-03-26 03:13:543156 "--experimental-repl-await",
willhaysletta43e8892018-04-08 06:33:193157 "--experimental-vm-modules",
Anna Henningsene7a23672017-09-05 20:38:323158 "--experimental-worker",
willhaysletta43e8892018-04-08 06:33:193159 "--force-fips",
3160 "--icu-data-dir",
Sam Robertsd6cd4662017-05-12 19:39:113161 "--inspect",
3162 "--inspect-brk",
3163 "--inspect-port",
guybedfordd21a11d2017-09-03 11:20:063164 "--loader",
willhaysletta43e8892018-04-08 06:33:193165 "--napi-modules",
3166 "--no-deprecation",
Andreas Madsen23a39112017-10-19 12:15:083167 "--no-force-async-hooks-checks",
willhaysletta43e8892018-04-08 06:33:193168 "--no-warnings",
3169 "--openssl-config",
3170 "--pending-deprecation",
3171 "--redirect-warnings",
3172 "--require",
3173 "--throw-deprecation",
3174 "--tls-cipher-list",
3175 "--trace-deprecation",
Evan Lucas701dc9a2017-11-28 11:46:353176 "--trace-event-categories",
Andreas Madsen85212bb2018-01-31 16:12:093177 "--trace-event-file-pattern",
willhaysletta43e8892018-04-08 06:33:193178 "--trace-events-enabled",
3179 "--trace-sync-io",
3180 "--trace-warnings",
Sam Robertsf2282bb2017-02-20 14:18:433181 "--track-heap-objects",
Sam Robertsf2282bb2017-02-20 14:18:433182 "--use-bundled-ca",
Sam Robertsd6cd4662017-05-12 19:39:113183 "--use-openssl-ca",
willhaysletta43e8892018-04-08 06:33:193184 "--v8-pool-size",
3185 "--zero-fill-buffers",
3186 "-r",
Sam Robertsf2282bb2017-02-20 14:18:433187
Sam Roberts97a6aa92017-07-05 21:25:553188 // V8 options (define with '_', which allows '-' or '_')
3189 "--abort_on_uncaught_exception",
Sam Robertsf2282bb2017-02-20 14:18:433190 "--max_old_space_size",
willhaysletta43e8892018-04-08 06:33:193191 "--perf_basic_prof",
3192 "--perf_prof",
Anna Henningsen89b32282017-10-25 17:51:583193 "--stack_trace_limit",
Sam Robertsf2282bb2017-02-20 14:18:433194 };
3195
3196 for (unsigned i = 0; i < arraysize(whitelist); i++) {
3197 const char* allowed = whitelist[i];
Sam Roberts97a6aa92017-07-05 21:25:553198 if (ArgIsAllowed(arg, allowed))
Sam Robertsf2282bb2017-02-20 14:18:433199 return;
3200 }
3201
3202 fprintf(stderr, "%s: %s is not allowed in NODE_OPTIONS\n", exe, arg);
3203 exit(9);
3204}
3205
3206
Evan Lucas5b6f5752015-06-01 14:15:103207// Parse command line arguments.
3208//
3209// argv is modified in place. exec_argv and v8_argv are out arguments that
3210// ParseArgs() allocates memory for and stores a pointer to the output
3211// vector in. The caller should free them with delete[].
3212//
3213// On exit:
3214//
3215// * argv contains the arguments with node and V8 options filtered out.
3216// * exec_argv contains both node and V8 options and nothing else.
3217// * v8_argv contains argv[0] plus any V8 options
3218static void ParseArgs(int* argc,
3219 const char** argv,
3220 int* exec_argc,
3221 const char*** exec_argv,
3222 int* v8_argc,
Sam Robertsf2282bb2017-02-20 14:18:433223 const char*** v8_argv,
3224 bool is_env) {
Evan Lucas5b6f5752015-06-01 14:15:103225 const unsigned int nargs = static_cast<unsigned int>(*argc);
3226 const char** new_exec_argv = new const char*[nargs];
3227 const char** new_v8_argv = new const char*[nargs];
3228 const char** new_argv = new const char*[nargs];
Daniel Beveniusde168b42017-04-10 13:13:243229#if HAVE_OPENSSL
Daniel Bevenius8a7db9d2017-03-28 06:56:393230 bool use_bundled_ca = false;
3231 bool use_openssl_ca = false;
Daniel Bevenius892ce062017-04-27 03:45:343232#endif // HAVE_OPENSSL
Evan Lucas5b6f5752015-06-01 14:15:103233
3234 for (unsigned int i = 0; i < nargs; ++i) {
3235 new_exec_argv[i] = nullptr;
3236 new_v8_argv[i] = nullptr;
3237 new_argv[i] = nullptr;
Evan Lucas5b6f5752015-06-01 14:15:103238 }
3239
3240 // exec_argv starts with the first option, the other two start with argv[0].
3241 unsigned int new_exec_argc = 0;
3242 unsigned int new_v8_argc = 1;
3243 unsigned int new_argc = 1;
3244 new_v8_argv[0] = argv[0];
3245 new_argv[0] = argv[0];
3246
3247 unsigned int index = 1;
Matt Loring49440b72015-11-25 14:08:583248 bool short_circuit = false;
3249 while (index < nargs && argv[index][0] == '-' && !short_circuit) {
Evan Lucas5b6f5752015-06-01 14:15:103250 const char* const arg = argv[index];
3251 unsigned int args_consumed = 1;
3252
Sam Robertsf2282bb2017-02-20 14:18:433253 CheckIfAllowedInEnv(argv[0], is_env, arg);
3254
Sam Roberts3954ea92017-04-22 03:34:543255 if (debug_options.ParseOption(argv[0], arg)) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223256 // Done, consumed by DebugOptions::ParseOption().
Evan Lucas5b6f5752015-06-01 14:15:103257 } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3258 printf("%s\n", NODE_VERSION);
3259 exit(0);
3260 } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3261 PrintHelp();
3262 exit(0);
3263 } else if (strcmp(arg, "--eval") == 0 ||
3264 strcmp(arg, "-e") == 0 ||
3265 strcmp(arg, "--print") == 0 ||
3266 strcmp(arg, "-pe") == 0 ||
3267 strcmp(arg, "-p") == 0) {
3268 bool is_eval = strchr(arg, 'e') != nullptr;
3269 bool is_print = strchr(arg, 'p') != nullptr;
3270 print_eval = print_eval || is_print;
3271 // --eval, -e and -pe always require an argument.
3272 if (is_eval == true) {
3273 args_consumed += 1;
3274 eval_string = argv[index + 1];
3275 if (eval_string == nullptr) {
3276 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3277 exit(9);
3278 }
3279 } else if ((index + 1 < nargs) &&
3280 argv[index + 1] != nullptr &&
3281 argv[index + 1][0] != '-') {
3282 args_consumed += 1;
3283 eval_string = argv[index + 1];
3284 if (strncmp(eval_string, "\\-", 2) == 0) {
3285 // Starts with "\\-": escaped expression, drop the backslash.
3286 eval_string += 1;
3287 }
3288 }
3289 } else if (strcmp(arg, "--require") == 0 ||
3290 strcmp(arg, "-r") == 0) {
3291 const char* module = argv[index + 1];
3292 if (module == nullptr) {
3293 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3294 exit(9);
3295 }
3296 args_consumed += 1;
Sam Robertscecdf7c2017-04-05 18:45:523297 preload_modules.push_back(module);
Dave Eddy2e6ece42015-08-17 21:33:133298 } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3299 syntax_check_only = true;
Evan Lucas5b6f5752015-06-01 14:15:103300 } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3301 force_repl = true;
3302 } else if (strcmp(arg, "--no-deprecation") == 0) {
3303 no_deprecation = true;
Jason Ginchereau56e881d2017-03-20 21:55:263304 } else if (strcmp(arg, "--napi-modules") == 0) {
Gabriel Schulhofa8c0a432017-08-18 10:30:053305 // no-op
James M Snellc6656db2016-01-20 19:38:353306 } else if (strcmp(arg, "--no-warnings") == 0) {
3307 no_process_warnings = true;
3308 } else if (strcmp(arg, "--trace-warnings") == 0) {
3309 trace_warnings = true;
James M Snell03e89b32016-12-04 18:38:353310 } else if (strncmp(arg, "--redirect-warnings=", 20) == 0) {
3311 config_warning_file = arg + 20;
Evan Lucas5b6f5752015-06-01 14:15:103312 } else if (strcmp(arg, "--trace-deprecation") == 0) {
3313 trace_deprecation = true;
3314 } else if (strcmp(arg, "--trace-sync-io") == 0) {
3315 trace_sync_io = true;
Andreas Madsen23a39112017-10-19 12:15:083316 } else if (strcmp(arg, "--no-force-async-hooks-checks") == 0) {
3317 no_force_async_hooks_checks = true;
misterpoeba4847e2016-08-05 21:04:253318 } else if (strcmp(arg, "--trace-events-enabled") == 0) {
James M Snell5c27e442018-04-04 01:05:333319 if (trace_enabled_categories.empty())
3320 trace_enabled_categories = "v8,node,node.async_hooks";
misterpoeba4847e2016-08-05 21:04:253321 } else if (strcmp(arg, "--trace-event-categories") == 0) {
3322 const char* categories = argv[index + 1];
3323 if (categories == nullptr) {
3324 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3325 exit(9);
3326 }
3327 args_consumed += 1;
3328 trace_enabled_categories = categories;
Andreas Madsen85212bb2018-01-31 16:12:093329 } else if (strcmp(arg, "--trace-event-file-pattern") == 0) {
3330 const char* file_pattern = argv[index + 1];
3331 if (file_pattern == nullptr) {
3332 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3333 exit(9);
3334 }
3335 args_consumed += 1;
3336 trace_file_pattern = file_pattern;
Bradley Meckcf14a242015-07-09 16:15:263337 } else if (strcmp(arg, "--track-heap-objects") == 0) {
3338 track_heap_objects = true;
Evan Lucas5b6f5752015-06-01 14:15:103339 } else if (strcmp(arg, "--throw-deprecation") == 0) {
3340 throw_deprecation = true;
James M Snelld3875912016-02-04 01:16:103341 } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3342 const char* cve = arg + 18;
3343 Revert(cve);
James M Snell5d38d542016-05-02 23:31:203344 } else if (strcmp(arg, "--preserve-symlinks") == 0) {
3345 config_preserve_symlinks = true;
David Goldstein23659652018-04-10 07:40:563346 } else if (strcmp(arg, "--preserve-symlinks-main") == 0) {
3347 config_preserve_symlinks_main = true;
Bradley Fariasc8a389e2017-06-06 00:44:563348 } else if (strcmp(arg, "--experimental-modules") == 0) {
3349 config_experimental_modules = true;
Myles Borinsba3d55a2018-01-25 22:32:433350 new_v8_argv[new_v8_argc] = "--harmony-dynamic-import";
3351 new_v8_argc += 1;
Michaël Zasso9e1a6f82017-12-24 15:26:243352 new_v8_argv[new_v8_argc] = "--harmony-import-meta";
3353 new_v8_argc += 1;
Gus Caplan0993fbe2018-01-14 07:35:513354 } else if (strcmp(arg, "--experimental-vm-modules") == 0) {
3355 config_experimental_vm_modules = true;
Anna Henningsene7a23672017-09-05 20:38:323356 } else if (strcmp(arg, "--experimental-worker") == 0) {
3357 config_experimental_worker = true;
Timothy Gube92eab2018-03-26 03:13:543358 } else if (strcmp(arg, "--experimental-repl-await") == 0) {
3359 config_experimental_repl_await = true;
guybedfordd21a11d2017-09-03 11:20:063360 } else if (strcmp(arg, "--loader") == 0) {
3361 const char* module = argv[index + 1];
3362 if (!config_experimental_modules) {
3363 fprintf(stderr, "%s: %s requires --experimental-modules be enabled\n",
3364 argv[0], arg);
3365 exit(9);
3366 }
3367 if (module == nullptr) {
3368 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3369 exit(9);
3370 }
3371 args_consumed += 1;
3372 config_userland_loader = module;
Matt Loring49440b72015-11-25 14:08:583373 } else if (strcmp(arg, "--prof-process") == 0) {
3374 prof_process = true;
3375 short_circuit = true;
James M Snell85ab4a52016-01-25 23:00:063376 } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
3377 zero_fill_all_buffers = true;
James M Snella16b5702017-03-11 20:18:533378 } else if (strcmp(arg, "--pending-deprecation") == 0) {
3379 config_pending_deprecation = true;
Evan Lucas5b6f5752015-06-01 14:15:103380 } else if (strcmp(arg, "--v8-options") == 0) {
3381 new_v8_argv[new_v8_argc] = "--help";
3382 new_v8_argc += 1;
Tom Gallacher03e07d32015-12-18 12:24:563383 } else if (strncmp(arg, "--v8-pool-size=", 15) == 0) {
3384 v8_thread_pool_size = atoi(arg + 15);
James M Snell5ba868f2015-08-17 22:51:513385#if HAVE_OPENSSL
3386 } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) {
3387 default_cipher_list = arg + 18;
Adam Majer33012e92016-12-21 10:16:393388 } else if (strncmp(arg, "--use-openssl-ca", 16) == 0) {
3389 ssl_openssl_cert_store = true;
Daniel Bevenius8a7db9d2017-03-28 06:56:393390 use_openssl_ca = true;
Adam Majer33012e92016-12-21 10:16:393391 } else if (strncmp(arg, "--use-bundled-ca", 16) == 0) {
Daniel Bevenius8a7db9d2017-03-28 06:56:393392 use_bundled_ca = true;
Adam Majer33012e92016-12-21 10:16:393393 ssl_openssl_cert_store = false;
Stefan Budeanu7c48cb52016-01-22 23:10:093394#if NODE_FIPS_MODE
3395 } else if (strcmp(arg, "--enable-fips") == 0) {
3396 enable_fips_crypto = true;
3397 } else if (strcmp(arg, "--force-fips") == 0) {
3398 force_fips_crypto = true;
3399#endif /* NODE_FIPS_MODE */
Fedor Indutnydb411cf2016-09-29 08:53:303400 } else if (strncmp(arg, "--openssl-config=", 17) == 0) {
Sam Roberts59afa272017-01-25 22:13:343401 openssl_config.assign(arg + 17);
Stefan Budeanu7c48cb52016-01-22 23:10:093402#endif /* HAVE_OPENSSL */
Evan Lucas5b6f5752015-06-01 14:15:103403#if defined(NODE_HAVE_I18N_SUPPORT)
3404 } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
Ben Noordhuis291b5992017-02-11 13:04:583405 icu_data_dir.assign(arg + 15);
Evan Lucas5b6f5752015-06-01 14:15:103406#endif
3407 } else if (strcmp(arg, "--expose-internals") == 0 ||
3408 strcmp(arg, "--expose_internals") == 0) {
Sam Roberts8086cb62017-04-05 21:06:523409 config_expose_internals = true;
Ebrahim Byagowi594b5d72017-05-13 07:58:183410 } else if (strcmp(arg, "-") == 0) {
3411 break;
John Barboza0a9f3602016-12-30 05:28:383412 } else if (strcmp(arg, "--") == 0) {
3413 index += 1;
3414 break;
Sam Roberts53dae832017-05-12 19:47:473415 } else if (strcmp(arg, "--abort-on-uncaught-exception") == 0 ||
3416 strcmp(arg, "--abort_on_uncaught_exception") == 0) {
Trevor Norrisc0bde732017-03-07 19:40:183417 abort_on_uncaught_exception = true;
3418 // Also a V8 option. Pass through as-is.
3419 new_v8_argv[new_v8_argc] = arg;
3420 new_v8_argc += 1;
Evan Lucas5b6f5752015-06-01 14:15:103421 } else {
3422 // V8 option. Pass through as-is.
3423 new_v8_argv[new_v8_argc] = arg;
3424 new_v8_argc += 1;
3425 }
3426
3427 memcpy(new_exec_argv + new_exec_argc,
3428 argv + index,
3429 args_consumed * sizeof(*argv));
3430
3431 new_exec_argc += args_consumed;
3432 index += args_consumed;
3433 }
3434
Daniel Bevenius8a7db9d2017-03-28 06:56:393435#if HAVE_OPENSSL
3436 if (use_openssl_ca && use_bundled_ca) {
3437 fprintf(stderr,
3438 "%s: either --use-openssl-ca or --use-bundled-ca can be used, "
3439 "not both\n",
3440 argv[0]);
3441 exit(9);
3442 }
3443#endif
3444
Teddy Katza5f91ab2017-03-30 06:35:033445 if (eval_string != nullptr && syntax_check_only) {
3446 fprintf(stderr,
3447 "%s: either --check or --eval can be used, not both\n", argv[0]);
3448 exit(9);
3449 }
3450
Evan Lucas5b6f5752015-06-01 14:15:103451 // Copy remaining arguments.
3452 const unsigned int args_left = nargs - index;
Sam Robertsf2282bb2017-02-20 14:18:433453
3454 if (is_env && args_left) {
3455 fprintf(stderr, "%s: %s is not supported in NODE_OPTIONS\n",
3456 argv[0], argv[index]);
3457 exit(9);
3458 }
3459
Evan Lucas5b6f5752015-06-01 14:15:103460 memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3461 new_argc += args_left;
3462
3463 *exec_argc = new_exec_argc;
3464 *exec_argv = new_exec_argv;
3465 *v8_argc = new_v8_argc;
3466 *v8_argv = new_v8_argv;
3467
3468 // Copy new_argv over argv and update argc.
3469 memcpy(argv, new_argv, new_argc * sizeof(*argv));
3470 delete[] new_argv;
3471 *argc = static_cast<int>(new_argc);
Evan Lucas5b6f5752015-06-01 14:15:103472}
3473
Bert Belder829735e2011-11-04 15:23:023474
Sam Roberts26ab7692017-05-30 23:34:593475static void StartInspector(Environment* env, const char* path,
3476 DebugOptions debug_options) {
Eugene Ostroukhov7599b0e2016-12-13 01:08:313477#if HAVE_INSPECTOR
Eugene Ostroukhov5c263782017-05-01 20:31:143478 CHECK(!env->inspector_agent()->IsStarted());
3479 v8_platform.StartInspector(env, path, debug_options);
Eugene Ostroukhov7599b0e2016-12-13 01:08:313480#endif // HAVE_INSPECTOR
Ryan Dahl2a7e7b12010-12-18 19:17:293481}
3482
3483
Fedor Indutny82d0ac72011-09-24 13:51:593484#ifdef __POSIX__
Anna Henningsen0815b942016-05-08 01:28:473485void RegisterSignalHandler(int signal,
3486 void (*handler)(int signal),
3487 bool reset_handler) {
Tom Hughesf61b1102010-10-12 21:01:583488 struct sigaction sa;
Tom Hughesf61b1102010-10-12 21:01:583489 memset(&sa, 0, sizeof(sa));
3490 sa.sa_handler = handler;
Fedor Indutnyb64983d2015-03-20 05:03:343491#ifndef __FreeBSD__
3492 // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
3493 // in turn set for a libthr wrapper. This leads to a crash.
3494 // Work around the issue by manually setting SIG_DFL in the signal handler
Geir Haugec61b0e92014-03-31 07:52:033495 sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
Fedor Indutnyb64983d2015-03-20 05:03:343496#endif
Tom Hughesf61b1102010-10-12 21:01:583497 sigfillset(&sa.sa_mask);
Ben Noordhuis2d82cdf2014-10-22 01:29:323498 CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
Bert Belder829735e2011-11-04 15:23:023499}
3500
3501
Ben Noordhuis110a9cd2013-07-03 02:23:443502void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553503 Environment* env = Environment::GetCurrent(args);
Bert Belder829735e2011-11-04 15:23:023504
3505 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423506 return env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023507 }
3508
3509 pid_t pid;
3510 int r;
3511
3512 pid = args[0]->IntegerValue();
3513 r = kill(pid, SIGUSR1);
3514 if (r != 0) {
Fedor Indutny75adde02014-02-21 13:02:423515 return env->ThrowErrnoException(errno, "kill");
Bert Belder829735e2011-11-04 15:23:023516 }
Tom Hughesf61b1102010-10-12 21:01:583517}
Fedor Indutny8e29ce92013-07-31 18:07:293518#endif // __POSIX__
Tom Hughesf61b1102010-10-12 21:01:583519
3520
Bert Belder829735e2011-11-04 15:23:023521#ifdef _WIN32
Bert Belder8f2694b2012-02-16 21:19:483522static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
3523 size_t buf_len) {
3524 return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
Bert Belder829735e2011-11-04 15:23:023525}
3526
3527
Ben Noordhuis110a9cd2013-07-03 02:23:443528static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553529 Environment* env = Environment::GetCurrent(args);
Alexis Campailla440b9e22014-02-24 18:55:273530 Isolate* isolate = args.GetIsolate();
Bert Belder829735e2011-11-04 15:23:023531 DWORD pid;
Ben Noordhuis2d82cdf2014-10-22 01:29:323532 HANDLE process = nullptr;
3533 HANDLE thread = nullptr;
3534 HANDLE mapping = nullptr;
Bert Belder8f2694b2012-02-16 21:19:483535 wchar_t mapping_name[32];
Ben Noordhuis2d82cdf2014-10-22 01:29:323536 LPTHREAD_START_ROUTINE* handler = nullptr;
Bert Belder829735e2011-11-04 15:23:023537
3538 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423539 env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023540 goto out;
3541 }
3542
3543 pid = (DWORD) args[0]->IntegerValue();
3544
Bert Belder68db2062012-02-03 14:37:463545 process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
Bert Belder829735e2011-11-04 15:23:023546 PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
3547 PROCESS_VM_READ,
3548 FALSE,
3549 pid);
Ben Noordhuis2d82cdf2014-10-22 01:29:323550 if (process == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273551 isolate->ThrowException(
3552 WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
Bert Belder829735e2011-11-04 15:23:023553 goto out;
3554 }
3555
3556 if (GetDebugSignalHandlerMappingName(pid,
3557 mapping_name,
Ben Noordhuisa7581d02016-03-31 10:47:063558 arraysize(mapping_name)) < 0) {
Fedor Indutny75adde02014-02-21 13:02:423559 env->ThrowErrnoException(errno, "sprintf");
Bert Belder829735e2011-11-04 15:23:023560 goto out;
3561 }
3562
Bert Belder8f2694b2012-02-16 21:19:483563 mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
Ben Noordhuis2d82cdf2014-10-22 01:29:323564 if (mapping == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273565 isolate->ThrowException(WinapiErrnoException(isolate,
Fedor Indutny75adde02014-02-21 13:02:423566 GetLastError(),
3567 "OpenFileMappingW"));
Bert Belder829735e2011-11-04 15:23:023568 goto out;
3569 }
3570
Bert Belder8f2694b2012-02-16 21:19:483571 handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
3572 MapViewOfFile(mapping,
3573 FILE_MAP_READ,
3574 0,
3575 0,
3576 sizeof *handler));
Ben Noordhuis2d82cdf2014-10-22 01:29:323577 if (handler == nullptr || *handler == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273578 isolate->ThrowException(
3579 WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
Bert Belder829735e2011-11-04 15:23:023580 goto out;
3581 }
3582
Bert Belder68db2062012-02-03 14:37:463583 thread = CreateRemoteThread(process,
Ben Noordhuis2d82cdf2014-10-22 01:29:323584 nullptr,
Bert Belder829735e2011-11-04 15:23:023585 0,
3586 *handler,
Ben Noordhuis2d82cdf2014-10-22 01:29:323587 nullptr,
Bert Belder829735e2011-11-04 15:23:023588 0,
Ben Noordhuis2d82cdf2014-10-22 01:29:323589 nullptr);
3590 if (thread == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273591 isolate->ThrowException(WinapiErrnoException(isolate,
3592 GetLastError(),
3593 "CreateRemoteThread"));
Bert Belder829735e2011-11-04 15:23:023594 goto out;
3595 }
3596
3597 // Wait for the thread to terminate
3598 if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
Alexis Campailla440b9e22014-02-24 18:55:273599 isolate->ThrowException(WinapiErrnoException(isolate,
3600 GetLastError(),
3601 "WaitForSingleObject"));
Bert Belder829735e2011-11-04 15:23:023602 goto out;
3603 }
3604
3605 out:
Ben Noordhuis2d82cdf2014-10-22 01:29:323606 if (process != nullptr)
Fedor Indutny8e29ce92013-07-31 18:07:293607 CloseHandle(process);
Ben Noordhuis2d82cdf2014-10-22 01:29:323608 if (thread != nullptr)
Bert Belder829735e2011-11-04 15:23:023609 CloseHandle(thread);
Ben Noordhuis2d82cdf2014-10-22 01:29:323610 if (handler != nullptr)
Bert Belder829735e2011-11-04 15:23:023611 UnmapViewOfFile(handler);
Ben Noordhuis2d82cdf2014-10-22 01:29:323612 if (mapping != nullptr)
Bert Belder829735e2011-11-04 15:23:023613 CloseHandle(mapping);
Bert Belder829735e2011-11-04 15:23:023614}
Fedor Indutny8e29ce92013-07-31 18:07:293615#endif // _WIN32
Bert Belder829735e2011-11-04 15:23:023616
3617
Ben Noordhuis110a9cd2013-07-03 02:23:443618static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
Michaël Zasso719247f2017-04-24 13:35:563619#if HAVE_INSPECTOR
Eugene Ostroukhov5c263782017-05-01 20:31:143620 Environment* env = Environment::GetCurrent(args);
3621 if (env->inspector_agent()->IsStarted()) {
Michaël Zasso719247f2017-04-24 13:35:563622 env->inspector_agent()->Stop();
Fedor Indutny3f43b1c2012-02-12 15:53:433623 }
Eugene Ostroukhov5c263782017-05-01 20:31:143624#endif
Fedor Indutny3f43b1c2012-02-12 15:53:433625}
3626
3627
Ben Noordhuis5756f922015-01-26 22:15:203628inline void PlatformInit() {
3629#ifdef __POSIX__
Daniel Bevenius65a6e052017-04-07 06:48:323630#if HAVE_INSPECTOR
Ben Noordhuis63ae1d22015-01-26 22:26:333631 sigset_t sigmask;
3632 sigemptyset(&sigmask);
3633 sigaddset(&sigmask, SIGUSR1);
Ben Noordhuisb5f25a92015-02-18 02:43:293634 const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
Daniel Bevenius65a6e052017-04-07 06:48:323635#endif // HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:293636
3637 // Make sure file descriptors 0-2 are valid before we start logging anything.
Evan Lucas14dc17d2018-06-11 14:20:503638 for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
3639 struct stat ignored;
3640 if (fstat(fd, &ignored) == 0)
Ben Noordhuisb5f25a92015-02-18 02:43:293641 continue;
3642 // Anything but EBADF means something is seriously wrong. We don't
3643 // have to special-case EINTR, fstat() is not interruptible.
3644 if (errno != EBADF)
Evan Lucas870229e2015-09-16 15:12:413645 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:293646 if (fd != open("/dev/null", O_RDWR))
Evan Lucas870229e2015-09-16 15:12:413647 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:293648 }
3649
Daniel Bevenius65a6e052017-04-07 06:48:323650#if HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:293651 CHECK_EQ(err, 0);
Daniel Bevenius65a6e052017-04-07 06:48:323652#endif // HAVE_INSPECTOR
Ben Noordhuisdd47a8c2015-01-26 23:07:343653
Stewart X Addison0f0f3d32016-12-30 12:44:463654#ifndef NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:343655 // Restore signal dispositions, the parent process may have changed them.
3656 struct sigaction act;
3657 memset(&act, 0, sizeof(act));
3658
3659 // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
3660 // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
3661 // Counting up to SIGRTMIN doesn't work for the same reason.
Eugene Ostroukhov66269192016-06-08 21:09:283662 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
Ben Noordhuisdd47a8c2015-01-26 23:07:343663 if (nr == SIGKILL || nr == SIGSTOP)
3664 continue;
3665 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
3666 CHECK_EQ(0, sigaction(nr, &act, nullptr));
3667 }
Stewart X Addison0f0f3d32016-12-30 12:44:463668#endif // !NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:343669
Ben Noordhuis63ae1d22015-01-26 22:26:333670 RegisterSignalHandler(SIGINT, SignalExit, true);
3671 RegisterSignalHandler(SIGTERM, SignalExit, true);
Ben Noordhuisdd47a8c2015-01-26 23:07:343672
Ben Noordhuis5756f922015-01-26 22:15:203673 // Raise the open file descriptor limit.
3674 struct rlimit lim;
3675 if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
3676 // Do a binary search for the limit.
3677 rlim_t min = lim.rlim_cur;
3678 rlim_t max = 1 << 20;
3679 // But if there's a defined upper bound, don't search, just set it.
3680 if (lim.rlim_max != RLIM_INFINITY) {
3681 min = lim.rlim_max;
3682 max = lim.rlim_max;
3683 }
3684 do {
3685 lim.rlim_cur = min + (max - min) / 2;
3686 if (setrlimit(RLIMIT_NOFILE, &lim)) {
3687 max = lim.rlim_cur;
3688 } else {
3689 min = lim.rlim_cur;
3690 }
3691 } while (min + 1 < max);
3692 }
Ben Noordhuis5756f922015-01-26 22:15:203693#endif // __POSIX__
Bartosz Sosnowskibd496e02017-03-14 17:22:533694#ifdef _WIN32
3695 for (int fd = 0; fd <= 2; ++fd) {
3696 auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
3697 if (handle == INVALID_HANDLE_VALUE ||
3698 GetFileType(handle) == FILE_TYPE_UNKNOWN) {
3699 // Ignore _close result. If it fails or not depends on used Windows
3700 // version. We will just check _open result.
3701 _close(fd);
3702 if (fd != _open("nul", _O_RDWR))
3703 ABORT();
3704 }
3705 }
3706#endif // _WIN32
Ben Noordhuis5756f922015-01-26 22:15:203707}
3708
3709
Sam Robertsf2282bb2017-02-20 14:18:433710void ProcessArgv(int* argc,
3711 const char** argv,
3712 int* exec_argc,
3713 const char*** exec_argv,
3714 bool is_env = false) {
3715 // Parse a few arguments which are specific to Node.
3716 int v8_argc;
3717 const char** v8_argv;
3718 ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv, is_env);
3719
3720 // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
3721 // manually? That would give us a little more control over its runtime
3722 // behavior but it could also interfere with the user's intentions in ways
3723 // we fail to anticipate. Dillema.
3724 for (int i = 1; i < v8_argc; ++i) {
3725 if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
3726 v8_is_profiling = true;
3727 break;
3728 }
3729 }
3730
3731#ifdef __POSIX__
3732 // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the
3733 // performance penalty of frequent EINTR wakeups when the profiler is running.
3734 // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
3735 if (v8_is_profiling) {
3736 uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
3737 }
3738#endif
3739
3740 // The const_cast doesn't violate conceptual const-ness. V8 doesn't modify
3741 // the argv array or the elements it points to.
3742 if (v8_argc > 1)
3743 V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
3744
3745 // Anything that's still in v8_argv is not a V8 or a node option.
3746 for (int i = 1; i < v8_argc; i++) {
3747 fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
3748 }
3749 delete[] v8_argv;
3750 v8_argv = nullptr;
3751
3752 if (v8_argc > 1) {
3753 exit(9);
3754 }
3755}
3756
3757
Ben Noordhuis185c5152013-09-02 14:42:013758void Init(int* argc,
3759 const char** argv,
3760 int* exec_argc,
3761 const char*** exec_argv) {
Ben Noordhuis74a82152012-02-03 15:32:003762 // Initialize prog_start_time to get relative uptime.
Rasmus Christian Pedersen734fb492014-09-18 12:10:533763 prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
Ben Noordhuis74a82152012-02-03 15:32:003764
Yihong Wang8680bb92017-10-22 06:16:503765 // Register built-in modules
Daniel Beveniuscae41822018-02-23 14:42:203766 RegisterBuiltinModules();
Yihong Wang8680bb92017-10-22 06:16:503767
Bert Belder09be3602012-06-13 23:28:513768 // Make inherited handles noninheritable.
3769 uv_disable_stdio_inheritance();
3770
Ben Noordhuis490d5ab2014-03-31 12:22:493771#if defined(NODE_V8_OPTIONS)
3772 // Should come before the call to V8::SetFlagsFromCommandLine()
3773 // so the user can disable a flag --foo at run-time by passing
3774 // --no_foo from the command line.
3775 V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
3776#endif
Fedor Indutnyb55c9d62014-03-26 20:30:493777
James M Snella16b5702017-03-11 20:18:533778 {
3779 std::string text;
3780 config_pending_deprecation =
3781 SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1';
3782 }
3783
Marc Udoffd3b1a2b2016-09-20 22:21:443784 // Allow for environment set preserving symlinks.
Ben Noordhuisa8734af2017-01-28 12:27:023785 {
3786 std::string text;
3787 config_preserve_symlinks =
3788 SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
Marc Udoffd3b1a2b2016-09-20 22:21:443789 }
3790
David Goldstein23659652018-04-10 07:40:563791 {
3792 std::string text;
3793 config_preserve_symlinks_main =
3794 SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) && text[0] == '1';
3795 }
3796
Ben Noordhuisa8734af2017-01-28 12:27:023797 if (config_warning_file.empty())
3798 SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file);
James M Snell03e89b32016-12-04 18:38:353799
Daniel Beveniuse1d88992017-02-28 19:04:123800#if HAVE_OPENSSL
Sam Roberts59afa272017-01-25 22:13:343801 if (openssl_config.empty())
3802 SafeGetenv("OPENSSL_CONF", &openssl_config);
Daniel Beveniuse1d88992017-02-28 19:04:123803#endif
Sam Roberts59afa272017-01-25 22:13:343804
Sam Robertsf2282bb2017-02-20 14:18:433805#if !defined(NODE_WITHOUT_NODE_OPTIONS)
3806 std::string node_options;
3807 if (SafeGetenv("NODE_OPTIONS", &node_options)) {
3808 // Smallest tokens are 2-chars (a not space and a space), plus 2 extra
3809 // pointers, for the prepended executable name, and appended NULL pointer.
3810 size_t max_len = 2 + (node_options.length() + 1) / 2;
3811 const char** argv_from_env = new const char*[max_len];
3812 int argc_from_env = 0;
3813 // [0] is expected to be the program name, fill it in from the real argv.
3814 argv_from_env[argc_from_env++] = argv[0];
Evan Lucas5b6f5752015-06-01 14:15:103815
Sam Robertsf2282bb2017-02-20 14:18:433816 char* cstr = strdup(node_options.c_str());
3817 char* initptr = cstr;
3818 char* token;
3819 while ((token = strtok(initptr, " "))) { // NOLINT(runtime/threadsafe_fn)
3820 initptr = nullptr;
3821 argv_from_env[argc_from_env++] = token;
Ben Noordhuis9566fe82013-10-03 08:45:323822 }
Sam Robertsf2282bb2017-02-20 14:18:433823 argv_from_env[argc_from_env] = nullptr;
3824 int exec_argc_;
3825 const char** exec_argv_ = nullptr;
3826 ProcessArgv(&argc_from_env, argv_from_env, &exec_argc_, &exec_argv_, true);
3827 delete[] exec_argv_;
3828 delete[] argv_from_env;
3829 free(cstr);
Oleksandr Chekhovskyi8e141352015-08-07 13:03:043830 }
3831#endif
3832
Sam Robertsf2282bb2017-02-20 14:18:433833 ProcessArgv(argc, argv, exec_argc, exec_argv);
3834
Steven R. Loomisac2857b2014-09-05 05:03:243835#if defined(NODE_HAVE_I18N_SUPPORT)
Ben Noordhuisa8734af2017-01-28 12:27:023836 // If the parameter isn't given, use the env variable.
3837 if (icu_data_dir.empty())
3838 SafeGetenv("NODE_ICU_DATA", &icu_data_dir);
Steven R. Loomisac2857b2014-09-05 05:03:243839 // Initialize ICU.
Ben Noordhuisa8734af2017-01-28 12:27:023840 // If icu_data_dir is empty here, it will load the 'minimal' data.
Steven R. Loomisac2857b2014-09-05 05:03:243841 if (!i18n::InitializeICUDirectory(icu_data_dir)) {
Ben Noordhuis46e773c2017-05-16 13:15:143842 fprintf(stderr,
3843 "%s: could not initialize ICU "
Timothy Gu93308352017-06-26 03:59:443844 "(check NODE_ICU_DATA or --icu-data-dir parameters)\n",
Ben Noordhuis46e773c2017-05-16 13:15:143845 argv[0]);
3846 exit(9);
Steven R. Loomisac2857b2014-09-05 05:03:243847 }
3848#endif
Tom Hughes78da9cb2010-10-18 22:50:563849
Cheng Zhao22e1aea2015-01-12 21:31:253850 // We should set node_is_initialized here instead of in node::Start,
3851 // otherwise embedders using node::Init to initialize everything will not be
3852 // able to set it and native modules will not load for them.
3853 node_is_initialized = true;
Ben Noordhuis5866f1a2011-12-09 18:02:333854}
Ben Noordhuis356992f2011-11-22 16:10:093855
Ben Noordhuis5866f1a2011-12-09 18:02:333856
Ben Noordhuis756b6222013-08-10 22:26:113857void RunAtExit(Environment* env) {
Daniel Beveniusec539212017-03-21 07:06:433858 env->RunAtExitCallbacks();
Ben Noordhuise4a8d262012-04-21 05:13:253859}
3860
3861
Anna Henningsenc0f3bc22017-11-17 21:13:183862uv_loop_t* GetCurrentEventLoop(v8::Isolate* isolate) {
3863 HandleScope handle_scope(isolate);
3864 auto context = isolate->GetCurrentContext();
3865 if (context.IsEmpty())
3866 return nullptr;
3867 return Environment::GetCurrent(context)->event_loop();
3868}
3869
3870
Ben Noordhuise4a8d262012-04-21 05:13:253871void AtExit(void (*cb)(void* arg), void* arg) {
Daniel Bevenius42c14c52018-02-05 10:20:073872 auto env = Environment::GetThreadLocalEnv();
Daniel Beveniusec539212017-03-21 07:06:433873 AtExit(env, cb, arg);
3874}
3875
3876
3877void AtExit(Environment* env, void (*cb)(void* arg), void* arg) {
Tobias Nießen39f20962018-05-20 15:44:063878 CHECK_NOT_NULL(env);
Daniel Beveniusec539212017-03-21 07:06:433879 env->AtExit(cb, arg);
Ben Noordhuise4a8d262012-04-21 05:13:253880}
3881
3882
Anatoli Papirovski8803b692018-01-18 21:52:513883void RunBeforeExit(Environment* env) {
3884 env->RunBeforeExitCallbacks();
3885
3886 if (!uv_loop_alive(env->event_loop()))
3887 EmitBeforeExit(env);
3888}
3889
3890
Ben Noordhuisa2eeb432013-10-07 13:39:393891void EmitBeforeExit(Environment* env) {
Ben Noordhuisa2eeb432013-10-07 13:39:393892 HandleScope handle_scope(env->isolate());
Fedor Indutnye2c90402015-03-12 21:19:163893 Context::Scope context_scope(env->context());
Ben Noordhuisa2eeb432013-10-07 13:39:393894 Local<Object> process_object = env->process_object();
James M Snell9459dfa2018-06-03 14:28:293895 Local<String> exit_code = env->exit_code_string();
Ben Noordhuisa2eeb432013-10-07 13:39:393896 Local<Value> args[] = {
3897 FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
James M Snell9459dfa2018-06-03 14:28:293898 process_object->Get(env->context(), exit_code).ToLocalChecked()
3899 ->ToInteger(env->context()).ToLocalChecked()
Ben Noordhuisa2eeb432013-10-07 13:39:393900 };
Anna Henningsena86323d2017-05-21 17:39:523901 MakeCallback(env->isolate(),
3902 process_object, "emit", arraysize(args), args,
Andreas Madsenc6ce5002017-07-06 06:20:033903 {0, 0}).ToLocalChecked();
Ben Noordhuisa2eeb432013-10-07 13:39:393904}
3905
3906
Fedor Indutnye57ab7b2014-01-18 22:49:333907int EmitExit(Environment* env) {
Ben Noordhuis5866f1a2011-12-09 18:02:333908 // process.emit('exit')
Ben Noordhuis756b6222013-08-10 22:26:113909 HandleScope handle_scope(env->isolate());
Ben Noordhuis27f115d2013-11-11 09:53:003910 Context::Scope context_scope(env->context());
Ben Noordhuis756b6222013-08-10 22:26:113911 Local<Object> process_object = env->process_object();
James M Snell9459dfa2018-06-03 14:28:293912 process_object->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "_exiting"),
3913 True(env->isolate()));
isaacsa5dba822013-09-06 23:46:353914
James M Snell9459dfa2018-06-03 14:28:293915 Local<String> exit_code = env->exit_code_string();
3916 int code = process_object->Get(env->context(), exit_code).ToLocalChecked()
3917 ->Int32Value(env->context()).ToChecked();
isaacsa5dba822013-09-06 23:46:353918
Ben Noordhuisf674b092013-08-07 19:50:413919 Local<Value> args[] = {
James M Snell9459dfa2018-06-03 14:28:293920 FIXED_ONE_BYTE_STRING(env->isolate(), "exit"),
Fedor Indutnyce04c722014-03-13 16:38:143921 Integer::New(env->isolate(), code)
Ben Noordhuisf674b092013-08-07 19:50:413922 };
isaacsa5dba822013-09-06 23:46:353923
Anna Henningsena86323d2017-05-21 17:39:523924 MakeCallback(env->isolate(),
3925 process_object, "emit", arraysize(args), args,
Andreas Madsenc6ce5002017-07-06 06:20:033926 {0, 0}).ToLocalChecked();
Fedor Indutnyc0d81f92014-02-09 10:40:573927
3928 // Reload exit code, it may be changed by `emit('exit')`
James M Snell9459dfa2018-06-03 14:28:293929 return process_object->Get(env->context(), exit_code).ToLocalChecked()
3930 ->Int32Value(env->context()).ToChecked();
Ben Noordhuis756b6222013-08-10 22:26:113931}
3932
3933
helloshuangzi963cb3a2018-05-11 18:06:053934ArrayBufferAllocator* CreateArrayBufferAllocator() {
3935 return new ArrayBufferAllocator();
3936}
3937
3938
3939void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator) {
3940 delete allocator;
3941}
3942
3943
Ben Noordhuisc3cd4532016-05-31 14:42:523944IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) {
Anna Henningsenc7ad7292017-09-14 11:05:483945 return new IsolateData(isolate, loop, nullptr);
3946}
3947
helloshuangzi963cb3a2018-05-11 18:06:053948
Anna Henningsenc7ad7292017-09-14 11:05:483949IsolateData* CreateIsolateData(
3950 Isolate* isolate,
3951 uv_loop_t* loop,
3952 MultiIsolatePlatform* platform) {
3953 return new IsolateData(isolate, loop, platform);
Ben Noordhuisc3cd4532016-05-31 14:42:523954}
3955
3956
helloshuangzi963cb3a2018-05-11 18:06:053957IsolateData* CreateIsolateData(
3958 Isolate* isolate,
3959 uv_loop_t* loop,
3960 MultiIsolatePlatform* platform,
3961 ArrayBufferAllocator* allocator) {
3962 return new IsolateData(isolate, loop, platform, allocator->zero_fill_field());
3963}
3964
3965
Ben Noordhuisc3cd4532016-05-31 14:42:523966void FreeIsolateData(IsolateData* isolate_data) {
3967 delete isolate_data;
3968}
3969
3970
3971Environment* CreateEnvironment(IsolateData* isolate_data,
Michaël Zasso4abc8962015-07-18 09:34:163972 Local<Context> context,
Fedor Indutny6a610a02014-10-04 14:44:393973 int argc,
3974 const char* const* argv,
3975 int exec_argc,
3976 const char* const* exec_argv) {
Ben Noordhuisc3cd4532016-05-31 14:42:523977 Isolate* isolate = context->GetIsolate();
Ben Noordhuis756b6222013-08-10 22:26:113978 HandleScope handle_scope(isolate);
Ben Noordhuis756b6222013-08-10 22:26:113979 Context::Scope context_scope(context);
James M Snell5c27e442018-04-04 01:05:333980 auto env = new Environment(isolate_data, context,
3981 v8_platform.GetTracingAgent());
Ben Noordhuis58cec4e2016-06-01 08:54:423982 env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
Ben Noordhuis756b6222013-08-10 22:26:113983 return env;
Ben Noordhuis5866f1a2011-12-09 18:02:333984}
3985
Micheil Smith19fd5302012-03-05 17:53:153986
Ben Noordhuisaac79df2016-06-01 09:18:023987void FreeEnvironment(Environment* env) {
Anna Henningsen5c6cf302017-09-09 20:28:023988 env->RunCleanup();
Ben Noordhuisaac79df2016-06-01 09:18:023989 delete env;
3990}
3991
3992
Allen Yonghuang Wangb00c34c2018-05-01 00:34:053993MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform() {
3994 return v8_platform.Platform();
3995}
3996
3997
Cheng Zhao27281122017-11-13 02:41:203998MultiIsolatePlatform* CreatePlatform(
3999 int thread_pool_size,
4000 v8::TracingController* tracing_controller) {
4001 return new NodePlatform(thread_pool_size, tracing_controller);
4002}
4003
4004
4005void FreePlatform(MultiIsolatePlatform* platform) {
4006 delete platform;
4007}
4008
4009
Ben Noordhuis668ad442017-09-07 11:26:474010Local<Context> NewContext(Isolate* isolate,
4011 Local<ObjectTemplate> object_template) {
4012 auto context = Context::New(isolate, nullptr, object_template);
4013 if (context.IsEmpty()) return context;
4014 HandleScope handle_scope(isolate);
4015 auto intl_key = FIXED_ONE_BYTE_STRING(isolate, "Intl");
4016 auto break_iter_key = FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
Gus Caplancb5f3582018-02-26 20:29:414017 context->SetEmbedderData(
4018 ContextEmbedderIndex::kAllowWasmCodeGeneration, True(isolate));
Ben Noordhuis668ad442017-09-07 11:26:474019 Local<Value> intl_v;
Ben Noordhuis668ad442017-09-07 11:26:474020 if (context->Global()->Get(context, intl_key).ToLocal(&intl_v) &&
Timothy Gu2146c88b2017-10-17 05:29:414021 intl_v->IsObject()) {
4022 Local<Object> intl = intl_v.As<Object>();
Ben Noordhuis668ad442017-09-07 11:26:474023 intl->Delete(context, break_iter_key).FromJust();
4024 }
4025 return context;
4026}
4027
4028
Ben Noordhuisceb60232016-10-21 12:24:484029inline int Start(Isolate* isolate, IsolateData* isolate_data,
4030 int argc, const char* const* argv,
4031 int exec_argc, const char* const* exec_argv) {
4032 HandleScope handle_scope(isolate);
Ben Noordhuis668ad442017-09-07 11:26:474033 Local<Context> context = NewContext(isolate);
Ben Noordhuisceb60232016-10-21 12:24:484034 Context::Scope context_scope(context);
James M Snell5c27e442018-04-04 01:05:334035 Environment env(isolate_data, context, v8_platform.GetTracingAgent());
Ben Noordhuisceb60232016-10-21 12:24:484036 env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4037
James M Snelle60eed12018-05-20 16:07:374038 TRACE_EVENT_METADATA1("__metadata", "version", "node", NODE_VERSION_STRING);
Ali Ijaz Sheikh3ff723f2018-05-15 18:52:184039 TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
4040 "JavaScriptMainThread");
4041
Eugene Ostroukhov7599b0e2016-12-13 01:08:314042 const char* path = argc > 1 ? argv[1] : nullptr;
Sam Roberts26ab7692017-05-30 23:34:594043 StartInspector(&env, path, debug_options);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:224044
Eugene Ostroukhov5c263782017-05-01 20:31:144045 if (debug_options.inspector_enabled() && !v8_platform.InspectorStarted(&env))
Eugene Ostroukhov7599b0e2016-12-13 01:08:314046 return 12; // Signal internal error.
Ben Noordhuisceb60232016-10-21 12:24:484047
Trevor Norrisc0bde732017-03-07 19:40:184048 env.set_abort_on_uncaught_exception(abort_on_uncaught_exception);
4049
Andreas Madsen23a39112017-10-19 12:15:084050 if (no_force_async_hooks_checks) {
4051 env.async_hooks()->no_force_checks();
Andreas Madsen7c079d12017-10-19 10:43:404052 }
4053
Ben Noordhuisceb60232016-10-21 12:24:484054 {
4055 Environment::AsyncCallbackScope callback_scope(&env);
Andreas Madsen3a69ef52017-09-26 13:50:104056 env.async_hooks()->push_async_ids(1, 0);
Ben Noordhuisceb60232016-10-21 12:24:484057 LoadEnvironment(&env);
Andreas Madsen3a69ef52017-09-26 13:50:104058 env.async_hooks()->pop_async_id(1);
Ben Noordhuisceb60232016-10-21 12:24:484059 }
4060
4061 env.set_trace_sync_io(trace_sync_io);
4062
Ben Noordhuisceb60232016-10-21 12:24:484063 {
4064 SealHandleScope seal(isolate);
4065 bool more;
James M Snell96cb4fb2018-03-06 18:42:374066 env.performance_state()->Mark(
4067 node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
Ben Noordhuisceb60232016-10-21 12:24:484068 do {
Matt Loring9e086952017-03-13 22:17:574069 uv_run(env.event_loop(), UV_RUN_DEFAULT);
Ben Noordhuisceb60232016-10-21 12:24:484070
Anna Henningsenc7ad7292017-09-14 11:05:484071 v8_platform.DrainVMTasks(isolate);
Anna Henningsenf27b5e42017-09-15 13:03:484072
4073 more = uv_loop_alive(env.event_loop());
4074 if (more)
4075 continue;
4076
Anatoli Papirovski8803b692018-01-18 21:52:514077 RunBeforeExit(&env);
Ben Noordhuisceb60232016-10-21 12:24:484078
Matt Loring9e086952017-03-13 22:17:574079 // Emit `beforeExit` if the loop became alive either after emitting
4080 // event, or after running some callbacks.
4081 more = uv_loop_alive(env.event_loop());
Ben Noordhuisceb60232016-10-21 12:24:484082 } while (more == true);
James M Snell96cb4fb2018-03-06 18:42:374083 env.performance_state()->Mark(
4084 node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
Ben Noordhuisceb60232016-10-21 12:24:484085 }
4086
4087 env.set_trace_sync_io(false);
4088
4089 const int exit_code = EmitExit(&env);
Anna Henningsen5c6cf302017-09-09 20:28:024090
Anna Henningsen61fd0272017-09-09 20:29:084091 WaitForInspectorDisconnect(&env);
4092
Anna Henningsenbcb324c2017-09-20 12:43:194093 env.set_can_call_into_js(false);
Anna Henningsen0df031a2017-09-01 15:03:414094 env.stop_sub_worker_contexts();
Anna Henningsen43fd1d72018-05-30 09:18:434095 uv_tty_reset_mode();
Anna Henningsen5c6cf302017-09-09 20:28:024096 env.RunCleanup();
Ben Noordhuisceb60232016-10-21 12:24:484097 RunAtExit(&env);
Ben Noordhuisceb60232016-10-21 12:24:484098
Anna Henningsenc7ad7292017-09-14 11:05:484099 v8_platform.DrainVMTasks(isolate);
Anna Henningsen2cedff92017-10-22 22:52:554100 v8_platform.CancelVMTasks(isolate);
Ben Noordhuisceb60232016-10-21 12:24:484101#if defined(LEAK_SANITIZER)
4102 __lsan_do_leak_check();
4103#endif
4104
4105 return exit_code;
4106}
4107
Gus Caplancb5f3582018-02-26 20:29:414108bool AllowWasmCodeGenerationCallback(
4109 Local<Context> context, Local<String>) {
4110 Local<Value> wasm_code_gen =
4111 context->GetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration);
4112 return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
4113}
4114
helloshuangzi963cb3a2018-05-11 18:06:054115Isolate* NewIsolate(ArrayBufferAllocator* allocator) {
Ben Noordhuis9a03ae62015-07-01 21:47:374116 Isolate::CreateParams params;
helloshuangzi963cb3a2018-05-11 18:06:054117 params.array_buffer_allocator = allocator;
Chunyang Daia881b532015-10-21 16:24:124118#ifdef NODE_ENABLE_VTUNE_PROFILING
4119 params.code_event_handler = vTune::GetVtuneCodeEventHandler();
4120#endif
Ben Noordhuisceb60232016-10-21 12:24:484121
helloshuangzi963cb3a2018-05-11 18:06:054122 Isolate* isolate = Isolate::New(params);
Ben Noordhuisceb60232016-10-21 12:24:484123 if (isolate == nullptr)
helloshuangzi963cb3a2018-05-11 18:06:054124 return nullptr;
Ben Noordhuisceb60232016-10-21 12:24:484125
4126 isolate->AddMessageListener(OnMessage);
4127 isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
Michaël Zassoa16081c2018-02-13 08:23:494128 isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
Ben Noordhuisceb60232016-10-21 12:24:484129 isolate->SetFatalErrorHandler(OnFatalError);
Gus Caplancb5f3582018-02-26 20:29:414130 isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback);
Ben Noordhuisceb60232016-10-21 12:24:484131
helloshuangzi963cb3a2018-05-11 18:06:054132 return isolate;
4133}
4134
4135inline int Start(uv_loop_t* event_loop,
4136 int argc, const char* const* argv,
4137 int exec_argc, const char* const* exec_argv) {
4138 std::unique_ptr<ArrayBufferAllocator, decltype(&FreeArrayBufferAllocator)>
4139 allocator(CreateArrayBufferAllocator(), &FreeArrayBufferAllocator);
4140 Isolate* const isolate = NewIsolate(allocator.get());
4141 if (isolate == nullptr)
4142 return 12; // Signal internal error.
4143
Ben Noordhuisd7087df2016-06-17 23:39:054144 {
4145 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Tobias Nießen39f20962018-05-20 15:44:064146 CHECK_NULL(node_isolate);
Ben Noordhuisd77e8182016-10-21 11:47:494147 node_isolate = isolate;
Ben Noordhuis844f0a92016-03-25 16:59:074148 }
Ben Noordhuis844f0a92016-03-25 16:59:074149
Ben Noordhuisd77e8182016-10-21 11:47:494150 int exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474151 {
4152 Locker locker(isolate);
4153 Isolate::Scope isolate_scope(isolate);
4154 HandleScope handle_scope(isolate);
helloshuangzi963cb3a2018-05-11 18:06:054155 std::unique_ptr<IsolateData, decltype(&FreeIsolateData)> isolate_data(
4156 CreateIsolateData(
4157 isolate,
4158 event_loop,
4159 v8_platform.Platform(),
4160 allocator.get()),
4161 &FreeIsolateData);
Hannes Payer91d13122017-11-22 13:43:424162 if (track_heap_objects) {
4163 isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
4164 }
helloshuangzi963cb3a2018-05-11 18:06:054165 exit_code =
4166 Start(isolate, isolate_data.get(), argc, argv, exec_argc, exec_argv);
Petka Antonov4ae64b22015-03-03 20:25:474167 }
4168
Ben Noordhuisd7087df2016-06-17 23:39:054169 {
4170 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuisceb60232016-10-21 12:24:484171 CHECK_EQ(node_isolate, isolate);
4172 node_isolate = nullptr;
Ben Noordhuisd7087df2016-06-17 23:39:054173 }
Ben Noordhuis53e64bb2015-10-26 13:11:034174
Petka Antonov4ae64b22015-03-03 20:25:474175 isolate->Dispose();
Ben Noordhuisd77e8182016-10-21 11:47:494176
4177 return exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474178}
4179
Ben Noordhuis185c5152013-09-02 14:42:014180int Start(int argc, char** argv) {
Evan Lucas14dc17d2018-06-11 14:20:504181 atexit([] () { uv_tty_reset_mode(); });
Ben Noordhuis5756f922015-01-26 22:15:204182 PlatformInit();
Daniel Beveniuscae41822018-02-23 14:42:204183 performance::performance_node_start = PERFORMANCE_NOW();
Ben Noordhuis5756f922015-01-26 22:15:204184
Ben Noordhuis5fdff382014-10-11 14:52:074185 CHECK_GT(argc, 0);
Micheil Smith19fd5302012-03-05 17:53:154186
Ben Noordhuis185c5152013-09-02 14:42:014187 // Hack around with the argv pointer. Used for process.title = "blah".
Ben Noordhuis1a979982012-03-15 22:10:324188 argv = uv_setup_args(argc, argv);
4189
Ben Noordhuis185c5152013-09-02 14:42:014190 // This needs to run *before* V8::Initialize(). The const_cast is not
4191 // optional, in case you're wondering.
4192 int exec_argc;
4193 const char** exec_argv;
4194 Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
Ben Noordhuis5866f1a2011-12-09 18:02:334195
Ben Noordhuis7ac23912013-09-20 20:01:494196#if HAVE_OPENSSL
Ben Noordhuisa8734af2017-01-28 12:27:024197 {
4198 std::string extra_ca_certs;
4199 if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
4200 crypto::UseExtraCaCerts(extra_ca_certs);
4201 }
Stefan Budeanu7c48cb52016-01-22 23:10:094202#ifdef NODE_FIPS_MODE
4203 // In the case of FIPS builds we should make sure
4204 // the random source is properly initialized first.
4205 OPENSSL_init();
4206#endif // NODE_FIPS_MODE
Ben Noordhuis7ac23912013-09-20 20:01:494207 // V8 on Windows doesn't have a good source of entropy. Seed it from
4208 // OpenSSL's pool.
4209 V8::SetEntropySource(crypto::EntropySource);
Ben Noordhuisa8734af2017-01-28 12:27:024210#endif // HAVE_OPENSSL
Ben Noordhuis7ac23912013-09-20 20:01:494211
Anna Henningsenc7ad7292017-09-14 11:05:484212 v8_platform.Initialize(v8_thread_pool_size);
Ben Noordhuis75ea5662013-09-23 12:27:264213 V8::Initialize();
Daniel Beveniuscae41822018-02-23 14:42:204214 performance::performance_v8_start = PERFORMANCE_NOW();
Anna Henningsen72c60e82016-09-10 16:21:204215 v8_initialized = true;
Ben Noordhuisd77e8182016-10-21 11:47:494216 const int exit_code =
4217 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
James M Snell5c27e442018-04-04 01:05:334218 v8_platform.StopTracingAgent();
Anna Henningsen72c60e82016-09-10 16:21:204219 v8_initialized = false;
Ryan27b268b2009-06-17 13:05:444220 V8::Dispose();
Igor Zinkovskya58b6432011-07-07 20:54:304221
Matt Loring9e086952017-03-13 22:17:574222 // uv_run cannot be called from the time before the beforeExit callback
4223 // runs until the program exits unless the event loop has any referenced
4224 // handles after beforeExit terminates. This prevents unrefed timers
4225 // that happen to terminate during shutdown from being run unsafely.
4226 // Since uv_run cannot be called, uv_async handles held by the platform
4227 // will never be fully cleaned up.
Stefan Budeanu410296c2016-03-27 00:17:554228 v8_platform.Dispose();
Ben Noordhuis4a801c22015-04-02 21:51:014229
Ben Noordhuis185c5152013-09-02 14:42:014230 delete[] exec_argv;
Ben Noordhuis2d82cdf2014-10-22 01:29:324231 exec_argv = nullptr;
Micheil Smith19fd5302012-03-05 17:53:154232
Petka Antonov4ae64b22015-03-03 20:25:474233 return exit_code;
Ryan19478ed2009-03-03 00:56:154234}
Ryan Dahl124fbed2010-09-19 20:13:574235
Yihong Wang8680bb92017-10-22 06:16:504236// Call built-in modules' _register_<module name> function to
4237// do module registration explicitly.
4238void RegisterBuiltinModules() {
4239#define V(modname) _register_##modname();
4240 NODE_BUILTIN_MODULES(V)
4241#undef V
4242}
Ryan Dahl124fbed2010-09-19 20:13:574243
4244} // namespace node
Eugene Ostroukhov3f48ab32017-04-25 21:55:554245
4246#if !HAVE_INSPECTOR
Daniel Beveniusebbf3932018-03-23 08:38:164247void Initialize() {}
Eugene Ostroukhov3f48ab32017-04-25 21:55:554248
Daniel Beveniusebbf3932018-03-23 08:38:164249NODE_BUILTIN_MODULE_CONTEXT_AWARE(inspector, Initialize)
Eugene Ostroukhov3f48ab32017-04-25 21:55:554250#endif // !HAVE_INSPECTOR