blob: 656d132ec9fb321aad3a31c801618c179d10c117 [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"
Ben Noordhuis02cab972013-07-31 21:16:0831
32#if defined HAVE_PERFCTR
33#include "node_counters.h"
34#endif
35
36#if HAVE_OPENSSL
37#include "node_crypto.h"
38#endif
39
Steven R. Loomisac2857b2014-09-05 05:03:2440#if defined(NODE_HAVE_I18N_SUPPORT)
41#include "node_i18n.h"
42#endif
43
Ben Noordhuis399cb252017-05-27 11:31:0044#if HAVE_INSPECTOR
45#include "inspector_io.h"
46#endif
47
Ben Noordhuisc4def502013-10-28 19:18:5948#if defined HAVE_DTRACE || defined HAVE_ETW
Ben Noordhuis02cab972013-07-31 21:16:0849#include "node_dtrace.h"
50#endif
51
Glen Keane5e825d12015-01-22 12:35:1652#if defined HAVE_LTTNG
53#include "node_lttng.h"
54#endif
55
Bert Belder22d03c92012-08-06 23:48:1556#include "ares.h"
Daniel Bevenius78447662017-11-14 12:34:5257#include "async_wrap-inl.h"
Ben Noordhuis756b6222013-08-10 22:26:1158#include "env-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0859#include "handle_wrap.h"
Anna Henningsen6a1275d2017-04-17 12:49:3160#include "http_parser.h"
James M Snelle71e71b2017-07-17 17:17:1661#include "nghttp2/nghttp2ver.h"
Daniel Beveniusb58a1cd2017-11-14 12:34:5262#include "req_wrap-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0863#include "string_bytes.h"
misterpoeba4847e2016-08-05 21:04:2564#include "tracing/agent.h"
Timothy J Fontaine1a09da62014-06-10 23:36:0465#include "util.h"
Ben Noordhuisff4a9d32012-03-09 23:11:1166#include "uv.h"
Stefan Budeanu410296c2016-03-27 00:17:5567#if NODE_USE_V8_PLATFORM
Ben Noordhuis4a801c22015-04-02 21:51:0168#include "libplatform/libplatform.h"
Stefan Budeanu410296c2016-03-27 00:17:5569#endif // NODE_USE_V8_PLATFORM
Ben Noordhuis57231d52013-10-02 04:37:4470#include "v8-profiler.h"
Ben Noordhuis02cab972013-07-31 21:16:0871#include "zlib.h"
Ryan Dahl4635ed72010-03-11 20:40:1972
Chunyang Daia881b532015-10-21 16:24:1273#ifdef NODE_ENABLE_VTUNE_PROFILING
74#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
75#endif
76
Ben Noordhuis02cab972013-07-31 21:16:0877#include <errno.h>
Myles Borins9cc39ff2017-04-24 16:47:2678#include <fcntl.h> // _O_RDWR
Ben Noordhuis02cab972013-07-31 21:16:0879#include <limits.h> // PATH_MAX
Bert Beldere0f47be2011-01-17 23:22:3680#include <locale.h>
Bert Belder9cec08e2011-05-23 23:42:2281#include <signal.h>
Ryan19478ed2009-03-03 00:56:1582#include <stdio.h>
Ryan34a6f102009-05-28 12:47:1683#include <stdlib.h>
Ryan Dahlc90e44e2010-05-10 23:38:4784#include <string.h>
Ben Noordhuis02cab972013-07-31 21:16:0885#include <sys/types.h>
Ben Noordhuisc5c28c32015-10-10 13:01:4986
87#include <string>
Brian White2d356072015-10-13 21:18:1588#include <vector>
Ben Noordhuis02cab972013-07-31 21:16:0889
Evan Lucas30b8bb02015-09-27 15:59:0290#if defined(NODE_HAVE_I18N_SUPPORT)
91#include <unicode/uvernum.h>
92#endif
93
Karl Skomski6ed06032015-08-14 08:07:1894#if defined(LEAK_SANITIZER)
95#include <sanitizer/lsan_interface.h>
96#endif
97
Ben Noordhuis02cab972013-07-31 21:16:0898#if defined(_MSC_VER)
Peter Bright13d6a1f2011-08-06 04:23:2599#include <direct.h>
Peter Brightb9d77772011-08-11 01:45:56100#include <io.h>
101#define umask _umask
102typedef int mode_t;
Ben Noordhuis02cab972013-07-31 21:16:08103#else
Ben Noordhuis844f0a92016-03-25 16:59:07104#include <pthread.h>
Ben Noordhuis68200542013-10-02 10:17:57105#include <sys/resource.h> // getrlimit, setrlimit
Ben Noordhuis02cab972013-07-31 21:16:08106#include <unistd.h> // setuid, getuid
Peter Bright13d6a1f2011-08-06 04:23:25107#endif
Ryane02b71e2009-03-03 23:31:37108
Ed Schouten78dbcbe2017-10-30 10:58:13109#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ben Noordhuis02cab972013-07-31 21:16:08110#include <pwd.h> // getpwnam()
111#include <grp.h> // getgrnam()
Bert Beldera177d602010-11-25 00:02:55112#endif
113
Ezequiel Garcia5f223752017-04-29 20:06:22114#if defined(__POSIX__)
115#include <dlfcn.h>
116#endif
117
Fedor Indutny8e29ce92013-07-31 18:07:29118#ifdef __APPLE__
Ben Noordhuis02cab972013-07-31 21:16:08119#include <crt_externs.h>
120#define environ (*_NSGetEnviron())
Fedor Indutny8e29ce92013-07-31 18:07:29121#elif !defined(_MSC_VER)
Ryan3e4fc9f2009-09-10 14:48:38122extern char **environ;
Fedor Indutny8e29ce92013-07-31 18:07:29123#endif
Ryan3e4fc9f2009-09-10 14:48:38124
Yihong Wang8680bb92017-10-22 06:16:50125// This is used to load built-in modules. Instead of using
126// __attribute__((constructor)), we call the _register_<modname>
127// function for each built-in modules explicitly in
128// node::RegisterBuiltinModules(). This is only forward declaration.
129// The definitions are in each module's implementation when calling
130// the NODE_BUILTIN_MODULE_CONTEXT_AWARE.
131#define V(modname) void _register_##modname();
132 NODE_BUILTIN_MODULES(V)
133#undef V
134
Ryand6c9d312009-09-11 14:02:29135namespace node {
136
Ben Noordhuis110a9cd2013-07-03 02:23:44137using v8::Array;
Ben Noordhuis0693d222013-06-29 06:16:25138using v8::ArrayBuffer;
Ben Noordhuis110a9cd2013-07-03 02:23:44139using v8::Boolean;
140using v8::Context;
Fedor Indutnyce04c722014-03-13 16:38:14141using v8::EscapableHandleScope;
Ben Noordhuis110a9cd2013-07-03 02:23:44142using v8::Exception;
Patrick Mueller52cb4102016-04-05 13:17:48143using v8::Float64Array;
Ben Noordhuis110a9cd2013-07-03 02:23:44144using v8::Function;
145using v8::FunctionCallbackInfo;
Ben Noordhuis110a9cd2013-07-03 02:23:44146using v8::HandleScope;
147using v8::HeapStatistics;
148using v8::Integer;
149using v8::Isolate;
Anna Henningsenf3cd5372017-12-01 23:04:56150using v8::Just;
Ben Noordhuis511af4d2013-07-30 19:28:43151using v8::Local;
Ben Noordhuis110a9cd2013-07-03 02:23:44152using v8::Locker;
Anna Henningsenf3cd5372017-12-01 23:04:56153using v8::Maybe;
Michaël Zasso023c3172016-02-08 21:34:05154using v8::MaybeLocal;
Ben Noordhuis110a9cd2013-07-03 02:23:44155using v8::Message;
Ali Ijaz Sheikhc1649a72016-02-12 08:58:26156using v8::Name;
AnnaMagab194122016-10-06 20:50:41157using v8::NamedPropertyHandlerConfiguration;
Anna Henningsenf3cd5372017-12-01 23:04:56158using v8::Nothing;
Jeremiah Senkpiel21d66d62016-03-23 22:09:10159using v8::Null;
Ben Noordhuis110a9cd2013-07-03 02:23:44160using v8::Number;
161using v8::Object;
162using v8::ObjectTemplate;
Petka Antonov872702d2015-02-22 12:44:12163using v8::Promise;
164using v8::PromiseRejectMessage;
Ben Noordhuis110a9cd2013-07-03 02:23:44165using v8::PropertyCallbackInfo;
Michaël Zasso023c3172016-02-08 21:34:05166using v8::ScriptOrigin;
Fedor Indutnya07c6912015-04-11 14:02:33167using v8::SealHandleScope;
Ben Noordhuis511af4d2013-07-30 19:28:43168using v8::String;
Ben Noordhuis110a9cd2013-07-03 02:23:44169using v8::TryCatch;
Ben Noordhuis70d1f322015-06-19 11:23:56170using v8::Uint32Array;
Anna Henningsen64616bb2017-08-08 18:02:55171using v8::Undefined;
Ben Noordhuis110a9cd2013-07-03 02:23:44172using v8::V8;
173using v8::Value;
Ben Noordhuis110a9cd2013-07-03 02:23:44174
Trevor Norrisc0bde732017-03-07 19:40:18175using AsyncHooks = node::Environment::AsyncHooks;
176
Evan Lucas5b6f5752015-06-01 14:15:10177static bool print_eval = false;
178static bool force_repl = false;
Dave Eddy2e6ece42015-08-17 21:33:13179static bool syntax_check_only = false;
Evan Lucas5b6f5752015-06-01 14:15:10180static bool trace_deprecation = false;
181static bool throw_deprecation = false;
Evan Lucas5b6f5752015-06-01 14:15:10182static bool trace_sync_io = false;
Andreas Madsen23a39112017-10-19 12:15:08183static bool no_force_async_hooks_checks = false;
Bradley Meckcf14a242015-07-09 16:15:26184static bool track_heap_objects = false;
Evan Lucas5b6f5752015-06-01 14:15:10185static const char* eval_string = nullptr;
Sam Robertscecdf7c2017-04-05 18:45:52186static std::vector<std::string> preload_modules;
Tom Gallacher03e07d32015-12-18 12:24:56187static const int v8_default_thread_pool_size = 4;
188static int v8_thread_pool_size = v8_default_thread_pool_size;
Matt Loring49440b72015-11-25 14:08:58189static bool prof_process = false;
Ben Noordhuis9566fe82013-10-03 08:45:32190static bool v8_is_profiling = false;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22191static bool node_is_initialized = false;
Keith M Wesolowski76b98462013-12-17 00:00:44192static node_module* modpending;
193static node_module* modlist_builtin;
Bradley Fariasa36aa042017-10-03 15:07:48194static node_module* modlist_internal;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22195static node_module* modlist_linked;
Keith M Wesolowski76b98462013-12-17 00:00:44196static node_module* modlist_addon;
misterpoeba4847e2016-08-05 21:04:25197static bool trace_enabled = false;
Sam Roberts809ca2f2017-04-05 19:09:32198static std::string trace_enabled_categories; // NOLINT(runtime/string)
Trevor Norrisc0bde732017-03-07 19:40:18199static bool abort_on_uncaught_exception = false;
Ben Noordhuis74a82152012-02-03 15:32:00200
James M Snell35f6e592017-08-16 16:34:37201// Bit flag used to track security reverts (see node_revert.h)
202unsigned int reverted = 0;
203
Evan Lucas5b6f5752015-06-01 14:15:10204#if defined(NODE_HAVE_I18N_SUPPORT)
205// Path to ICU data (for i18n / Intl)
Ben Noordhuis46345b92017-02-11 13:00:22206std::string icu_data_dir; // NOLINT(runtime/string)
Evan Lucas5b6f5752015-06-01 14:15:10207#endif
Steven R. Loomisac2857b2014-09-05 05:03:24208
isaacs48c3d202012-06-21 19:20:23209// used by C++ modules as well
210bool no_deprecation = false;
211
Fedor Indutnydb411cf2016-09-29 08:53:30212#if HAVE_OPENSSL
Adam Majer33012e92016-12-21 10:16:39213// use OpenSSL's cert store instead of bundled certs
214bool ssl_openssl_cert_store =
215#if defined(NODE_OPENSSL_CERT_STORE)
216 true;
217#else
218 false;
219#endif
220
Fedor Indutnydb411cf2016-09-29 08:53:30221# if NODE_FIPS_MODE
Stefan Budeanu7c48cb52016-01-22 23:10:09222// used by crypto module
223bool enable_fips_crypto = false;
224bool force_fips_crypto = false;
Fedor Indutnydb411cf2016-09-29 08:53:30225# endif // NODE_FIPS_MODE
Sam Roberts59afa272017-01-25 22:13:34226std::string openssl_config; // NOLINT(runtime/string)
Fedor Indutnydb411cf2016-09-29 08:53:30227#endif // HAVE_OPENSSL
Stefan Budeanu7c48cb52016-01-22 23:10:09228
James M Snellc6656db2016-01-20 19:38:35229// true if process warnings should be suppressed
230bool no_process_warnings = false;
231bool trace_warnings = false;
232
James M Snell5d38d542016-05-02 23:31:20233// Set in node.cc by ParseArgs when --preserve-symlinks is used.
234// Used in node_config.cc to set a constant on process.binding('config')
235// that is used by lib/module.js
236bool config_preserve_symlinks = false;
237
Bradley Fariasc8a389e2017-06-06 00:44:56238// Set in node.cc by ParseArgs when --experimental-modules is used.
239// Used in node_config.cc to set a constant on process.binding('config')
240// that is used by lib/module.js
241bool config_experimental_modules = false;
242
guybedfordd21a11d2017-09-03 11:20:06243// Set in node.cc by ParseArgs when --loader is used.
244// Used in node_config.cc to set a constant on process.binding('config')
245// that is used by lib/internal/bootstrap_node.js
246std::string config_userland_loader; // NOLINT(runtime/string)
247
James M Snella16b5702017-03-11 20:18:53248// Set by ParseArgs when --pending-deprecation or NODE_PENDING_DEPRECATION
249// is used.
250bool config_pending_deprecation = false;
251
James M Snell03e89b32016-12-04 18:38:35252// Set in node.cc by ParseArgs when --redirect-warnings= is used.
Ben Noordhuisa8734af2017-01-28 12:27:02253std::string config_warning_file; // NOLINT(runtime/string)
James M Snell03e89b32016-12-04 18:38:35254
Sam Roberts8086cb62017-04-05 21:06:52255// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
256// used.
257// Used in node_config.cc to set a constant on process.binding('config')
258// that is used by lib/internal/bootstrap_node.js
259bool config_expose_internals = false;
260
Anna Henningsen72c60e82016-09-10 16:21:20261bool v8_initialized = false;
262
Daniel Bevenius6caf1b02017-04-20 18:08:53263bool linux_at_secure = false;
264
Ben Noordhuis74a82152012-02-03 15:32:00265// process-relative uptime base, initialized at start-up
266static double prog_start_time;
Ben Noordhuis5d0816b2013-01-06 22:06:48267
Ben Noordhuisd7087df2016-06-17 23:39:05268static Mutex node_isolate_mutex;
Ben Noordhuis844f0a92016-03-25 16:59:07269static v8::Isolate* node_isolate;
Stefan Budeanu410296c2016-03-27 00:17:55270
cornholio2777a7e2017-06-11 19:01:27271node::DebugOptions debug_options;
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22272
Stefan Budeanu410296c2016-03-27 00:17:55273static struct {
274#if NODE_USE_V8_PLATFORM
Anna Henningsenc7ad7292017-09-14 11:05:48275 void Initialize(int thread_pool_size) {
Andreas Madsend217b282017-07-17 23:47:12276 if (trace_enabled) {
277 tracing_agent_.reset(new tracing::Agent());
278 platform_ = new NodePlatform(thread_pool_size,
279 tracing_agent_->GetTracingController());
280 V8::InitializePlatform(platform_);
281 tracing::TraceEventHelper::SetTracingController(
282 tracing_agent_->GetTracingController());
283 } else {
284 tracing_agent_.reset(nullptr);
285 platform_ = new NodePlatform(thread_pool_size, nullptr);
286 V8::InitializePlatform(platform_);
287 tracing::TraceEventHelper::SetTracingController(
288 new v8::TracingController());
289 }
Stefan Budeanu410296c2016-03-27 00:17:55290 }
291
292 void Dispose() {
Matt Loring9e086952017-03-13 22:17:57293 platform_->Shutdown();
Stefan Budeanu410296c2016-03-27 00:17:55294 delete platform_;
295 platform_ = nullptr;
Franziska Hinkelmann787863d2017-11-12 21:16:10296 tracing_agent_.reset(nullptr);
Matt Loring9e086952017-03-13 22:17:57297 }
298
Anna Henningsenc7ad7292017-09-14 11:05:48299 void DrainVMTasks(Isolate* isolate) {
300 platform_->DrainBackgroundTasks(isolate);
Stefan Budeanu410296c2016-03-27 00:17:55301 }
302
Anna Henningsen2cedff92017-10-22 22:52:55303 void CancelVMTasks(Isolate* isolate) {
304 platform_->CancelPendingDelayedTasks(isolate);
305 }
306
Ben Noordhuisc5c28c32015-10-10 13:01:49307#if HAVE_INSPECTOR
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22308 bool StartInspector(Environment *env, const char* script_path,
309 const node::DebugOptions& options) {
Sam Roberts2791b362017-05-26 02:00:24310 // Inspector agent can't fail to start, but if it was configured to listen
311 // right away on the websocket port and fails to bind/etc, this will return
312 // false.
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22313 return env->inspector_agent()->Start(platform_, script_path, options);
Ben Noordhuisc5c28c32015-10-10 13:01:49314 }
Eugene Ostroukhov5c263782017-05-01 20:31:14315
316 bool InspectorStarted(Environment *env) {
317 return env->inspector_agent()->IsStarted();
318 }
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22319#endif // HAVE_INSPECTOR
Stefan Budeanu410296c2016-03-27 00:17:55320
Myk Melez046f66a2017-01-31 17:56:09321 void StartTracingAgent() {
Matt Loring5e5a52f2017-06-29 08:55:38322 tracing_agent_->Start(trace_enabled_categories);
Myk Melez046f66a2017-01-31 17:56:09323 }
324
325 void StopTracingAgent() {
326 tracing_agent_->Stop();
327 }
328
Anna Henningsenc7ad7292017-09-14 11:05:48329 NodePlatform* Platform() {
330 return platform_;
331 }
332
Franziska Hinkelmann787863d2017-11-12 21:16:10333 std::unique_ptr<tracing::Agent> tracing_agent_;
Matt Loring9e086952017-03-13 22:17:57334 NodePlatform* platform_;
Stefan Budeanu410296c2016-03-27 00:17:55335#else // !NODE_USE_V8_PLATFORM
Anna Henningsenc7ad7292017-09-14 11:05:48336 void Initialize(int thread_pool_size) {}
Stefan Budeanu410296c2016-03-27 00:17:55337 void Dispose() {}
Anna Henningsenc7ad7292017-09-14 11:05:48338 void DrainVMTasks(Isolate* isolate) {}
Anna Henningsen2cedff92017-10-22 22:52:55339 void CancelVMTasks(Isolate* isolate) {}
Eugene Ostroukhov609a2652016-06-10 01:00:08340 bool StartInspector(Environment *env, const char* script_path,
Myk Melez046f66a2017-01-31 17:56:09341 const node::DebugOptions& options) {
Stefan Budeanu410296c2016-03-27 00:17:55342 env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
Eugene Ostroukhov7599b0e2016-12-13 01:08:31343 return true;
Stefan Budeanu410296c2016-03-27 00:17:55344 }
Myk Melez046f66a2017-01-31 17:56:09345
346 void StartTracingAgent() {
347 fprintf(stderr, "Node compiled with NODE_USE_V8_PLATFORM=0, "
348 "so event tracing is not available.\n");
349 }
350 void StopTracingAgent() {}
Anna Henningsenc7ad7292017-09-14 11:05:48351
352 NodePlatform* Platform() {
353 return nullptr;
354 }
Daniel Beveniusae5e65c2017-05-23 05:40:48355#endif // !NODE_USE_V8_PLATFORM
356
357#if !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
Eugene Ostroukhov5c263782017-05-01 20:31:14358 bool InspectorStarted(Environment *env) {
359 return false;
360 }
Daniel Beveniusae5e65c2017-05-23 05:40:48361#endif // !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
Stefan Budeanu410296c2016-03-27 00:17:55362} v8_platform;
Ben Noordhuis5d0816b2013-01-06 22:06:48363
Ben Noordhuis844f0a92016-03-25 16:59:07364#ifdef __POSIX__
Eugene Ostroukhov66269192016-06-08 21:09:28365static const unsigned kMaxSignal = 32;
Ben Noordhuis844f0a92016-03-25 16:59:07366#endif
367
Brian White2d356072015-10-13 21:18:15368static void PrintErrorString(const char* format, ...) {
369 va_list ap;
370 va_start(ap, format);
371#ifdef _WIN32
372 HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
373
374 // Check if stderr is something other than a tty/console
375 if (stderr_handle == INVALID_HANDLE_VALUE ||
376 stderr_handle == nullptr ||
377 uv_guess_handle(_fileno(stderr)) != UV_TTY) {
378 vfprintf(stderr, format, ap);
Ömer Fadıl Usta44a298b2015-10-28 12:49:51379 va_end(ap);
Brian White2d356072015-10-13 21:18:15380 return;
381 }
382
383 // Fill in any placeholders
384 int n = _vscprintf(format, ap);
385 std::vector<char> out(n + 1);
386 vsprintf(out.data(), format, ap);
387
388 // Get required wide buffer size
389 n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
390
391 std::vector<wchar_t> wbuf(n);
392 MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
Nikolai Vavilov09f861f2016-07-16 17:06:47393
394 // Don't include the null character in the output
395 CHECK_GT(n, 0);
396 WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
Brian White2d356072015-10-13 21:18:15397#else
398 vfprintf(stderr, format, ap);
399#endif
400 va_end(ap);
401}
402
Felix Geisendörferf8a3cf92010-04-28 13:04:08403const char *signo_string(int signo) {
404#define SIGNO_CASE(e) case e: return #e;
405 switch (signo) {
Felix Geisendörferf8a3cf92010-04-28 13:04:08406#ifdef SIGHUP
407 SIGNO_CASE(SIGHUP);
408#endif
409
410#ifdef SIGINT
411 SIGNO_CASE(SIGINT);
412#endif
413
414#ifdef SIGQUIT
415 SIGNO_CASE(SIGQUIT);
416#endif
417
418#ifdef SIGILL
419 SIGNO_CASE(SIGILL);
420#endif
421
422#ifdef SIGTRAP
423 SIGNO_CASE(SIGTRAP);
424#endif
425
426#ifdef SIGABRT
427 SIGNO_CASE(SIGABRT);
428#endif
429
430#ifdef SIGIOT
431# if SIGABRT != SIGIOT
432 SIGNO_CASE(SIGIOT);
433# endif
434#endif
435
436#ifdef SIGBUS
437 SIGNO_CASE(SIGBUS);
438#endif
439
440#ifdef SIGFPE
441 SIGNO_CASE(SIGFPE);
442#endif
443
444#ifdef SIGKILL
445 SIGNO_CASE(SIGKILL);
446#endif
447
448#ifdef SIGUSR1
449 SIGNO_CASE(SIGUSR1);
450#endif
451
452#ifdef SIGSEGV
453 SIGNO_CASE(SIGSEGV);
454#endif
455
456#ifdef SIGUSR2
457 SIGNO_CASE(SIGUSR2);
458#endif
459
460#ifdef SIGPIPE
461 SIGNO_CASE(SIGPIPE);
462#endif
463
464#ifdef SIGALRM
465 SIGNO_CASE(SIGALRM);
466#endif
467
468 SIGNO_CASE(SIGTERM);
Bert Belderdcc35082010-11-25 00:04:31469
470#ifdef SIGCHLD
Felix Geisendörferf8a3cf92010-04-28 13:04:08471 SIGNO_CASE(SIGCHLD);
Bert Belderdcc35082010-11-25 00:04:31472#endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08473
474#ifdef SIGSTKFLT
475 SIGNO_CASE(SIGSTKFLT);
476#endif
477
478
479#ifdef SIGCONT
480 SIGNO_CASE(SIGCONT);
481#endif
482
483#ifdef SIGSTOP
484 SIGNO_CASE(SIGSTOP);
485#endif
486
487#ifdef SIGTSTP
488 SIGNO_CASE(SIGTSTP);
489#endif
490
Bert Belder600a6462012-08-20 21:59:21491#ifdef SIGBREAK
492 SIGNO_CASE(SIGBREAK);
493#endif
494
Felix Geisendörferf8a3cf92010-04-28 13:04:08495#ifdef SIGTTIN
496 SIGNO_CASE(SIGTTIN);
497#endif
498
499#ifdef SIGTTOU
500 SIGNO_CASE(SIGTTOU);
501#endif
502
503#ifdef SIGURG
504 SIGNO_CASE(SIGURG);
505#endif
506
507#ifdef SIGXCPU
508 SIGNO_CASE(SIGXCPU);
509#endif
510
511#ifdef SIGXFSZ
512 SIGNO_CASE(SIGXFSZ);
513#endif
514
515#ifdef SIGVTALRM
516 SIGNO_CASE(SIGVTALRM);
517#endif
518
519#ifdef SIGPROF
520 SIGNO_CASE(SIGPROF);
521#endif
522
523#ifdef SIGWINCH
524 SIGNO_CASE(SIGWINCH);
525#endif
526
527#ifdef SIGIO
528 SIGNO_CASE(SIGIO);
529#endif
530
531#ifdef SIGPOLL
Ryan Dahl3bb21b52010-04-28 22:07:15532# if SIGPOLL != SIGIO
Felix Geisendörferf8a3cf92010-04-28 13:04:08533 SIGNO_CASE(SIGPOLL);
Ryan Dahl3bb21b52010-04-28 22:07:15534# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08535#endif
536
537#ifdef SIGLOST
Michael Dawson2a17c7f2015-08-12 15:53:33538# if SIGLOST != SIGABRT
Felix Geisendörferf8a3cf92010-04-28 13:04:08539 SIGNO_CASE(SIGLOST);
Michael Dawson2a17c7f2015-08-12 15:53:33540# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08541#endif
542
543#ifdef SIGPWR
Raffaele Senab3b81d62010-06-09 04:08:05544# if SIGPWR != SIGLOST
Felix Geisendörferf8a3cf92010-04-28 13:04:08545 SIGNO_CASE(SIGPWR);
Raffaele Senab3b81d62010-06-09 04:08:05546# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08547#endif
548
James Reggiofb5f66a2016-04-07 01:00:04549#ifdef SIGINFO
550# if !defined(SIGPWR) || SIGINFO != SIGPWR
551 SIGNO_CASE(SIGINFO);
552# endif
553#endif
554
Felix Geisendörferf8a3cf92010-04-28 13:04:08555#ifdef SIGSYS
556 SIGNO_CASE(SIGSYS);
557#endif
558
Felix Geisendörferf8a3cf92010-04-28 13:04:08559 default: return "";
560 }
561}
562
Ryan Dahlc9e27b12010-04-23 00:53:45563
Fedor Indutny75adde02014-02-21 13:02:42564Local<Value> ErrnoException(Isolate* isolate,
565 int errorno,
Ryan Dahlc9e27b12010-04-23 00:53:45566 const char *syscall,
visionmedia45948e02010-05-14 14:52:49567 const char *msg,
568 const char *path) {
Fedor Indutny75adde02014-02-21 13:02:42569 Environment* env = Environment::GetCurrent(isolate);
Ben Noordhuis756b6222013-08-10 22:26:11570
visionmedia45948e02010-05-14 14:52:49571 Local<Value> e;
Fedor Indutny75adde02014-02-21 13:02:42572 Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
Ben Noordhuis2d82cdf2014-10-22 01:29:32573 if (msg == nullptr || msg[0] == '\0') {
Bert Belder2ce09612011-01-17 21:47:59574 msg = strerror(errorno);
Bert Belder2ce09612011-01-17 21:47:59575 }
Fedor Indutny75adde02014-02-21 13:02:42576 Local<String> message = OneByteString(env->isolate(), msg);
Ryan Dahlc9e27b12010-04-23 00:53:45577
Ben Noordhuis4f394992015-03-13 18:15:18578 Local<String> cons =
Fedor Indutny75adde02014-02-21 13:02:42579 String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
Ben Noordhuis4f394992015-03-13 18:15:18580 cons = String::Concat(cons, message);
Ryan Dahlc9e27b12010-04-23 00:53:45581
Ben Noordhuis4f394992015-03-13 18:15:18582 Local<String> path_string;
583 if (path != nullptr) {
584 // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
585 path_string = String::NewFromUtf8(env->isolate(), path);
visionmedia45948e02010-05-14 14:52:49586 }
587
Ben Noordhuis4f394992015-03-13 18:15:18588 if (path_string.IsEmpty() == false) {
589 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
590 cons = String::Concat(cons, path_string);
591 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
592 }
593 e = Exception::Error(cons);
594
Leko19221d12017-11-27 07:16:32595 Local<Object> obj = e.As<Object>();
Fedor Indutnyce04c722014-03-13 16:38:14596 obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
Ben Noordhuis756b6222013-08-10 22:26:11597 obj->Set(env->code_string(), estring);
visionmedia45948e02010-05-14 14:52:49598
Ben Noordhuis4f394992015-03-13 18:15:18599 if (path_string.IsEmpty() == false) {
600 obj->Set(env->path_string(), path_string);
Ben Noordhuis756b6222013-08-10 22:26:11601 }
602
Ben Noordhuis2d82cdf2014-10-22 01:29:32603 if (syscall != nullptr) {
Fedor Indutny75adde02014-02-21 13:02:42604 obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
Ben Noordhuis756b6222013-08-10 22:26:11605 }
606
Ryan Dahlc9e27b12010-04-23 00:53:45607 return e;
608}
609
610
Bert Belderbc2c85c2015-01-31 10:48:34611static Local<String> StringFromPath(Isolate* isolate, const char* path) {
612#ifdef _WIN32
613 if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
614 return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
615 String::NewFromUtf8(isolate, path + 8));
616 } else if (strncmp(path, "\\\\?\\", 4) == 0) {
617 return String::NewFromUtf8(isolate, path + 4);
618 }
619#endif
620
621 return String::NewFromUtf8(isolate, path);
622}
623
624
Fedor Indutny75adde02014-02-21 13:02:42625Local<Value> UVException(Isolate* isolate,
626 int errorno,
Bert Belderbc2c85c2015-01-31 10:48:34627 const char* syscall,
628 const char* msg,
629 const char* path) {
630 return UVException(isolate, errorno, syscall, msg, path, nullptr);
631}
632
633
634Local<Value> UVException(Isolate* isolate,
635 int errorno,
636 const char* syscall,
637 const char* msg,
638 const char* path,
639 const char* dest) {
Fedor Indutny75adde02014-02-21 13:02:42640 Environment* env = Environment::GetCurrent(isolate);
Bert Belder823a4432011-12-01 23:02:51641
642 if (!msg || !msg[0])
Ben Noordhuisca9eb712013-07-18 21:18:50643 msg = uv_strerror(errorno);
Bert Belder823a4432011-12-01 23:02:51644
Bert Belderbc2c85c2015-01-31 10:48:34645 Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
646 Local<String> js_syscall = OneByteString(isolate, syscall);
647 Local<String> js_path;
648 Local<String> js_dest;
Bert Belder823a4432011-12-01 23:02:51649
Bert Belderbc2c85c2015-01-31 10:48:34650 Local<String> js_msg = js_code;
651 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
652 js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
653 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
654 js_msg = String::Concat(js_msg, js_syscall);
Ben Noordhuis756b6222013-08-10 22:26:11655
Ben Noordhuis2d82cdf2014-10-22 01:29:32656 if (path != nullptr) {
Bert Belderbc2c85c2015-01-31 10:48:34657 js_path = StringFromPath(isolate, path);
658
659 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
660 js_msg = String::Concat(js_msg, js_path);
661 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
Ben Noordhuis756b6222013-08-10 22:26:11662 }
663
Bert Belderbc2c85c2015-01-31 10:48:34664 if (dest != nullptr) {
665 js_dest = StringFromPath(isolate, dest);
666
667 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
668 js_msg = String::Concat(js_msg, js_dest);
669 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
Ben Noordhuis756b6222013-08-10 22:26:11670 }
671
Bert Belderbc2c85c2015-01-31 10:48:34672 Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
673
Bert Belderbc2c85c2015-01-31 10:48:34674 e->Set(env->errno_string(), Integer::New(isolate, errorno));
675 e->Set(env->code_string(), js_code);
676 e->Set(env->syscall_string(), js_syscall);
677 if (!js_path.IsEmpty())
678 e->Set(env->path_string(), js_path);
679 if (!js_dest.IsEmpty())
680 e->Set(env->dest_string(), js_dest);
681
Bert Belder823a4432011-12-01 23:02:51682 return e;
683}
684
685
Ben Noordhuis8f6c5872014-10-11 19:48:25686// Look up environment variable unless running as setuid root.
Sam Roberts901e9262017-01-27 19:49:14687bool SafeGetenv(const char* key, std::string* text) {
Ed Schouten78dbcbe2017-10-30 10:58:13688#if !defined(__CloudABI__) && !defined(_WIN32)
cjihrig88fe7e82017-05-25 17:32:37689 if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
690 goto fail;
Ben Noordhuis8f6c5872014-10-11 19:48:25691#endif
cjihrig88fe7e82017-05-25 17:32:37692
Ben Noordhuisa8734af2017-01-28 12:27:02693 if (const char* value = getenv(key)) {
694 *text = value;
695 return true;
696 }
cjihrig88fe7e82017-05-25 17:32:37697
698fail:
Ben Noordhuisa8734af2017-01-28 12:27:02699 text->clear();
700 return false;
Ben Noordhuis8f6c5872014-10-11 19:48:25701}
702
703
Bert Belder6ee73a22011-11-04 15:10:48704#ifdef _WIN32
Igor Zinkovsky500c8f42011-12-15 20:36:05705// Does about the same as strerror(),
706// but supports all windows error messages
Alexis Campailla93f3b642014-08-05 13:33:16707static const char *winapi_strerror(const int errorno, bool* must_free) {
Ben Noordhuis2d82cdf2014-10-22 01:29:32708 char *errmsg = nullptr;
Igor Zinkovsky500c8f42011-12-15 20:36:05709
710 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
Ben Noordhuis2d82cdf2014-10-22 01:29:32711 FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
712 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
Igor Zinkovsky500c8f42011-12-15 20:36:05713
714 if (errmsg) {
Alexis Campailla93f3b642014-08-05 13:33:16715 *must_free = true;
716
Igor Zinkovsky500c8f42011-12-15 20:36:05717 // Remove trailing newlines
718 for (int i = strlen(errmsg) - 1;
719 i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
720 errmsg[i] = '\0';
721 }
722
723 return errmsg;
724 } else {
725 // FormatMessage failed
Alexis Campailla93f3b642014-08-05 13:33:16726 *must_free = false;
Igor Zinkovsky500c8f42011-12-15 20:36:05727 return "Unknown error";
728 }
729}
730
731
Alexis Campailla440b9e22014-02-24 18:55:27732Local<Value> WinapiErrnoException(Isolate* isolate,
Fedor Indutny75adde02014-02-21 13:02:42733 int errorno,
Bert Belder829735e2011-11-04 15:23:02734 const char* syscall,
735 const char* msg,
736 const char* path) {
Alexis Campailla440b9e22014-02-24 18:55:27737 Environment* env = Environment::GetCurrent(isolate);
Bert Belder6ee73a22011-11-04 15:10:48738 Local<Value> e;
Alexis Campailla93f3b642014-08-05 13:33:16739 bool must_free = false;
Bert Belder829735e2011-11-04 15:23:02740 if (!msg || !msg[0]) {
Alexis Campailla93f3b642014-08-05 13:33:16741 msg = winapi_strerror(errorno, &must_free);
Bert Belder6ee73a22011-11-04 15:10:48742 }
Fedor Indutny75adde02014-02-21 13:02:42743 Local<String> message = OneByteString(env->isolate(), msg);
Bert Belder6ee73a22011-11-04 15:10:48744
Bert Belder6ee73a22011-11-04 15:10:48745 if (path) {
Ben Noordhuisf674b092013-08-07 19:50:41746 Local<String> cons1 =
Alexis Campailla440b9e22014-02-24 18:55:27747 String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
Ben Noordhuisf674b092013-08-07 19:50:41748 Local<String> cons2 =
Alexis Campailla440b9e22014-02-24 18:55:27749 String::Concat(cons1, String::NewFromUtf8(isolate, path));
Ben Noordhuisf674b092013-08-07 19:50:41750 Local<String> cons3 =
Alexis Campailla440b9e22014-02-24 18:55:27751 String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
Bert Belder6ee73a22011-11-04 15:10:48752 e = Exception::Error(cons3);
753 } else {
754 e = Exception::Error(message);
755 }
756
Leko19221d12017-11-27 07:16:32757 Local<Object> obj = e.As<Object>();
Fedor Indutnyce04c722014-03-13 16:38:14758 obj->Set(env->errno_string(), Integer::New(isolate, errorno));
Bert Belder6ee73a22011-11-04 15:10:48759
Ben Noordhuis2d82cdf2014-10-22 01:29:32760 if (path != nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:27761 obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
Ben Noordhuis756b6222013-08-10 22:26:11762 }
763
Ben Noordhuis2d82cdf2014-10-22 01:29:32764 if (syscall != nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:27765 obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
Ben Noordhuis756b6222013-08-10 22:26:11766 }
767
Alexis Campailla93f3b642014-08-05 13:33:16768 if (must_free)
769 LocalFree((HLOCAL)msg);
770
Bert Belder6ee73a22011-11-04 15:10:48771 return e;
772}
773#endif
774
775
Trevor Norris74178a52015-09-14 22:31:10776void* ArrayBufferAllocator::Allocate(size_t size) {
Ben Noordhuis27e84dd2016-05-31 18:58:31777 if (zero_fill_field_ || zero_fill_all_buffers)
Anna Henningsenea940862016-09-10 16:19:24778 return node::UncheckedCalloc(size);
Ben Noordhuis3a399632016-06-01 13:53:01779 else
Anna Henningsenea940862016-09-10 16:19:24780 return node::UncheckedMalloc(size);
Trevor Norris74178a52015-09-14 22:31:10781}
782
Anna Henningsen9d522222017-04-12 17:17:24783namespace {
784
Anna Henningsen9d522222017-04-12 17:17:24785bool ShouldAbortOnUncaughtException(Isolate* isolate) {
Jeremy Whitlock77a10ed2015-10-05 20:08:53786 HandleScope scope(isolate);
Jeremy Whitlock77a10ed2015-10-05 20:08:53787 Environment* env = Environment::GetCurrent(isolate);
Anna Henningsenb73e66e2017-11-29 19:55:43788 return env->should_abort_on_uncaught_toggle()[0] &&
789 !env->inside_should_not_abort_on_uncaught_scope();
Jeremy Whitlock77a10ed2015-10-05 20:08:53790}
791
Anna Henningsen4503da82017-11-20 18:57:20792
Timothy Gu80685772017-09-30 05:15:24793Local<Value> GetDomainProperty(Environment* env, Local<Object> object) {
794 Local<Value> domain_v =
795 object->GetPrivate(env->context(), env->domain_private_symbol())
796 .ToLocalChecked();
797 if (domain_v->IsObject()) {
798 return domain_v;
799 }
800 return object->Get(env->context(), env->domain_string()).ToLocalChecked();
801}
802
803
Anna Henningsen602fd362017-09-14 15:58:53804void DomainEnter(Environment* env, Local<Object> object) {
Timothy Gu80685772017-09-30 05:15:24805 Local<Value> domain_v = GetDomainProperty(env, object);
Anna Henningsen2509c342017-09-06 15:49:10806 if (domain_v->IsObject()) {
807 Local<Object> domain = domain_v.As<Object>();
Anna Henningsen2509c342017-09-06 15:49:10808 Local<Value> enter_v = domain->Get(env->enter_string());
809 if (enter_v->IsFunction()) {
810 if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
811 FatalError("node::AsyncWrap::MakeCallback",
812 "domain enter callback threw, please report this");
813 }
814 }
815 }
Anna Henningsen2509c342017-09-06 15:49:10816}
817
818
Anna Henningsen602fd362017-09-14 15:58:53819void DomainExit(Environment* env, v8::Local<v8::Object> object) {
Timothy Gu80685772017-09-30 05:15:24820 Local<Value> domain_v = GetDomainProperty(env, object);
Anna Henningsen2509c342017-09-06 15:49:10821 if (domain_v->IsObject()) {
822 Local<Object> domain = domain_v.As<Object>();
Anna Henningsen2509c342017-09-06 15:49:10823 Local<Value> exit_v = domain->Get(env->exit_string());
824 if (exit_v->IsFunction()) {
825 if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
826 FatalError("node::AsyncWrap::MakeCallback",
827 "domain exit callback threw, please report this");
828 }
829 }
830 }
Anna Henningsen2509c342017-09-06 15:49:10831}
832
Trevor Norris828f1452014-01-09 19:11:40833void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:55834 Environment* env = Environment::GetCurrent(args);
Trevor Norris828f1452014-01-09 19:11:40835
836 if (env->using_domains())
837 return;
838 env->set_using_domains(true);
839
Fedor Indutny75adde02014-02-21 13:02:42840 HandleScope scope(env->isolate());
Trevor Norris828f1452014-01-09 19:11:40841
Trevor Norris828f1452014-01-09 19:11:40842 // Do a little housekeeping.
843 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:04844 env->context(),
845 FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust();
Trevor Norris828f1452014-01-09 19:11:40846}
847
Anna Henningsen84dabe82017-04-18 16:02:27848
Vladimir Kurchatkin30bd7b62014-09-04 16:02:04849void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
850 args.GetIsolate()->RunMicrotasks();
851}
852
Trevor Norris828f1452014-01-09 19:11:40853
Trevor Norris494227b2015-10-14 20:58:52854void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
855 Environment* env = Environment::GetCurrent(args);
856
857 CHECK(args[0]->IsFunction());
858
Trevor Norris83524b32015-11-10 09:58:51859 env->set_push_values_to_array_function(args[0].As<Function>());
Trevor Norris494227b2015-10-14 20:58:52860 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:04861 env->context(),
862 FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust();
Trevor Norris494227b2015-10-14 20:58:52863}
864
865
Trevor Norrisefa62fd2013-09-24 21:12:11866void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:55867 Environment* env = Environment::GetCurrent(args);
Trevor Norrisefa62fd2013-09-24 21:12:11868
Ben Noordhuis70d1f322015-06-19 11:23:56869 CHECK(args[0]->IsFunction());
Trevor Norrisefa62fd2013-09-24 21:12:11870
Ben Noordhuis70d1f322015-06-19 11:23:56871 env->set_tick_callback_function(args[0].As<Function>());
Trevor Norrisefa62fd2013-09-24 21:12:11872
Trevor Norrisefa62fd2013-09-24 21:12:11873 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:04874 env->context(),
Anatoli Papirovski4444b6b2017-12-18 03:45:45875 FIXED_ONE_BYTE_STRING(env->isolate(), "_setupNextTick")).FromJust();
Ben Noordhuis70d1f322015-06-19 11:23:56876
Anatoli Papirovski4444b6b2017-12-18 03:45:45877 v8::Local<v8::Function> run_microtasks_fn =
878 env->NewFunctionTemplate(RunMicrotasks)->GetFunction(env->context())
879 .ToLocalChecked();
880 run_microtasks_fn->SetName(
881 FIXED_ONE_BYTE_STRING(env->isolate(), "runMicrotasks"));
882
883 Local<Array> ret = Array::New(env->isolate(), 2);
884 ret->Set(env->context(), 0,
Anatoli Papirovski58467862017-12-27 18:47:51885 env->tick_info()->fields().GetJSArray()).FromJust();
Anatoli Papirovski4444b6b2017-12-18 03:45:45886 ret->Set(env->context(), 1, run_microtasks_fn).FromJust();
887
888 args.GetReturnValue().Set(ret);
Trevor Norris3f5d5842013-08-07 00:01:44889}
890
Petka Antonov872702d2015-02-22 12:44:12891void PromiseRejectCallback(PromiseRejectMessage message) {
892 Local<Promise> promise = message.GetPromise();
893 Isolate* isolate = promise->GetIsolate();
Anatoli Papirovskid62566e2018-01-17 14:39:01894 v8::PromiseRejectEvent event = message.GetEvent();
Petka Antonov872702d2015-02-22 12:44:12895
896 Environment* env = Environment::GetCurrent(isolate);
Anatoli Papirovskid62566e2018-01-17 14:39:01897 Local<Function> callback;
898 Local<Value> value;
Petka Antonov872702d2015-02-22 12:44:12899
Anatoli Papirovskid62566e2018-01-17 14:39:01900 if (event == v8::kPromiseRejectWithNoHandler) {
901 callback = env->promise_reject_unhandled_function();
902 value = message.GetValue();
903
904 if (value.IsEmpty())
905 value = Undefined(isolate);
906 } else if (event == v8::kPromiseHandlerAddedAfterReject) {
907 callback = env->promise_reject_handled_function();
Petka Antonov872702d2015-02-22 12:44:12908 value = Undefined(isolate);
Anatoli Papirovskid62566e2018-01-17 14:39:01909 } else {
910 UNREACHABLE();
911 }
Petka Antonov872702d2015-02-22 12:44:12912
Anatoli Papirovskid62566e2018-01-17 14:39:01913 Local<Value> args[] = { promise, value };
914 MaybeLocal<Value> ret = callback->Call(env->context(),
915 Undefined(isolate),
916 arraysize(args),
917 args);
Petka Antonov872702d2015-02-22 12:44:12918
Anatoli Papirovskid62566e2018-01-17 14:39:01919 if (!ret.IsEmpty() && ret.ToLocalChecked()->IsTrue())
920 env->tick_info()->promise_rejections_toggle_on();
Petka Antonov872702d2015-02-22 12:44:12921}
922
923void SetupPromises(const FunctionCallbackInfo<Value>& args) {
924 Environment* env = Environment::GetCurrent(args);
925 Isolate* isolate = env->isolate();
926
927 CHECK(args[0]->IsFunction());
Anatoli Papirovskid62566e2018-01-17 14:39:01928 CHECK(args[1]->IsFunction());
Petka Antonov872702d2015-02-22 12:44:12929
930 isolate->SetPromiseRejectCallback(PromiseRejectCallback);
Anatoli Papirovskid62566e2018-01-17 14:39:01931 env->set_promise_reject_unhandled_function(args[0].As<Function>());
932 env->set_promise_reject_handled_function(args[1].As<Function>());
Petka Antonov872702d2015-02-22 12:44:12933
934 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:04935 env->context(),
Daniel Beveniusc27360e2017-08-11 08:39:00936 FIXED_ONE_BYTE_STRING(isolate, "_setupPromises")).FromJust();
Petka Antonov872702d2015-02-22 12:44:12937}
938
Anna Henningsen9d522222017-04-12 17:17:24939} // anonymous namespace
940
Trevor Norris3f5d5842013-08-07 00:01:44941
Anna Henningsene5a25cb2017-04-21 21:06:21942void AddPromiseHook(v8::Isolate* isolate, promise_hook_func fn, void* arg) {
943 Environment* env = Environment::GetCurrent(isolate);
944 env->AddPromiseHook(fn, arg);
945}
946
Anna Henningsen64616bb2017-08-08 18:02:55947CallbackScope::CallbackScope(Isolate* isolate,
948 Local<Object> object,
949 async_context asyncContext)
950 : private_(new InternalCallbackScope(Environment::GetCurrent(isolate),
951 object,
952 asyncContext)),
953 try_catch_(isolate) {
954 try_catch_.SetVerbose(true);
955}
956
957CallbackScope::~CallbackScope() {
958 if (try_catch_.HasCaught())
959 private_->MarkAsFailed();
960 delete private_;
961}
962
Anna Henningsen41aaacb2017-10-24 21:22:07963InternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap)
964 : InternalCallbackScope(async_wrap->env(),
965 async_wrap->object(),
966 { async_wrap->get_async_id(),
967 async_wrap->get_trigger_async_id() }) {}
968
Anna Henningsen64616bb2017-08-08 18:02:55969InternalCallbackScope::InternalCallbackScope(Environment* env,
970 Local<Object> object,
Anna Henningsenf27b5e42017-09-15 13:03:48971 const async_context& asyncContext,
972 ResourceExpectation expect)
Anna Henningsen64616bb2017-08-08 18:02:55973 : env_(env),
974 async_context_(asyncContext),
975 object_(object),
976 callback_scope_(env) {
Anna Henningsenf27b5e42017-09-15 13:03:48977 if (expect == kRequireResource) {
978 CHECK(!object.IsEmpty());
979 }
Anna Henningsen64616bb2017-08-08 18:02:55980
Anna Henningsenf27b5e42017-09-15 13:03:48981 HandleScope handle_scope(env->isolate());
Trevor Norrisefa62fd2013-09-24 21:12:11982 // If you hit this assertion, you forgot to enter the v8::Context first.
Anna Henningsen037d9082017-09-29 21:35:43983 CHECK_EQ(Environment::GetCurrent(env->isolate()), env);
Trevor Norrisefa62fd2013-09-24 21:12:11984
vladimir51e09482017-10-10 20:40:43985 if (asyncContext.async_id == 0 && env->using_domains() &&
986 !object_.IsEmpty()) {
Anna Henningsen602fd362017-09-14 15:58:53987 DomainEnter(env, object_);
Trevor Norrisb9e60322014-12-09 04:10:44988 }
989
Anna Henningsen64616bb2017-08-08 18:02:55990 if (asyncContext.async_id != 0) {
991 // No need to check a return value because the application will exit if
992 // an exception occurs.
993 AsyncWrap::EmitBefore(env, asyncContext.async_id);
994 }
995
Andreas Madsen3a69ef52017-09-26 13:50:10996 env->async_hooks()->push_async_ids(async_context_.async_id,
Anna Henningsen64616bb2017-08-08 18:02:55997 async_context_.trigger_async_id);
998 pushed_ids_ = true;
999}
1000
1001InternalCallbackScope::~InternalCallbackScope() {
1002 Close();
1003}
1004
1005void InternalCallbackScope::Close() {
1006 if (closed_) return;
1007 closed_ = true;
Anna Henningsenf27b5e42017-09-15 13:03:481008 HandleScope handle_scope(env_->isolate());
Anna Henningsen64616bb2017-08-08 18:02:551009
1010 if (pushed_ids_)
Andreas Madsen3a69ef52017-09-26 13:50:101011 env_->async_hooks()->pop_async_id(async_context_.async_id);
Anna Henningsen64616bb2017-08-08 18:02:551012
1013 if (failed_) return;
1014
1015 if (async_context_.async_id != 0) {
1016 AsyncWrap::EmitAfter(env_, async_context_.async_id);
1017 }
1018
vladimir51e09482017-10-10 20:40:431019 if (async_context_.async_id == 0 && env_->using_domains() &&
1020 !object_.IsEmpty()) {
Anna Henningsen602fd362017-09-14 15:58:531021 DomainExit(env_, object_);
Anna Henningsen64616bb2017-08-08 18:02:551022 }
1023
1024 if (IsInnerMakeCallback()) {
1025 return;
1026 }
1027
1028 Environment::TickInfo* tick_info = env_->tick_info();
1029
Anatoli Papirovski58467862017-12-27 18:47:511030 if (!tick_info->has_scheduled()) {
Anna Henningsen64616bb2017-08-08 18:02:551031 env_->isolate()->RunMicrotasks();
1032 }
1033
1034 // Make sure the stack unwound properly. If there are nested MakeCallback's
1035 // then it should return early and not reach this code.
Andreas Madsen7c079d12017-10-19 10:43:401036 if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) {
1037 CHECK_EQ(env_->execution_async_id(), 0);
1038 CHECK_EQ(env_->trigger_async_id(), 0);
1039 }
Anna Henningsen64616bb2017-08-08 18:02:551040
Anatoli Papirovskid62566e2018-01-17 14:39:011041 if (!tick_info->has_scheduled() && !tick_info->has_promise_rejections()) {
Anna Henningsen64616bb2017-08-08 18:02:551042 return;
1043 }
1044
Andreas Madsen7c079d12017-10-19 10:43:401045 if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) {
1046 CHECK_EQ(env_->execution_async_id(), 0);
1047 CHECK_EQ(env_->trigger_async_id(), 0);
1048 }
Anna Henningsen64616bb2017-08-08 18:02:551049
Anatoli Papirovski4444b6b2017-12-18 03:45:451050 Local<Object> process = env_->process_object();
1051
Anna Henningsen64616bb2017-08-08 18:02:551052 if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
1053 failed_ = true;
1054 }
1055}
1056
1057MaybeLocal<Value> InternalMakeCallback(Environment* env,
1058 Local<Object> recv,
1059 const Local<Function> callback,
1060 int argc,
1061 Local<Value> argv[],
1062 async_context asyncContext) {
Anna Henningsenf27b5e42017-09-15 13:03:481063 CHECK(!recv.IsEmpty());
Anna Henningsen64616bb2017-08-08 18:02:551064 InternalCallbackScope scope(env, recv, asyncContext);
1065 if (scope.Failed()) {
1066 return Undefined(env->isolate());
Anna Henningsena86323d2017-05-21 17:39:521067 }
1068
1069 MaybeLocal<Value> ret;
1070
1071 {
Anna Henningsena86323d2017-05-21 17:39:521072 ret = callback->Call(env->context(), recv, argc, argv);
1073
1074 if (ret.IsEmpty()) {
1075 // NOTE: For backwards compatibility with public API we return Undefined()
1076 // if the top level call threw.
Anna Henningsen64616bb2017-08-08 18:02:551077 scope.MarkAsFailed();
1078 return scope.IsInnerMakeCallback() ? ret : Undefined(env->isolate());
Trevor Norrisa1da0242014-12-09 04:24:591079 }
1080 }
Trevor Norrisefa62fd2013-09-24 21:12:111081
Anna Henningsen64616bb2017-08-08 18:02:551082 scope.Close();
1083 if (scope.Failed()) {
Fedor Indutny75adde02014-02-21 13:02:421084 return Undefined(env->isolate());
Trevor Norris95afe282016-02-11 20:57:261085 }
Trevor Norris86c07452013-02-07 01:26:181086
Trevor Norrisa0867e12013-03-17 04:59:471087 return ret;
1088}
1089
1090
Anna Henningsena86323d2017-05-21 17:39:521091// Public MakeCallback()s
1092
1093
1094MaybeLocal<Value> MakeCallback(Isolate* isolate,
1095 Local<Object> recv,
1096 const char* method,
1097 int argc,
1098 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:031099 async_context asyncContext) {
Anna Henningsena86323d2017-05-21 17:39:521100 Local<String> method_string =
1101 String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
1102 .ToLocalChecked();
Andreas Madsenc6ce5002017-07-06 06:20:031103 return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
Trevor Norris86c07452013-02-07 01:26:181104}
1105
1106
Anna Henningsena86323d2017-05-21 17:39:521107MaybeLocal<Value> MakeCallback(Isolate* isolate,
1108 Local<Object> recv,
1109 Local<String> symbol,
1110 int argc,
1111 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:031112 async_context asyncContext) {
Ben Noordhuis921d2b02016-10-21 09:57:201113 Local<Value> callback_v = recv->Get(symbol);
1114 if (callback_v.IsEmpty()) return Local<Value>();
1115 if (!callback_v->IsFunction()) return Local<Value>();
1116 Local<Function> callback = callback_v.As<Function>();
Andreas Madsenc6ce5002017-07-06 06:20:031117 return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
Ben Noordhuis756b6222013-08-10 22:26:111118}
1119
1120
Anna Henningsena86323d2017-05-21 17:39:521121MaybeLocal<Value> MakeCallback(Isolate* isolate,
1122 Local<Object> recv,
1123 Local<Function> callback,
1124 int argc,
1125 Local<Value> argv[],
Andreas Madsenc6ce5002017-07-06 06:20:031126 async_context asyncContext) {
Ben Noordhuis921d2b02016-10-21 09:57:201127 // Observe the following two subtleties:
1128 //
1129 // 1. The environment is retrieved from the callback function's context.
1130 // 2. The context to enter is retrieved from the environment.
1131 //
1132 // Because of the AssignToContext() call in src/node_contextify.cc,
1133 // the two contexts need not be the same.
Ben Noordhuis921d2b02016-10-21 09:57:201134 Environment* env = Environment::GetCurrent(callback->CreationContext());
1135 Context::Scope context_scope(env->context());
Anna Henningsen64616bb2017-08-08 18:02:551136 return InternalMakeCallback(env, recv, callback,
1137 argc, argv, asyncContext);
Anna Henningsena86323d2017-05-21 17:39:521138}
1139
1140
1141// Legacy MakeCallback()s
1142
1143Local<Value> MakeCallback(Isolate* isolate,
1144 Local<Object> recv,
1145 const char* method,
1146 int argc,
1147 Local<Value>* argv) {
1148 EscapableHandleScope handle_scope(isolate);
Ben Noordhuis921d2b02016-10-21 09:57:201149 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:031150 MakeCallback(isolate, recv, method, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:521151 .FromMaybe(Local<Value>()));
1152}
1153
1154
1155Local<Value> MakeCallback(Isolate* isolate,
1156 Local<Object> recv,
1157 Local<String> symbol,
1158 int argc,
1159 Local<Value>* argv) {
1160 EscapableHandleScope handle_scope(isolate);
1161 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:031162 MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:521163 .FromMaybe(Local<Value>()));
1164}
1165
1166
1167Local<Value> MakeCallback(Isolate* isolate,
1168 Local<Object> recv,
1169 Local<Function> callback,
1170 int argc,
1171 Local<Value>* argv) {
1172 EscapableHandleScope handle_scope(isolate);
1173 return handle_scope.Escape(
Andreas Madsenc6ce5002017-07-06 06:20:031174 MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
Anna Henningsena86323d2017-05-21 17:39:521175 .FromMaybe(Local<Value>()));
Ben Noordhuis1f2f3fa2014-01-27 02:58:161176}
1177
1178
Fedor Indutnyc6367e72015-01-30 12:05:281179enum encoding ParseEncoding(const char* encoding,
1180 enum encoding default_encoding) {
1181 switch (encoding[0]) {
1182 case 'u':
1183 // utf8, utf16le
1184 if (encoding[1] == 't' && encoding[2] == 'f') {
1185 // Skip `-`
1186 encoding += encoding[3] == '-' ? 4 : 3;
1187 if (encoding[0] == '8' && encoding[1] == '\0')
1188 return UTF8;
1189 if (strncmp(encoding, "16le", 4) == 0)
1190 return UCS2;
Ryan Dahl07792af2009-09-21 10:27:221191
Fedor Indutnyc6367e72015-01-30 12:05:281192 // ucs2
1193 } else if (encoding[1] == 'c' && encoding[2] == 's') {
1194 encoding += encoding[3] == '-' ? 4 : 3;
1195 if (encoding[0] == '2' && encoding[1] == '\0')
1196 return UCS2;
1197 }
1198 break;
Trevor Norris54cc7212016-06-02 16:55:361199 case 'l':
1200 // latin1
1201 if (encoding[1] == 'a') {
1202 if (strncmp(encoding + 2, "tin1", 4) == 0)
1203 return LATIN1;
1204 }
Ben Noordhuis6b483242016-06-10 09:36:421205 break;
Fedor Indutnyc6367e72015-01-30 12:05:281206 case 'b':
1207 // binary
1208 if (encoding[1] == 'i') {
1209 if (strncmp(encoding + 2, "nary", 4) == 0)
Trevor Norris54cc7212016-06-02 16:55:361210 return LATIN1;
Ryan Dahl07792af2009-09-21 10:27:221211
Fedor Indutnyc6367e72015-01-30 12:05:281212 // buffer
1213 } else if (encoding[1] == 'u') {
1214 if (strncmp(encoding + 2, "ffer", 4) == 0)
1215 return BUFFER;
1216 }
1217 break;
1218 case '\0':
1219 return default_encoding;
1220 default:
1221 break;
1222 }
Ryan Dahl07792af2009-09-21 10:27:221223
Ben Noordhuisf6940df2016-05-04 18:56:041224 if (StringEqualNoCase(encoding, "utf8")) {
Ryan Dahl07792af2009-09-21 10:27:221225 return UTF8;
Ben Noordhuisf6940df2016-05-04 18:56:041226 } else if (StringEqualNoCase(encoding, "utf-8")) {
Ryan Dahl2b994d92009-10-06 08:45:181227 return UTF8;
Ben Noordhuisf6940df2016-05-04 18:56:041228 } else if (StringEqualNoCase(encoding, "ascii")) {
Ryan Dahl07792af2009-09-21 10:27:221229 return ASCII;
Ben Noordhuisf6940df2016-05-04 18:56:041230 } else if (StringEqualNoCase(encoding, "base64")) {
Ben Noordhuis95638c92010-07-28 12:20:231231 return BASE64;
Ben Noordhuisf6940df2016-05-04 18:56:041232 } else if (StringEqualNoCase(encoding, "ucs2")) {
Konstantin Käfer9e101f22011-02-06 20:49:521233 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041234 } else if (StringEqualNoCase(encoding, "ucs-2")) {
Konstantin Käfer9e101f22011-02-06 20:49:521235 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041236 } else if (StringEqualNoCase(encoding, "utf16le")) {
koichikfbb0ee62012-10-02 14:57:381237 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041238 } else if (StringEqualNoCase(encoding, "utf-16le")) {
koichikfbb0ee62012-10-02 14:57:381239 return UCS2;
Trevor Norris54cc7212016-06-02 16:55:361240 } else if (StringEqualNoCase(encoding, "latin1")) {
1241 return LATIN1;
Ben Noordhuisf6940df2016-05-04 18:56:041242 } else if (StringEqualNoCase(encoding, "binary")) {
Ben Noordhuisa92089b2016-06-13 09:37:391243 return LATIN1; // BINARY is a deprecated alias of LATIN1.
Ben Noordhuisf6940df2016-05-04 18:56:041244 } else if (StringEqualNoCase(encoding, "buffer")) {
Fedor Indutny63ff4492012-09-12 20:35:591245 return BUFFER;
Ben Noordhuisf6940df2016-05-04 18:56:041246 } else if (StringEqualNoCase(encoding, "hex")) {
isaacs0aa1a8a2011-02-20 01:29:011247 return HEX;
Ryan Dahl07792af2009-09-21 10:27:221248 } else {
Fedor Indutnyc6367e72015-01-30 12:05:281249 return default_encoding;
Ryan Dahl07792af2009-09-21 10:27:221250 }
1251}
1252
Fedor Indutnyc6367e72015-01-30 12:05:281253
1254enum encoding ParseEncoding(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:161255 Local<Value> encoding_v,
Fedor Indutnyc6367e72015-01-30 12:05:281256 enum encoding default_encoding) {
Tobias Nießen88351a22017-04-02 13:00:321257 CHECK(!encoding_v.IsEmpty());
1258
Fedor Indutnyc6367e72015-01-30 12:05:281259 if (!encoding_v->IsString())
1260 return default_encoding;
1261
1262 node::Utf8Value encoding(isolate, encoding_v);
1263
1264 return ParseEncoding(*encoding, default_encoding);
1265}
1266
Fedor Indutny75adde02014-02-21 13:02:421267Local<Value> Encode(Isolate* isolate,
Ben Noordhuis56fde662014-12-10 16:33:561268 const char* buf,
Fedor Indutny75adde02014-02-21 13:02:421269 size_t len,
1270 enum encoding encoding) {
Ben Noordhuis56fde662014-12-10 16:33:561271 CHECK_NE(encoding, UCS2);
Anna Henningsend56a7e62017-04-30 16:53:041272 Local<Value> error;
1273 return StringBytes::Encode(isolate, buf, len, encoding, &error)
1274 .ToLocalChecked();
Ben Noordhuis56fde662014-12-10 16:33:561275}
1276
1277Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
Anna Henningsend56a7e62017-04-30 16:53:041278 Local<Value> error;
1279 return StringBytes::Encode(isolate, buf, len, &error)
1280 .ToLocalChecked();
Ryan21a1b042009-09-09 13:51:491281}
1282
Ryand6c9d312009-09-11 14:02:291283// Returns -1 if the handle was not valid for decoding
Fedor Indutny75adde02014-02-21 13:02:421284ssize_t DecodeBytes(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:161285 Local<Value> val,
Fedor Indutny75adde02014-02-21 13:02:421286 enum encoding encoding) {
1287 HandleScope scope(isolate);
Ryan21a1b042009-09-09 13:51:491288
Fedor Indutny75adde02014-02-21 13:02:421289 return StringBytes::Size(isolate, val, encoding);
Ryan21a1b042009-09-09 13:51:491290}
1291
Ryan21a1b042009-09-09 13:51:491292// Returns number of bytes written.
Fedor Indutny75adde02014-02-21 13:02:421293ssize_t DecodeWrite(Isolate* isolate,
1294 char* buf,
Ryan Dahl53530e92010-04-02 21:55:281295 size_t buflen,
Michaël Zasso4abc8962015-07-18 09:34:161296 Local<Value> val,
Ryand6c9d312009-09-11 14:02:291297 enum encoding encoding) {
Ben Noordhuis2d82cdf2014-10-22 01:29:321298 return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
Ryan21a1b042009-09-09 13:51:491299}
1300
Brian White18490d32015-12-15 08:55:351301bool IsExceptionDecorated(Environment* env, Local<Value> er) {
1302 if (!er.IsEmpty() && er->IsObject()) {
1303 Local<Object> err_obj = er.As<Object>();
Ben Noordhuis924cc6c2016-02-02 22:50:071304 auto maybe_value =
1305 err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1306 Local<Value> decorated;
1307 return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
Brian White18490d32015-12-15 08:55:351308 }
1309 return false;
1310}
1311
Fedor Indutnyf1de13b2014-02-05 16:38:331312void AppendExceptionLine(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161313 Local<Value> er,
Anna Henningsen3cac6162016-06-24 03:50:001314 Local<Message> message,
1315 enum ErrorHandlingMode mode) {
Fedor Indutnyf1de13b2014-02-05 16:38:331316 if (message.IsEmpty())
Fedor Indutny2bc30f22013-10-16 16:57:261317 return;
isaacsb3cf3f32012-07-28 21:00:271318
Fedor Indutnyf1de13b2014-02-05 16:38:331319 HandleScope scope(env->isolate());
1320 Local<Object> err_obj;
1321 if (!er.IsEmpty() && er->IsObject()) {
1322 err_obj = er.As<Object>();
Ryan Dahl8e6dd522010-01-15 18:45:041323 }
Fedor Indutnyf1de13b2014-02-05 16:38:331324
Fedor Indutnyf1de13b2014-02-05 16:38:331325 // Print (filename):(line number): (message).
Timothy Gu3aea4c82017-10-04 03:51:121326 ScriptOrigin origin = message->GetScriptOrigin();
Trevor Norriscbf76c12015-01-07 22:13:351327 node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
Fedor Indutnyf1de13b2014-02-05 16:38:331328 const char* filename_string = *filename;
1329 int linenum = message->GetLineNumber();
1330 // Print line of source code.
Trevor Norriscbf76c12015-01-07 22:13:351331 node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
Fedor Indutnyf1de13b2014-02-05 16:38:331332 const char* sourceline_string = *sourceline;
Anna Henningsenb73e66e2017-11-29 19:55:431333 if (strstr(sourceline_string, "node-do-not-add-exception-line") != nullptr)
1334 return;
Fedor Indutnyf1de13b2014-02-05 16:38:331335
1336 // Because of how node modules work, all scripts are wrapped with a
1337 // "function (module, exports, __filename, ...) {"
1338 // to provide script local variables.
1339 //
1340 // When reporting errors on the first line of a script, this wrapper
1341 // function is leaked to the user. There used to be a hack here to
1342 // truncate off the first 62 characters, but it caused numerous other
1343 // problems when vm.runIn*Context() methods were used for non-module
1344 // code.
1345 //
1346 // If we ever decide to re-instate such a hack, the following steps
1347 // must be taken:
1348 //
1349 // 1. Pass a flag around to say "this code was wrapped"
1350 // 2. Update the stack frame output so that it is also correct.
1351 //
1352 // It would probably be simpler to add a line rather than add some
1353 // number of characters to the first line, since V8 truncates the
1354 // sourceline to 78 characters, and we end up not providing very much
1355 // useful debugging info to the user if we remove 62 characters.
1356
Timothy Gu3aea4c82017-10-04 03:51:121357 int script_start =
1358 (linenum - origin.ResourceLineOffset()->Value()) == 1 ?
1359 origin.ResourceColumnOffset()->Value() : 0;
Anna Henningsen4bd410b2016-05-20 20:55:371360 int start = message->GetStartColumn(env->context()).FromMaybe(0);
1361 int end = message->GetEndColumn(env->context()).FromMaybe(0);
Timothy Gu3aea4c82017-10-04 03:51:121362 if (start >= script_start) {
1363 CHECK_GE(end, start);
1364 start -= script_start;
1365 end -= script_start;
1366 }
Fedor Indutnyf1de13b2014-02-05 16:38:331367
Karl Skomski3bb92372015-09-03 08:10:291368 char arrow[1024];
1369 int max_off = sizeof(arrow) - 2;
1370
Fedor Indutnyf1de13b2014-02-05 16:38:331371 int off = snprintf(arrow,
1372 sizeof(arrow),
1373 "%s:%i\n%s\n",
1374 filename_string,
1375 linenum,
1376 sourceline_string);
Ben Noordhuis5fdff382014-10-11 14:52:071377 CHECK_GE(off, 0);
Karl Skomski3bb92372015-09-03 08:10:291378 if (off > max_off) {
1379 off = max_off;
1380 }
Fedor Indutnyf1de13b2014-02-05 16:38:331381
1382 // Print wavy underline (GetUnderline is deprecated).
1383 for (int i = 0; i < start; i++) {
Karl Skomski3bb92372015-09-03 08:10:291384 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:501385 break;
1386 }
Karl Skomski3bb92372015-09-03 08:10:291387 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:331388 arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1389 }
1390 for (int i = start; i < end; i++) {
Karl Skomski3bb92372015-09-03 08:10:291391 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:501392 break;
1393 }
Karl Skomski3bb92372015-09-03 08:10:291394 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:331395 arrow[off++] = '^';
1396 }
Karl Skomski3bb92372015-09-03 08:10:291397 CHECK_LE(off, max_off);
1398 arrow[off] = '\n';
1399 arrow[off + 1] = '\0';
Fedor Indutnyf1de13b2014-02-05 16:38:331400
1401 Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
Fedor Indutnyf1de13b2014-02-05 16:38:331402
Anna Henningsen3cac6162016-06-24 03:50:001403 const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1404 // If allocating arrow_str failed, print it out. There's not much else to do.
1405 // If it's not an error, but something needs to be printed out because
1406 // it's a fatal exception, also print it out from here.
1407 // Otherwise, the arrow property will be attached to the object and handled
1408 // by the caller.
1409 if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1410 if (env->printed_error())
1411 return;
1412 env->set_printed_error(true);
1413
1414 uv_tty_reset_mode();
1415 PrintErrorString("\n%s", arrow);
Ben Noordhuis924cc6c2016-02-02 22:50:071416 return;
1417 }
Fedor Indutnyf1de13b2014-02-05 16:38:331418
Anna Henningsen3cac6162016-06-24 03:50:001419 CHECK(err_obj->SetPrivate(
1420 env->context(),
1421 env->arrow_message_private_symbol(),
1422 arrow_str).FromMaybe(false));
Ryan Dahlb57c1f52010-11-24 02:46:131423}
1424
1425
Fedor Indutnyf1de13b2014-02-05 16:38:331426static void ReportException(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161427 Local<Value> er,
1428 Local<Message> message) {
Anna Henningsena0126722017-11-27 00:31:241429 CHECK(!er.IsEmpty());
1430 CHECK(!message.IsEmpty());
Fedor Indutnyf1de13b2014-02-05 16:38:331431 HandleScope scope(env->isolate());
Ryan Dahlb57c1f52010-11-24 02:46:131432
Anna Henningsen3cac6162016-06-24 03:50:001433 AppendExceptionLine(env, er, message, FATAL_ERROR);
Ryan Dahl53a841d2009-12-29 19:20:511434
Vladimir Kurchatkin259d4492013-12-06 11:56:371435 Local<Value> trace_value;
Fedor Indutnyef653212015-07-05 18:20:261436 Local<Value> arrow;
Brian White18490d32015-12-15 08:55:351437 const bool decorated = IsExceptionDecorated(env, er);
Vladimir Kurchatkin259d4492013-12-06 11:56:371438
Fedor Indutnyef653212015-07-05 18:20:261439 if (er->IsUndefined() || er->IsNull()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331440 trace_value = Undefined(env->isolate());
Fedor Indutnyef653212015-07-05 18:20:261441 } else {
Leko19221d12017-11-27 07:16:321442 Local<Object> err_obj = er->ToObject(env->context()).ToLocalChecked();
Fedor Indutnyef653212015-07-05 18:20:261443
1444 trace_value = err_obj->Get(env->stack_string());
Ben Noordhuis924cc6c2016-02-02 22:50:071445 arrow =
1446 err_obj->GetPrivate(
1447 env->context(),
1448 env->arrow_message_private_symbol()).ToLocalChecked();
Fedor Indutnyef653212015-07-05 18:20:261449 }
Vladimir Kurchatkin259d4492013-12-06 11:56:371450
Trevor Norriscbf76c12015-01-07 22:13:351451 node::Utf8Value trace(env->isolate(), trace_value);
Ryan Dahlda932302010-05-14 18:48:141452
isaacs8df6f9e2011-04-25 19:22:181453 // range errors have a trace member set to undefined
Miroslav Bajtosc16963b2013-06-17 19:19:591454 if (trace.length() > 0 && !trace_value->IsUndefined()) {
Brian White18490d32015-12-15 08:55:351455 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:151456 PrintErrorString("%s\n", *trace);
Fedor Indutnyef653212015-07-05 18:20:261457 } else {
1458 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:151459 PrintErrorString("%s\n%s\n", *arrow_string, *trace);
Fedor Indutnyef653212015-07-05 18:20:261460 }
isaacse9b6b0b2010-10-02 06:22:341461 } else {
1462 // this really only happens for RangeErrors, since they're the only
isaacs8df6f9e2011-04-25 19:22:181463 // kind that won't have all this info in the trace, or when non-Error
1464 // objects are thrown manually.
Ben Noordhuisf674b092013-08-07 19:50:411465 Local<Value> message;
1466 Local<Value> name;
isaacs8df6f9e2011-04-25 19:22:181467
Ben Noordhuisf674b092013-08-07 19:50:411468 if (er->IsObject()) {
1469 Local<Object> err_obj = er.As<Object>();
Fedor Indutnyf1de13b2014-02-05 16:38:331470 message = err_obj->Get(env->message_string());
1471 name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
isaacs8df6f9e2011-04-25 19:22:181472 }
1473
Ben Noordhuisf674b092013-08-07 19:50:411474 if (message.IsEmpty() ||
1475 message->IsUndefined() ||
1476 name.IsEmpty() ||
1477 name->IsUndefined()) {
1478 // Not an error object. Just print as-is.
cjihrig1ec09b02015-12-02 01:34:451479 String::Utf8Value message(er);
1480
1481 PrintErrorString("%s\n", *message ? *message :
1482 "<toString() threw exception>");
Ben Noordhuisf674b092013-08-07 19:50:411483 } else {
Trevor Norriscbf76c12015-01-07 22:13:351484 node::Utf8Value name_string(env->isolate(), name);
1485 node::Utf8Value message_string(env->isolate(), message);
Fedor Indutnyef653212015-07-05 18:20:261486
Brian White18490d32015-12-15 08:55:351487 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:151488 PrintErrorString("%s: %s\n", *name_string, *message_string);
Fedor Indutnyef653212015-07-05 18:20:261489 } else {
1490 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:151491 PrintErrorString("%s\n%s: %s\n",
1492 *arrow_string,
1493 *name_string,
1494 *message_string);
Fedor Indutnyef653212015-07-05 18:20:261495 }
Ben Noordhuisf674b092013-08-07 19:50:411496 }
Ryan5131e0a2009-03-09 00:23:411497 }
isaacse9b6b0b2010-10-02 06:22:341498
Ryand7e220c2009-09-09 20:35:401499 fflush(stderr);
Anna Henningsena0126722017-11-27 00:31:241500
1501#if HAVE_INSPECTOR
1502 env->inspector_agent()->FatalException(er, message);
1503#endif
Ryan5131e0a2009-03-09 00:23:411504}
1505
Miroslav Bajtosc16963b2013-06-17 19:19:591506
Fedor Indutnyf1de13b2014-02-05 16:38:331507static void ReportException(Environment* env, const TryCatch& try_catch) {
1508 ReportException(env, try_catch.Exception(), try_catch.Message());
Miroslav Bajtosc16963b2013-06-17 19:19:591509}
1510
1511
Ryand6c9d312009-09-11 14:02:291512// Executes a str within the current v8 context.
Fedor Indutnyf1de13b2014-02-05 16:38:331513static Local<Value> ExecuteString(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161514 Local<String> source,
1515 Local<String> filename) {
Fedor Indutnyce04c722014-03-13 16:38:141516 EscapableHandleScope scope(env->isolate());
Michaël Zasso79d74752016-01-26 08:06:431517 TryCatch try_catch(env->isolate());
Ryan408526a2009-04-21 11:52:211518
Miroslav Bajtosc16963b2013-06-17 19:19:591519 // try_catch must be nonverbose to disable FatalException() handler,
1520 // we will handle exceptions ourself.
1521 try_catch.SetVerbose(false);
1522
Michaël Zasso023c3172016-02-08 21:34:051523 ScriptOrigin origin(filename);
1524 MaybeLocal<v8::Script> script =
1525 v8::Script::Compile(env->context(), source, &origin);
Ryan63a9cd32009-04-15 08:08:281526 if (script.IsEmpty()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331527 ReportException(env, try_catch);
isaacs95862b22013-02-27 19:23:201528 exit(3);
Ryan63a9cd32009-04-15 08:08:281529 }
1530
Michaël Zasso023c3172016-02-08 21:34:051531 Local<Value> result = script.ToLocalChecked()->Run();
Ryan63a9cd32009-04-15 08:08:281532 if (result.IsEmpty()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331533 ReportException(env, try_catch);
isaacs95862b22013-02-27 19:23:201534 exit(4);
Ryan63a9cd32009-04-15 08:08:281535 }
1536
Fedor Indutnyce04c722014-03-13 16:38:141537 return scope.Escape(result);
Ryan63a9cd32009-04-15 08:08:281538}
1539
Felix Geisendörfer7371fcb2009-11-11 17:10:581540
Ben Noordhuis110a9cd2013-07-03 02:23:441541static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551542 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101543
Fedor Indutnyce04c722014-03-13 16:38:141544 Local<Array> ary = Array::New(args.GetIsolate());
Trevor Norris494227b2015-10-14 20:58:521545 Local<Context> ctx = env->context();
Trevor Norris83524b32015-11-10 09:58:511546 Local<Function> fn = env->push_values_to_array_function();
Trevor Norris946315f2015-11-11 00:04:561547 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1548 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101549
Trevor Norris494227b2015-10-14 20:58:521550 for (auto w : *env->req_wrap_queue()) {
Trevor Norris946315f2015-11-11 00:04:561551 if (w->persistent().IsEmpty())
1552 continue;
1553 argv[idx] = w->object();
Ben Noordhuisa7581d02016-03-31 10:47:061554 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561555 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1556 idx = 0;
Trevor Norris494227b2015-10-14 20:58:521557 }
1558 }
1559
Trevor Norris946315f2015-11-11 00:04:561560 if (idx > 0) {
1561 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Trevor Norris494227b2015-10-14 20:58:521562 }
Ben Noordhuis5f040652012-04-28 16:45:101563
Ben Noordhuis110a9cd2013-07-03 02:23:441564 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101565}
1566
1567
1568// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1569// implemented here for consistency with GetActiveRequests().
Ben Noordhuis110a9cd2013-07-03 02:23:441570void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551571 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101572
Fedor Indutnyce04c722014-03-13 16:38:141573 Local<Array> ary = Array::New(env->isolate());
Trevor Norris946315f2015-11-11 00:04:561574 Local<Context> ctx = env->context();
1575 Local<Function> fn = env->push_values_to_array_function();
1576 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1577 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101578
Fedor Indutny75adde02014-02-21 13:02:421579 Local<String> owner_sym = env->owner_string();
Ben Noordhuise813e342012-05-15 15:24:061580
Ben Noordhuis38dc0cd2015-01-30 11:54:531581 for (auto w : *env->handle_wrap_queue()) {
Ben Noordhuiscad1a622016-04-26 10:01:461582 if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
Fedor Indutny2bc30f22013-10-16 16:57:261583 continue;
Ben Noordhuis110a9cd2013-07-03 02:23:441584 Local<Object> object = w->object();
1585 Local<Value> owner = object->Get(owner_sym);
Fedor Indutny2bc30f22013-10-16 16:57:261586 if (owner->IsUndefined())
1587 owner = object;
Trevor Norris946315f2015-11-11 00:04:561588 argv[idx] = owner;
Ben Noordhuisa7581d02016-03-31 10:47:061589 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561590 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1591 idx = 0;
1592 }
1593 }
1594 if (idx > 0) {
1595 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Ben Noordhuis5f040652012-04-28 16:45:101596 }
1597
Ben Noordhuis110a9cd2013-07-03 02:23:441598 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101599}
1600
1601
Ben Noordhuisbe767cf2016-06-19 08:44:221602NO_RETURN void Abort() {
1603 DumpBacktrace(stderr);
1604 fflush(stderr);
1605 ABORT_NO_BACKTRACE();
1606}
1607
1608
Ben Noordhuis92dab4a2016-06-19 10:10:451609NO_RETURN void Assert(const char* const (*args)[4]) {
1610 auto filename = (*args)[0];
1611 auto linenum = (*args)[1];
1612 auto message = (*args)[2];
1613 auto function = (*args)[3];
1614
Ben Noordhuisf526deb2017-11-20 22:37:501615 char name[1024];
1616 GetHumanReadableProcessName(&name);
Ben Noordhuis92dab4a2016-06-19 10:10:451617
Ben Noordhuisf526deb2017-11-20 22:37:501618 fprintf(stderr, "%s: %s:%s:%s%s Assertion `%s' failed.\n",
1619 name, filename, linenum, function, *function ? ":" : "", message);
Ben Noordhuis92dab4a2016-06-19 10:10:451620 fflush(stderr);
1621
1622 Abort();
1623}
1624
1625
Ben Noordhuis110a9cd2013-07-03 02:23:441626static void Abort(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisbe767cf2016-06-19 08:44:221627 Abort();
Robert Mustacchi22404862011-12-15 01:02:151628}
1629
1630
Ben Noordhuis110a9cd2013-07-03 02:23:441631static void Chdir(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551632 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb20c3432010-02-12 05:55:081633
Brandon Beacher47fcf782009-11-03 18:13:381634 if (args.Length() != 1 || !args[0]->IsString()) {
Caitlin Potterbe2404e2015-01-09 16:38:281635 return env->ThrowTypeError("Bad argument.");
Brandon Beacher47fcf782009-11-03 18:13:381636 }
Ryan Dahlb20c3432010-02-12 05:55:081637
Trevor Norriscbf76c12015-01-07 22:13:351638 node::Utf8Value path(args.GetIsolate(), args[0]);
Ben Noordhuisca9eb712013-07-18 21:18:501639 int err = uv_chdir(*path);
1640 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421641 return env->ThrowUVException(err, "uv_chdir");
Brandon Beacher47fcf782009-11-03 18:13:381642 }
Brandon Beacher47fcf782009-11-03 18:13:381643}
1644
Bert Beldercbcf4fe2011-11-24 01:19:541645
Ben Noordhuis110a9cd2013-07-03 02:23:441646static void Cwd(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551647 Environment* env = Environment::GetCurrent(args);
Bert Beldere84edd22011-12-01 23:24:441648#ifdef _WIN32
1649 /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261650 char buf[MAX_PATH * 4];
Bert Beldere84edd22011-12-01 23:24:441651#else
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261652 char buf[PATH_MAX];
Bert Beldere84edd22011-12-01 23:24:441653#endif
Michael Carter8ea6adc2009-09-01 09:39:301654
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261655 size_t cwd_len = sizeof(buf);
1656 int err = uv_cwd(buf, &cwd_len);
Ben Noordhuisca9eb712013-07-18 21:18:501657 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421658 return env->ThrowUVException(err, "uv_cwd");
Michael Carter8ea6adc2009-09-01 09:39:301659 }
Peter Griess4e3c5d82010-07-12 15:47:451660
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261661 Local<String> cwd = String::NewFromUtf8(env->isolate(),
1662 buf,
1663 String::kNormalString,
Saúl Ibarra Corretgée46cbaa2014-10-17 07:31:591664 cwd_len);
Ben Noordhuis110a9cd2013-07-03 02:23:441665 args.GetReturnValue().Set(cwd);
Michael Carter8ea6adc2009-09-01 09:39:301666}
1667
Bert Beldere84edd22011-12-01 23:24:441668
Ben Noordhuis110a9cd2013-07-03 02:23:441669static void Umask(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551670 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis110a9cd2013-07-03 02:23:441671 uint32_t old;
isaacs5f2e9092011-01-25 18:40:121672
Ryan Dahlacc120a2011-08-09 20:53:561673 if (args.Length() < 1 || args[0]->IsUndefined()) {
Rasmus Andersson374300c2010-02-27 17:18:411674 old = umask(0);
Ben Noordhuis110a9cd2013-07-03 02:23:441675 umask(static_cast<mode_t>(old));
Fedor Indutny8e29ce92013-07-31 18:07:291676 } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421677 return env->ThrowTypeError("argument must be an integer or octal string.");
isaacs5f2e9092011-01-25 18:40:121678 } else {
1679 int oct;
Fedor Indutny8e29ce92013-07-31 18:07:291680 if (args[0]->IsInt32()) {
isaacs5f2e9092011-01-25 18:40:121681 oct = args[0]->Uint32Value();
1682 } else {
1683 oct = 0;
Trevor Norriscbf76c12015-01-07 22:13:351684 node::Utf8Value str(env->isolate(), args[0]);
isaacs5f2e9092011-01-25 18:40:121685
1686 // Parse the octal string.
Timothy J Fontaine1a09da62014-06-10 23:36:041687 for (size_t i = 0; i < str.length(); i++) {
isaacs5f2e9092011-01-25 18:40:121688 char c = (*str)[i];
1689 if (c > '7' || c < '0') {
Fedor Indutny75adde02014-02-21 13:02:421690 return env->ThrowTypeError("invalid octal string");
isaacs5f2e9092011-01-25 18:40:121691 }
1692 oct *= 8;
1693 oct += c - '0';
1694 }
1695 }
1696 old = umask(static_cast<mode_t>(oct));
Friedemann Altrock0433d822009-11-22 18:52:521697 }
isaacs5f2e9092011-01-25 18:40:121698
Ben Noordhuis110a9cd2013-07-03 02:23:441699 args.GetReturnValue().Set(old);
Friedemann Altrock0433d822009-11-22 18:52:521700}
1701
Michael Cartera3860762010-02-08 06:13:101702
Ed Schouten78dbcbe2017-10-30 10:58:131703#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ryan Dahlacc120a2011-08-09 20:53:561704
Ben Noordhuis3ece1302012-12-04 05:36:231705static const uid_t uid_not_found = static_cast<uid_t>(-1);
1706static const gid_t gid_not_found = static_cast<gid_t>(-1);
1707
1708
1709static uid_t uid_by_name(const char* name) {
1710 struct passwd pwd;
1711 struct passwd* pp;
1712 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231713
1714 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321715 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231716
Ben Noordhuis2d82cdf2014-10-22 01:29:321717 if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231718 return pp->pw_uid;
1719 }
1720
1721 return uid_not_found;
1722}
1723
1724
1725static char* name_by_uid(uid_t uid) {
1726 struct passwd pwd;
1727 struct passwd* pp;
1728 char buf[8192];
1729 int rc;
1730
1731 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321732 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231733
Ben Noordhuis2d82cdf2014-10-22 01:29:321734 if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1735 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231736 return strdup(pp->pw_name);
1737 }
1738
1739 if (rc == 0) {
1740 errno = ENOENT;
1741 }
1742
Ben Noordhuis2d82cdf2014-10-22 01:29:321743 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231744}
1745
1746
1747static gid_t gid_by_name(const char* name) {
1748 struct group pwd;
1749 struct group* pp;
1750 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231751
1752 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321753 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231754
Ben Noordhuis2d82cdf2014-10-22 01:29:321755 if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231756 return pp->gr_gid;
1757 }
1758
1759 return gid_not_found;
1760}
1761
1762
1763#if 0 // For future use.
1764static const char* name_by_gid(gid_t gid) {
1765 struct group pwd;
1766 struct group* pp;
1767 char buf[8192];
1768 int rc;
1769
1770 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321771 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231772
Ben Noordhuis2d82cdf2014-10-22 01:29:321773 if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1774 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231775 return strdup(pp->gr_name);
1776 }
1777
1778 if (rc == 0) {
1779 errno = ENOENT;
1780 }
1781
Ben Noordhuis2d82cdf2014-10-22 01:29:321782 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231783}
1784#endif
1785
1786
Michaël Zasso4abc8962015-07-18 09:34:161787static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:231788 if (value->IsUint32()) {
1789 return static_cast<uid_t>(value->Uint32Value());
1790 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141791 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:231792 return uid_by_name(*name);
1793 }
1794}
1795
1796
Michaël Zasso4abc8962015-07-18 09:34:161797static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:231798 if (value->IsUint32()) {
1799 return static_cast<gid_t>(value->Uint32Value());
1800 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141801 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:231802 return gid_by_name(*name);
1803 }
1804}
1805
Ben Noordhuis110a9cd2013-07-03 02:23:441806static void GetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:081807 // uid_t is an uint32_t on all supported platforms.
1808 args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
Michael Cartera3860762010-02-08 06:13:101809}
1810
Ryan Dahlacc120a2011-08-09 20:53:561811
Ben Noordhuis110a9cd2013-07-03 02:23:441812static void GetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:081813 // gid_t is an uint32_t on all supported platforms.
1814 args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
James Duncandf1c1e52010-02-23 22:45:021815}
1816
1817
Evan Lucas3c92ca22015-04-27 16:24:191818static void GetEUid(const FunctionCallbackInfo<Value>& args) {
1819 // uid_t is an uint32_t on all supported platforms.
1820 args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
1821}
1822
1823
1824static void GetEGid(const FunctionCallbackInfo<Value>& args) {
1825 // gid_t is an uint32_t on all supported platforms.
1826 args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
1827}
1828
1829
Ben Noordhuis110a9cd2013-07-03 02:23:441830static void SetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551831 Environment* env = Environment::GetCurrent(args);
Ryan Dahl39943402010-03-15 19:49:401832
Ben Noordhuis3ece1302012-12-04 05:36:231833 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421834 return env->ThrowTypeError("setgid argument must be a number or a string");
James Duncandf1c1e52010-02-23 22:45:021835 }
1836
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141837 gid_t gid = gid_by_name(env->isolate(), args[0]);
Blake Mizerany8c853402010-06-30 06:12:461838
Ben Noordhuis3ece1302012-12-04 05:36:231839 if (gid == gid_not_found) {
Fedor Indutny75adde02014-02-21 13:02:421840 return env->ThrowError("setgid group id does not exist");
Peter Griess2420f072010-05-19 00:40:441841 }
1842
Ben Noordhuis3ece1302012-12-04 05:36:231843 if (setgid(gid)) {
Fedor Indutny75adde02014-02-21 13:02:421844 return env->ThrowErrnoException(errno, "setgid");
James Duncandf1c1e52010-02-23 22:45:021845 }
James Duncandf1c1e52010-02-23 22:45:021846}
Michael Cartera3860762010-02-08 06:13:101847
Ryan Dahlacc120a2011-08-09 20:53:561848
Evan Lucas3c92ca22015-04-27 16:24:191849static void SetEGid(const FunctionCallbackInfo<Value>& args) {
1850 Environment* env = Environment::GetCurrent(args);
1851
1852 if (!args[0]->IsUint32() && !args[0]->IsString()) {
1853 return env->ThrowTypeError("setegid argument must be a number or string");
1854 }
1855
1856 gid_t gid = gid_by_name(env->isolate(), args[0]);
1857
1858 if (gid == gid_not_found) {
1859 return env->ThrowError("setegid group id does not exist");
1860 }
1861
1862 if (setegid(gid)) {
1863 return env->ThrowErrnoException(errno, "setegid");
1864 }
1865}
1866
1867
Ben Noordhuis110a9cd2013-07-03 02:23:441868static void SetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551869 Environment* env = Environment::GetCurrent(args);
Michael Cartera3860762010-02-08 06:13:101870
Ben Noordhuis3ece1302012-12-04 05:36:231871 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421872 return env->ThrowTypeError("setuid argument must be a number or a string");
Michael Cartera3860762010-02-08 06:13:101873 }
1874
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141875 uid_t uid = uid_by_name(env->isolate(), args[0]);
Peter Griess2420f072010-05-19 00:40:441876
Ben Noordhuis3ece1302012-12-04 05:36:231877 if (uid == uid_not_found) {
Fedor Indutny75adde02014-02-21 13:02:421878 return env->ThrowError("setuid user id does not exist");
Peter Griess2420f072010-05-19 00:40:441879 }
1880
Ben Noordhuis3ece1302012-12-04 05:36:231881 if (setuid(uid)) {
Fedor Indutny75adde02014-02-21 13:02:421882 return env->ThrowErrnoException(errno, "setuid");
Michael Cartera3860762010-02-08 06:13:101883 }
Michael Cartera3860762010-02-08 06:13:101884}
1885
Ryan Dahlacc120a2011-08-09 20:53:561886
Evan Lucas3c92ca22015-04-27 16:24:191887static void SetEUid(const FunctionCallbackInfo<Value>& args) {
1888 Environment* env = Environment::GetCurrent(args);
1889
1890 if (!args[0]->IsUint32() && !args[0]->IsString()) {
1891 return env->ThrowTypeError("seteuid argument must be a number or string");
1892 }
1893
1894 uid_t uid = uid_by_name(env->isolate(), args[0]);
1895
1896 if (uid == uid_not_found) {
1897 return env->ThrowError("seteuid user id does not exist");
1898 }
1899
1900 if (seteuid(uid)) {
1901 return env->ThrowErrnoException(errno, "seteuid");
1902 }
1903}
1904
1905
Ben Noordhuis110a9cd2013-07-03 02:23:441906static void GetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551907 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231908
Ben Noordhuis2d82cdf2014-10-22 01:29:321909 int ngroups = getgroups(0, nullptr);
Ben Noordhuis3ece1302012-12-04 05:36:231910
1911 if (ngroups == -1) {
Fedor Indutny75adde02014-02-21 13:02:421912 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231913 }
1914
1915 gid_t* groups = new gid_t[ngroups];
1916
1917 ngroups = getgroups(ngroups, groups);
1918
1919 if (ngroups == -1) {
1920 delete[] groups;
Fedor Indutny75adde02014-02-21 13:02:421921 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231922 }
1923
Fedor Indutnyce04c722014-03-13 16:38:141924 Local<Array> groups_list = Array::New(env->isolate(), ngroups);
Ben Noordhuis3ece1302012-12-04 05:36:231925 bool seen_egid = false;
1926 gid_t egid = getegid();
1927
1928 for (int i = 0; i < ngroups; i++) {
Fedor Indutnyce04c722014-03-13 16:38:141929 groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
Fedor Indutny2bc30f22013-10-16 16:57:261930 if (groups[i] == egid)
1931 seen_egid = true;
Ben Noordhuis3ece1302012-12-04 05:36:231932 }
1933
1934 delete[] groups;
1935
1936 if (seen_egid == false) {
Fedor Indutnyce04c722014-03-13 16:38:141937 groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
Ben Noordhuis3ece1302012-12-04 05:36:231938 }
1939
Ben Noordhuis110a9cd2013-07-03 02:23:441940 args.GetReturnValue().Set(groups_list);
Ben Noordhuis3ece1302012-12-04 05:36:231941}
1942
1943
Ben Noordhuis110a9cd2013-07-03 02:23:441944static void SetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551945 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231946
1947 if (!args[0]->IsArray()) {
Fedor Indutny75adde02014-02-21 13:02:421948 return env->ThrowTypeError("argument 1 must be an array");
Ben Noordhuis3ece1302012-12-04 05:36:231949 }
1950
1951 Local<Array> groups_list = args[0].As<Array>();
1952 size_t size = groups_list->Length();
1953 gid_t* groups = new gid_t[size];
1954
1955 for (size_t i = 0; i < size; i++) {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:141956 gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
Ben Noordhuis3ece1302012-12-04 05:36:231957
1958 if (gid == gid_not_found) {
1959 delete[] groups;
Fedor Indutny75adde02014-02-21 13:02:421960 return env->ThrowError("group name not found");
Ben Noordhuis3ece1302012-12-04 05:36:231961 }
1962
1963 groups[i] = gid;
1964 }
1965
1966 int rc = setgroups(size, groups);
1967 delete[] groups;
1968
1969 if (rc == -1) {
Fedor Indutny75adde02014-02-21 13:02:421970 return env->ThrowErrnoException(errno, "setgroups");
Ben Noordhuis3ece1302012-12-04 05:36:231971 }
Ben Noordhuis3ece1302012-12-04 05:36:231972}
1973
1974
Ben Noordhuis110a9cd2013-07-03 02:23:441975static void InitGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551976 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:231977
1978 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421979 return env->ThrowTypeError("argument 1 must be a number or a string");
Ben Noordhuis3ece1302012-12-04 05:36:231980 }
1981
1982 if (!args[1]->IsUint32() && !args[1]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421983 return env->ThrowTypeError("argument 2 must be a number or a string");
Ben Noordhuis3ece1302012-12-04 05:36:231984 }
1985
Trevor Norriscbf76c12015-01-07 22:13:351986 node::Utf8Value arg0(env->isolate(), args[0]);
Ben Noordhuis3ece1302012-12-04 05:36:231987 gid_t extra_group;
1988 bool must_free;
1989 char* user;
1990
1991 if (args[0]->IsUint32()) {
1992 user = name_by_uid(args[0]->Uint32Value());
1993 must_free = true;
1994 } else {
1995 user = *arg0;
1996 must_free = false;
1997 }
1998
Ben Noordhuis2d82cdf2014-10-22 01:29:321999 if (user == nullptr) {
Fedor Indutny75adde02014-02-21 13:02:422000 return env->ThrowError("initgroups user not found");
Ben Noordhuis3ece1302012-12-04 05:36:232001 }
2002
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142003 extra_group = gid_by_name(env->isolate(), args[1]);
Ben Noordhuis3ece1302012-12-04 05:36:232004
2005 if (extra_group == gid_not_found) {
Fedor Indutny2bc30f22013-10-16 16:57:262006 if (must_free)
2007 free(user);
Fedor Indutny75adde02014-02-21 13:02:422008 return env->ThrowError("initgroups extra group not found");
Ben Noordhuis3ece1302012-12-04 05:36:232009 }
2010
2011 int rc = initgroups(user, extra_group);
2012
2013 if (must_free) {
2014 free(user);
2015 }
2016
2017 if (rc) {
Fedor Indutny75adde02014-02-21 13:02:422018 return env->ThrowErrnoException(errno, "initgroups");
Ben Noordhuis3ece1302012-12-04 05:36:232019 }
Ben Noordhuis3ece1302012-12-04 05:36:232020}
2021
Ed Schouten78dbcbe2017-10-30 10:58:132022#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
Bert Belder30bab522010-11-25 00:09:062023
Michael Cartera3860762010-02-08 06:13:102024
Eugene Ostroukhov66269192016-06-08 21:09:282025static void WaitForInspectorDisconnect(Environment* env) {
2026#if HAVE_INSPECTOR
Eugene Ostroukhov73ad3f92017-11-11 00:01:002027 if (env->inspector_agent()->delegate() != nullptr) {
Eugene Ostroukhov66269192016-06-08 21:09:282028 // Restore signal dispositions, the app is done and is no longer
2029 // capable of handling signals.
Stewart X Addison0f0f3d32016-12-30 12:44:462030#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
Eugene Ostroukhov66269192016-06-08 21:09:282031 struct sigaction act;
2032 memset(&act, 0, sizeof(act));
2033 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2034 if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2035 continue;
2036 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2037 CHECK_EQ(0, sigaction(nr, &act, nullptr));
2038 }
2039#endif
2040 env->inspector_agent()->WaitForDisconnect();
2041 }
2042#endif
2043}
2044
2045
Anna Henningsen9d522222017-04-12 17:17:242046static void Exit(const FunctionCallbackInfo<Value>& args) {
Eugene Ostroukhov66269192016-06-08 21:09:282047 WaitForInspectorDisconnect(Environment::GetCurrent(args));
Andreas Madsen6aac05b2018-01-05 15:40:182048 if (trace_enabled) {
2049 v8_platform.StopTracingAgent();
2050 }
Rasmus Christian Pedersen734fb492014-09-18 12:10:532051 exit(args[0]->Int32Value());
Ryan0f517032009-04-29 09:09:322052}
2053
Ryan Dahl3ac6dee2010-05-08 02:05:592054
Ben Noordhuis110a9cd2013-07-03 02:23:442055static void Uptime(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552056 Environment* env = Environment::GetCurrent(args);
Igor Zinkovsky500c8f42011-12-15 20:36:052057 double uptime;
Tom Hughescf78ce52011-03-04 23:57:542058
Fedor Indutny6a610a02014-10-04 14:44:392059 uv_update_time(env->event_loop());
2060 uptime = uv_now(env->event_loop()) - prog_start_time;
Tom Hughescf78ce52011-03-04 23:57:542061
Timothy J Fontaineb19b60a2014-05-01 20:54:232062 args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
Tom Hughescf78ce52011-03-04 23:57:542063}
Ryan Dahl3ac6dee2010-05-08 02:05:592064
Ryan Dahlc344fbc2011-10-06 21:59:382065
Anna Henningsen9d522222017-04-12 17:17:242066static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552067 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb3b3cfe2009-11-03 12:00:422068
Ryan Dahl5783a522011-10-18 21:30:312069 size_t rss;
Ben Noordhuisca9eb712013-07-18 21:18:502070 int err = uv_resident_set_memory(&rss);
2071 if (err) {
Fedor Indutny75adde02014-02-21 13:02:422072 return env->ThrowUVException(err, "uv_resident_set_memory");
Ryan Dahl3a701292009-11-03 00:30:012073 }
2074
Brian Whitef385f772017-02-22 07:03:492075 Isolate* isolate = env->isolate();
Ryan Dahl38e425d2009-11-28 15:31:292076 // V8 memory usage
2077 HeapStatistics v8_heap_stats;
Brian Whitef385f772017-02-22 07:03:492078 isolate->GetHeapStatistics(&v8_heap_stats);
Ben Noordhuis756b6222013-08-10 22:26:112079
Brian Whitef385f772017-02-22 07:03:492080 // Get the double array pointer from the Float64Array argument.
2081 CHECK(args[0]->IsFloat64Array());
2082 Local<Float64Array> array = args[0].As<Float64Array>();
2083 CHECK_EQ(array->Length(), 4);
2084 Local<ArrayBuffer> ab = array->Buffer();
2085 double* fields = static_cast<double*>(ab->GetContents().Data());
Ben Noordhuis756b6222013-08-10 22:26:112086
Brian Whitef385f772017-02-22 07:03:492087 fields[0] = rss;
2088 fields[1] = v8_heap_stats.total_heap_size();
2089 fields[2] = v8_heap_stats.used_heap_size();
2090 fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
Ryan Dahl3a701292009-11-03 00:30:012091}
Ryan Dahlb3b3cfe2009-11-03 12:00:422092
Bert Belder4a2cb072010-11-29 17:40:142093
Anna Henningsen9d522222017-04-12 17:17:242094static void Kill(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552095 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb20c3432010-02-12 05:55:082096
Ryan Dahl4227e9d2010-12-21 23:40:102097 if (args.Length() != 2) {
Fedor Indutny75adde02014-02-21 13:02:422098 return env->ThrowError("Bad argument.");
Brandon Beacher334d56d2009-10-14 21:56:122099 }
Ryan Dahlb20c3432010-02-12 05:55:082100
Rasmus Christian Pedersen734fb492014-09-18 12:10:532101 int pid = args[0]->Int32Value();
Ryan Dahl6eca9482010-09-17 06:13:032102 int sig = args[1]->Int32Value();
Ben Noordhuisca9eb712013-07-18 21:18:502103 int err = uv_kill(pid, sig);
2104 args.GetReturnValue().Set(err);
Brandon Beacher334d56d2009-10-14 21:56:122105}
2106
Nathan Rajlich07c886f2012-03-05 16:51:582107// used in Hrtime() below
2108#define NANOS_PER_SEC 1000000000
2109
2110// Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2111// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
Joyee Cheunga647d822017-01-12 12:03:292112// so this function instead fills in an Uint32Array with 3 entries,
2113// to avoid any integer overflow possibility.
2114// The first two entries contain the second part of the value
2115// broken into the upper/lower 32 bits to be converted back in JS,
2116// because there is no Uint64Array in JS.
2117// The third entry contains the remaining nanosecond part of the value.
Anna Henningsen9d522222017-04-12 17:17:242118static void Hrtime(const FunctionCallbackInfo<Value>& args) {
Nathan Rajlich07c886f2012-03-05 16:51:582119 uint64_t t = uv_hrtime();
2120
Trevor Norris36e8a2c2015-11-11 07:15:152121 Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2122 uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
2123
Trevor Norris36e8a2c2015-11-11 07:15:152124 fields[0] = (t / NANOS_PER_SEC) >> 32;
2125 fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
2126 fields[2] = t % NANOS_PER_SEC;
Nathan Rajlich07c886f2012-03-05 16:51:582127}
2128
Patrick Mueller52cb4102016-04-05 13:17:482129// Microseconds in a second, as a float, used in CPUUsage() below
2130#define MICROS_PER_SEC 1e6
2131
2132// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
2133// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
2134// which are uv_timeval_t structs (long tv_sec, long tv_usec).
2135// Returns those values as Float64 microseconds in the elements of the array
2136// passed to the function.
Anna Henningsen9d522222017-04-12 17:17:242137static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
Patrick Mueller52cb4102016-04-05 13:17:482138 uv_rusage_t rusage;
2139
2140 // Call libuv to get the values we'll return.
2141 int err = uv_getrusage(&rusage);
2142 if (err) {
2143 // On error, return the strerror version of the error code.
2144 Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2145 args.GetReturnValue().Set(errmsg);
2146 return;
2147 }
2148
2149 // Get the double array pointer from the Float64Array argument.
2150 CHECK(args[0]->IsFloat64Array());
2151 Local<Float64Array> array = args[0].As<Float64Array>();
2152 CHECK_EQ(array->Length(), 2);
2153 Local<ArrayBuffer> ab = array->Buffer();
2154 double* fields = static_cast<double*>(ab->GetContents().Data());
2155
2156 // Set the Float64Array elements to be user / system values in microseconds.
2157 fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2158 fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2159}
2160
Keith M Wesolowski76b98462013-12-17 00:00:442161extern "C" void node_module_register(void* m) {
2162 struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2163
2164 if (mp->nm_flags & NM_F_BUILTIN) {
2165 mp->nm_link = modlist_builtin;
2166 modlist_builtin = mp;
Bradley Fariasa36aa042017-10-03 15:07:482167 } else if (mp->nm_flags & NM_F_INTERNAL) {
2168 mp->nm_link = modlist_internal;
2169 modlist_internal = mp;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222170 } else if (!node_is_initialized) {
2171 // "Linked" modules are included as part of the node project.
2172 // Like builtins they are registered *before* node::Init runs.
2173 mp->nm_flags = NM_F_LINKED;
2174 mp->nm_link = modlist_linked;
2175 modlist_linked = mp;
Keith M Wesolowski76b98462013-12-17 00:00:442176 } else {
Keith M Wesolowski76b98462013-12-17 00:00:442177 modpending = mp;
2178 }
2179}
2180
Bradley Fariasa36aa042017-10-03 15:07:482181inline struct node_module* FindModule(struct node_module* list,
2182 const char* name,
2183 int flag) {
Keith M Wesolowski76b98462013-12-17 00:00:442184 struct node_module* mp;
2185
Bradley Fariasa36aa042017-10-03 15:07:482186 for (mp = list; mp != nullptr; mp = mp->nm_link) {
Keith M Wesolowski76b98462013-12-17 00:00:442187 if (strcmp(mp->nm_modname, name) == 0)
2188 break;
2189 }
2190
Bradley Fariasa36aa042017-10-03 15:07:482191 CHECK(mp == nullptr || (mp->nm_flags & flag) != 0);
2192 return mp;
Keith M Wesolowski76b98462013-12-17 00:00:442193}
Bert Belderdd93c532011-10-28 10:05:092194
Bradley Fariasa36aa042017-10-03 15:07:482195node_module* get_builtin_module(const char* name) {
2196 return FindModule(modlist_builtin, name, NM_F_BUILTIN);
2197}
2198node_module* get_internal_module(const char* name) {
2199 return FindModule(modlist_internal, name, NM_F_INTERNAL);
2200}
2201node_module* get_linked_module(const char* name) {
2202 return FindModule(modlist_linked, name, NM_F_LINKED);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222203}
2204
Ezequiel Garcia5f223752017-04-29 20:06:222205struct DLib {
2206 std::string filename_;
2207 std::string errmsg_;
2208 void* handle_;
2209 int flags_;
2210
2211#ifdef __POSIX__
2212 static const int kDefaultFlags = RTLD_LAZY;
2213
2214 bool Open() {
2215 handle_ = dlopen(filename_.c_str(), flags_);
2216 if (handle_ != nullptr)
2217 return true;
2218 errmsg_ = dlerror();
2219 return false;
2220 }
2221
2222 void Close() {
2223 if (handle_ != nullptr)
2224 dlclose(handle_);
2225 }
2226#else // !__POSIX__
2227 static const int kDefaultFlags = 0;
2228 uv_lib_t lib_;
2229
2230 bool Open() {
2231 int ret = uv_dlopen(filename_.c_str(), &lib_);
2232 if (ret == 0) {
2233 handle_ = static_cast<void*>(lib_.handle);
2234 return true;
2235 }
2236 errmsg_ = uv_dlerror(&lib_);
2237 uv_dlclose(&lib_);
2238 return false;
2239 }
2240
2241 void Close() {
2242 uv_dlclose(&lib_);
2243 }
2244#endif // !__POSIX__
2245};
2246
2247// DLOpen is process.dlopen(module, filename, flags).
isaacs15508582013-01-24 23:40:582248// Used to load 'module.node' dynamically shared objects.
Ben Noordhuis756b6222013-08-10 22:26:112249//
2250// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2251// when two contexts try to load the same shared object. Maybe have a shadow
2252// cache that's a plain C list or hash table that's shared across contexts?
Anna Henningsen9d522222017-04-12 17:17:242253static void DLOpen(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552254 Environment* env = Environment::GetCurrent(args);
Ryan2b6d7242009-06-20 13:07:102255
Ben Noordhuisa60056d2014-12-11 14:29:522256 CHECK_EQ(modpending, nullptr);
2257
Ezequiel Garcia5f223752017-04-29 20:06:222258 if (args.Length() < 2) {
2259 env->ThrowError("process.dlopen needs at least 2 arguments.");
Keith M Wesolowski76b98462013-12-17 00:00:442260 return;
Bert Belderdd93c532011-10-28 10:05:092261 }
Ryana97dce72009-08-31 09:14:342262
Ezequiel Garcia5f223752017-04-29 20:06:222263 int32_t flags = DLib::kDefaultFlags;
2264 if (args.Length() > 2 && !args[2]->Int32Value(env->context()).To(&flags)) {
2265 return env->ThrowTypeError("flag argument must be an integer.");
2266 }
2267
Leko19221d12017-11-27 07:16:322268 Local<Object> module =
2269 args[0]->ToObject(env->context()).ToLocalChecked(); // Cast
Trevor Norriscbf76c12015-01-07 22:13:352270 node::Utf8Value filename(env->isolate(), args[1]); // Cast
Ezequiel Garcia5f223752017-04-29 20:06:222271 DLib dlib;
2272 dlib.filename_ = *filename;
2273 dlib.flags_ = flags;
2274 bool is_opened = dlib.Open();
isaacs15508582013-01-24 23:40:582275
Ben Noordhuisa60056d2014-12-11 14:29:522276 // Objects containing v14 or later modules will have registered themselves
2277 // on the pending list. Activate all of them now. At present, only one
2278 // module per object is supported.
2279 node_module* const mp = modpending;
2280 modpending = nullptr;
Ryan2b6d7242009-06-20 13:07:102281
Ezequiel Garcia5f223752017-04-29 20:06:222282 if (!is_opened) {
2283 Local<String> errmsg = OneByteString(env->isolate(), dlib.errmsg_.c_str());
2284 dlib.Close();
Ben Noordhuis039fac62012-05-17 05:13:292285#ifdef _WIN32
2286 // Windows needs to add the filename into the error message
Leko19221d12017-11-27 07:16:322287 errmsg = String::Concat(errmsg,
2288 args[1]->ToString(env->context()).ToLocalChecked());
Fedor Indutny8e29ce92013-07-31 18:07:292289#endif // _WIN32
Fedor Indutny75adde02014-02-21 13:02:422290 env->isolate()->ThrowException(Exception::Error(errmsg));
Ben Noordhuis110a9cd2013-07-03 02:23:442291 return;
Ryan2b6d7242009-06-20 13:07:102292 }
2293
Ben Noordhuis2d82cdf2014-10-22 01:29:322294 if (mp == nullptr) {
Ezequiel Garcia5f223752017-04-29 20:06:222295 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:422296 env->ThrowError("Module did not self-register.");
Keith M Wesolowski76b98462013-12-17 00:00:442297 return;
Paul Querna367b87d2010-07-13 08:33:512298 }
Gabriel Schulhofa8c0a432017-08-18 10:30:052299 if (mp->nm_version == -1) {
2300 if (env->EmitNapiWarning()) {
Anna Henningsenf3cd5372017-12-01 23:04:562301 if (ProcessEmitWarning(env, "N-API is an experimental feature and could "
2302 "change at any time.").IsNothing()) {
2303 dlib.Close();
2304 return;
2305 }
Jason Ginchereau56e881d2017-03-20 21:55:262306 }
Gabriel Schulhofa8c0a432017-08-18 10:30:052307 } else if (mp->nm_version != NODE_MODULE_VERSION) {
2308 char errmsg[1024];
2309 snprintf(errmsg,
2310 sizeof(errmsg),
2311 "The module '%s'"
2312 "\nwas compiled against a different Node.js version using"
2313 "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
2314 "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
2315 "re-installing\nthe module (for instance, using `npm rebuild` "
2316 "or `npm install`).",
2317 *filename, mp->nm_version, NODE_MODULE_VERSION);
Fedor Indutnya6d674d2015-09-10 11:01:202318
2319 // NOTE: `mp` is allocated inside of the shared library's memory, calling
Ezequiel Garcia5f223752017-04-29 20:06:222320 // `dlclose` will deallocate it
2321 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:422322 env->ThrowError(errmsg);
Keith M Wesolowski76b98462013-12-17 00:00:442323 return;
2324 }
2325 if (mp->nm_flags & NM_F_BUILTIN) {
Ezequiel Garcia5f223752017-04-29 20:06:222326 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:422327 env->ThrowError("Built-in module self-registered.");
Keith M Wesolowski76b98462013-12-17 00:00:442328 return;
Ryan2b6d7242009-06-20 13:07:102329 }
Ryan2b6d7242009-06-20 13:07:102330
Ezequiel Garcia5f223752017-04-29 20:06:222331 mp->nm_dso_handle = dlib.handle_;
Keith M Wesolowski76b98462013-12-17 00:00:442332 mp->nm_link = modlist_addon;
2333 modlist_addon = mp;
2334
Ben Noordhuisa60056d2014-12-11 14:29:522335 Local<String> exports_string = env->exports_string();
Leko19221d12017-11-27 07:16:322336 MaybeLocal<Value> maybe_exports =
2337 module->Get(env->context(), exports_string);
2338
2339 if (maybe_exports.IsEmpty() ||
2340 maybe_exports.ToLocalChecked()->ToObject(env->context()).IsEmpty()) {
2341 dlib.Close();
2342 return;
2343 }
2344
2345 Local<Object> exports =
2346 maybe_exports.ToLocalChecked()->ToObject(env->context())
2347 .FromMaybe(Local<Object>());
Ben Noordhuisa60056d2014-12-11 14:29:522348
Ben Noordhuis2d82cdf2014-10-22 01:29:322349 if (mp->nm_context_register_func != nullptr) {
Keith M Wesolowski76b98462013-12-17 00:00:442350 mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
Ben Noordhuis2d82cdf2014-10-22 01:29:322351 } else if (mp->nm_register_func != nullptr) {
Keith M Wesolowski76b98462013-12-17 00:00:442352 mp->nm_register_func(exports, module, mp->nm_priv);
Ben Noordhuis756b6222013-08-10 22:26:112353 } else {
Ezequiel Garcia5f223752017-04-29 20:06:222354 dlib.Close();
Fedor Indutny75adde02014-02-21 13:02:422355 env->ThrowError("Module has no declared entry point.");
Keith M Wesolowski76b98462013-12-17 00:00:442356 return;
Ben Noordhuis756b6222013-08-10 22:26:112357 }
Ryan2b6d7242009-06-20 13:07:102358
Peter Griess4e3c5d82010-07-12 15:47:452359 // Tell coverity that 'handle' should not be freed when we return.
2360 // coverity[leaked_storage]
Ryan2b6d7242009-06-20 13:07:102361}
2362
Tim-Smartae10a482010-03-12 08:36:002363
Ryand6c9d312009-09-11 14:02:292364static void OnFatalError(const char* location, const char* message) {
Ryan Dahl53a841d2009-12-29 19:20:512365 if (location) {
Brian White2d356072015-10-13 21:18:152366 PrintErrorString("FATAL ERROR: %s %s\n", location, message);
Ryan Dahl53a841d2009-12-29 19:20:512367 } else {
Brian White2d356072015-10-13 21:18:152368 PrintErrorString("FATAL ERROR: %s\n", message);
Ryan Dahl53a841d2009-12-29 19:20:512369 }
Ben Noordhuisc56a96c2013-06-29 05:30:112370 fflush(stderr);
Evan Lucas870229e2015-09-16 15:12:412371 ABORT();
Ryan63a9cd32009-04-15 08:08:282372}
2373
Miroslav Bajtosc16963b2013-06-17 19:19:592374
Trevor Norrisfa10b752013-06-20 23:44:022375NO_RETURN void FatalError(const char* location, const char* message) {
2376 OnFatalError(location, message);
James M Snell936c9ff2015-06-24 03:42:492377 // to suppress compiler warning
Evan Lucas870229e2015-09-16 15:12:412378 ABORT();
Trevor Norrisfa10b752013-06-20 23:44:022379}
2380
2381
Anna Henningsena0126722017-11-27 00:31:242382FatalTryCatch::~FatalTryCatch() {
2383 if (HasCaught()) {
2384 HandleScope scope(env_->isolate());
2385 ReportException(env_, *this);
2386 exit(7);
2387 }
2388}
2389
2390
Fedor Indutny75adde02014-02-21 13:02:422391void FatalException(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:162392 Local<Value> error,
2393 Local<Message> message) {
Fedor Indutny75adde02014-02-21 13:02:422394 HandleScope scope(isolate);
Felix Geisendörfer2b252ac2009-11-14 22:07:542395
Fedor Indutny75adde02014-02-21 13:02:422396 Environment* env = Environment::GetCurrent(isolate);
Ben Noordhuis756b6222013-08-10 22:26:112397 Local<Object> process_object = env->process_object();
2398 Local<String> fatal_exception_string = env->fatal_exception_string();
2399 Local<Function> fatal_exception_function =
2400 process_object->Get(fatal_exception_string).As<Function>();
Ryan Dahl45a806a2009-12-09 08:02:212401
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472402 int exit_code = 0;
Ben Noordhuis756b6222013-08-10 22:26:112403 if (!fatal_exception_function->IsFunction()) {
isaacs4401bb42012-12-26 20:28:332404 // failed before the process._fatalException function was added!
2405 // this is probably pretty bad. Nothing to do but report and exit.
Fedor Indutnyf1de13b2014-02-05 16:38:332406 ReportException(env, error, message);
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472407 exit_code = 6;
Felix Geisendörfer2b252ac2009-11-14 22:07:542408 }
2409
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472410 if (exit_code == 0) {
2411 TryCatch fatal_try_catch(isolate);
isaacs07be9fc2012-05-09 22:12:132412
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472413 // Do not call FatalException when _fatalException handler throws
2414 fatal_try_catch.SetVerbose(false);
Miroslav Bajtosc16963b2013-06-17 19:19:592415
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472416 // this will return true if the JS layer handled it, false otherwise
2417 Local<Value> caught =
2418 fatal_exception_function->Call(process_object, 1, &error);
isaacs4401bb42012-12-26 20:28:332419
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472420 if (fatal_try_catch.HasCaught()) {
2421 // the fatal exception function threw, so we must exit
2422 ReportException(env, fatal_try_catch);
2423 exit_code = 7;
2424 }
2425
2426 if (exit_code == 0 && false == caught->BooleanValue()) {
2427 ReportException(env, error, message);
2428 exit_code = 1;
2429 }
isaacs4401bb42012-12-26 20:28:332430 }
2431
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472432 if (exit_code) {
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472433 exit(exit_code);
isaacs80a55e92012-04-07 02:23:162434 }
Ryane78917b2009-03-09 13:08:312435}
2436
Ryan0e9e9272009-04-04 14:53:432437
Fedor Indutny75adde02014-02-21 13:02:422438void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2439 HandleScope scope(isolate);
Daniel Beveniusfefab902017-05-03 17:17:222440 if (!try_catch.IsVerbose()) {
2441 FatalException(isolate, try_catch.Exception(), try_catch.Message());
2442 }
Miroslav Bajtosc16963b2013-06-17 19:19:592443}
2444
2445
Anna Henningsen9d522222017-04-12 17:17:242446static void OnMessage(Local<Message> message, Local<Value> error) {
Miroslav Bajtosc16963b2013-06-17 19:19:592447 // The current version of V8 sends messages for errors only
2448 // (thus `error` is always set).
Fedor Indutny75adde02014-02-21 13:02:422449 FatalException(Isolate::GetCurrent(), error, message);
Miroslav Bajtosc16963b2013-06-17 19:19:592450}
2451
Anna Henningsenf3cd5372017-12-01 23:04:562452static Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
2453 const char* warning,
2454 const char* type = nullptr,
2455 const char* code = nullptr) {
2456 HandleScope handle_scope(env->isolate());
2457 Context::Scope context_scope(env->context());
2458
2459 Local<Object> process = env->process_object();
2460 Local<Value> emit_warning;
2461 if (!process->Get(env->context(),
2462 env->emit_warning_string()).ToLocal(&emit_warning)) {
2463 return Nothing<bool>();
2464 }
2465
2466 if (!emit_warning->IsFunction()) return Just(false);
2467
2468 int argc = 0;
2469 Local<Value> args[3]; // warning, type, code
2470
2471 // The caller has to be able to handle a failure anyway, so we might as well
2472 // do proper error checking for string creation.
2473 if (!String::NewFromUtf8(env->isolate(),
2474 warning,
2475 v8::NewStringType::kNormal).ToLocal(&args[argc++])) {
2476 return Nothing<bool>();
2477 }
2478 if (type != nullptr) {
2479 if (!String::NewFromOneByte(env->isolate(),
2480 reinterpret_cast<const uint8_t*>(type),
2481 v8::NewStringType::kNormal)
2482 .ToLocal(&args[argc++])) {
2483 return Nothing<bool>();
2484 }
2485 if (code != nullptr &&
2486 !String::NewFromOneByte(env->isolate(),
2487 reinterpret_cast<const uint8_t*>(code),
2488 v8::NewStringType::kNormal)
2489 .ToLocal(&args[argc++])) {
2490 return Nothing<bool>();
2491 }
2492 }
2493
2494 // MakeCallback() unneeded because emitWarning is internal code, it calls
2495 // process.emit('warning', ...), but does so on the nextTick.
2496 if (emit_warning.As<Function>()->Call(env->context(),
2497 process,
2498 argc,
2499 args).IsEmpty()) {
2500 return Nothing<bool>();
2501 }
2502 return Just(true);
2503}
2504
2505
Sam Roberts213134f2016-11-07 21:18:232506// Call process.emitWarning(str), fmt is a snprintf() format string
Anna Henningsenf3cd5372017-12-01 23:04:562507Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
Sam Roberts213134f2016-11-07 21:18:232508 char warning[1024];
2509 va_list ap;
2510
2511 va_start(ap, fmt);
2512 vsnprintf(warning, sizeof(warning), fmt, ap);
2513 va_end(ap);
2514
Anna Henningsenf3cd5372017-12-01 23:04:562515 return ProcessEmitWarningGeneric(env, warning);
Sam Roberts213134f2016-11-07 21:18:232516}
2517
Anna Henningsenf3cd5372017-12-01 23:04:562518
2519Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
2520 const char* warning,
2521 const char* deprecation_code) {
2522 return ProcessEmitWarningGeneric(env,
2523 warning,
2524 "DeprecationWarning",
2525 deprecation_code);
2526}
2527
2528
Bradley Fariasa36aa042017-10-03 15:07:482529static bool PullFromCache(Environment* env,
2530 const FunctionCallbackInfo<Value>& args,
2531 Local<String> module,
2532 Local<Object> cache) {
2533 Local<Context> context = env->context();
2534 Local<Value> exports_v;
2535 Local<Object> exports;
2536 if (cache->Get(context, module).ToLocal(&exports_v) &&
2537 exports_v->IsObject() &&
2538 exports_v->ToObject(context).ToLocal(&exports)) {
2539 args.GetReturnValue().Set(exports);
2540 return true;
2541 }
2542 return false;
2543}
2544
2545static Local<Object> InitModule(Environment* env,
2546 node_module* mod,
2547 Local<String> module) {
2548 Local<Object> exports = Object::New(env->isolate());
2549 // Internal bindings don't have a "module" object, only exports.
2550 CHECK_EQ(mod->nm_register_func, nullptr);
2551 CHECK_NE(mod->nm_context_register_func, nullptr);
2552 Local<Value> unused = Undefined(env->isolate());
2553 mod->nm_context_register_func(exports,
2554 unused,
2555 env->context(),
2556 mod->nm_priv);
2557 return exports;
2558}
2559
2560static void ThrowIfNoSuchModule(Environment* env, const char* module_v) {
2561 char errmsg[1024];
2562 snprintf(errmsg,
2563 sizeof(errmsg),
2564 "No such module: %s",
2565 module_v);
2566 env->ThrowError(errmsg);
2567}
Trevor Norrisa17200b2016-03-14 18:35:222568
Ben Noordhuis110a9cd2013-07-03 02:23:442569static void Binding(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552570 Environment* env = Environment::GetCurrent(args);
Ryan Dahl627fb5a2010-03-15 20:48:032571
Bradley Fariasa36aa042017-10-03 15:07:482572 Local<String> module;
2573 if (!args[0]->ToString(env->context()).ToLocal(&module)) return;
Ryan Dahl627fb5a2010-03-15 20:48:032574
Ben Noordhuis756b6222013-08-10 22:26:112575 Local<Object> cache = env->binding_cache_object();
Ryan Dahl627fb5a2010-03-15 20:48:032576
Bradley Fariasa36aa042017-10-03 15:07:482577 if (PullFromCache(env, args, module, cache))
Ben Noordhuis110a9cd2013-07-03 02:23:442578 return;
Ryan Dahl6eca9482010-09-17 06:13:032579
Ryan Dahlea9ee1f2011-07-28 02:30:322580 // Append a string to process.moduleLoadList
2581 char buf[1024];
Bradley Fariasa36aa042017-10-03 15:07:482582 node::Utf8Value module_v(env->isolate(), module);
Fedor Indutny8e29ce92013-07-31 18:07:292583 snprintf(buf, sizeof(buf), "Binding %s", *module_v);
Ben Noordhuis110a9cd2013-07-03 02:23:442584
Ben Noordhuis756b6222013-08-10 22:26:112585 Local<Array> modules = env->module_load_list_array();
Ben Noordhuis110a9cd2013-07-03 02:23:442586 uint32_t l = modules->Length();
Fedor Indutny75adde02014-02-21 13:02:422587 modules->Set(l, OneByteString(env->isolate(), buf));
Ryan Dahlea9ee1f2011-07-28 02:30:322588
Keith M Wesolowski76b98462013-12-17 00:00:442589 node_module* mod = get_builtin_module(*module_v);
Bradley Fariasa36aa042017-10-03 15:07:482590 Local<Object> exports;
Ben Noordhuis2d82cdf2014-10-22 01:29:322591 if (mod != nullptr) {
Bradley Fariasa36aa042017-10-03 15:07:482592 exports = InitModule(env, mod, module);
Ryan Dahl6eca9482010-09-17 06:13:032593 } else if (!strcmp(*module_v, "constants")) {
Fedor Indutnyce04c722014-03-13 16:38:142594 exports = Object::New(env->isolate());
Sakthipriyan Vairamani (thefourtheye)caf9ae72016-12-26 11:12:092595 CHECK(exports->SetPrototype(env->context(),
2596 Null(env->isolate())).FromJust());
James M Snelldcccbfd2016-05-02 17:27:122597 DefineConstants(env->isolate(), exports);
Ryan Dahlc90546f2010-03-15 21:22:502598 } else if (!strcmp(*module_v, "natives")) {
Fedor Indutnyce04c722014-03-13 16:38:142599 exports = Object::New(env->isolate());
Fedor Indutny75adde02014-02-21 13:02:422600 DefineJavaScript(env, exports);
Ryan Dahl627fb5a2010-03-15 20:48:032601 } else {
Bradley Fariasa36aa042017-10-03 15:07:482602 return ThrowIfNoSuchModule(env, *module_v);
Ryan Dahl627fb5a2010-03-15 20:48:032603 }
Bradley Fariasa36aa042017-10-03 15:07:482604 cache->Set(module, exports);
2605
2606 args.GetReturnValue().Set(exports);
2607}
2608
2609static void InternalBinding(const FunctionCallbackInfo<Value>& args) {
2610 Environment* env = Environment::GetCurrent(args);
2611
2612 Local<String> module;
2613 if (!args[0]->ToString(env->context()).ToLocal(&module)) return;
2614
2615 Local<Object> cache = env->internal_binding_cache_object();
2616
2617 if (PullFromCache(env, args, module, cache))
2618 return;
2619
2620 // Append a string to process.moduleLoadList
2621 char buf[1024];
2622 node::Utf8Value module_v(env->isolate(), module);
2623 snprintf(buf, sizeof(buf), "Internal Binding %s", *module_v);
2624
2625 Local<Array> modules = env->module_load_list_array();
2626 uint32_t l = modules->Length();
2627 modules->Set(l, OneByteString(env->isolate(), buf));
2628
2629 node_module* mod = get_internal_module(*module_v);
2630 if (mod == nullptr) return ThrowIfNoSuchModule(env, *module_v);
2631 Local<Object> exports = InitModule(env, mod, module);
2632 cache->Set(module, exports);
Ryan Dahl627fb5a2010-03-15 20:48:032633
Ben Noordhuis110a9cd2013-07-03 02:23:442634 args.GetReturnValue().Set(exports);
Ryan Dahl627fb5a2010-03-15 20:48:032635}
2636
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222637static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2638 Environment* env = Environment::GetCurrent(args.GetIsolate());
2639
Bradley Fariasa36aa042017-10-03 15:07:482640 Local<String> module_name;
2641 if (!args[0]->ToString(env->context()).ToLocal(&module_name)) return;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222642
2643 Local<Object> cache = env->binding_cache_object();
Phillip Kovalev71470a82016-01-19 21:52:162644 Local<Value> exports_v = cache->Get(module_name);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222645
2646 if (exports_v->IsObject())
2647 return args.GetReturnValue().Set(exports_v.As<Object>());
2648
Phillip Kovalev71470a82016-01-19 21:52:162649 node::Utf8Value module_name_v(env->isolate(), module_name);
2650 node_module* mod = get_linked_module(*module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222651
Bert Belder9483bfe2014-12-09 04:57:172652 if (mod == nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222653 char errmsg[1024];
2654 snprintf(errmsg,
2655 sizeof(errmsg),
2656 "No such module was linked: %s",
Phillip Kovalev71470a82016-01-19 21:52:162657 *module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222658 return env->ThrowError(errmsg);
2659 }
2660
Phillip Kovalev71470a82016-01-19 21:52:162661 Local<Object> module = Object::New(env->isolate());
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222662 Local<Object> exports = Object::New(env->isolate());
Phillip Kovalev71470a82016-01-19 21:52:162663 Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
2664 module->Set(exports_prop, exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222665
Bert Belder9483bfe2014-12-09 04:57:172666 if (mod->nm_context_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222667 mod->nm_context_register_func(exports,
2668 module,
2669 env->context(),
2670 mod->nm_priv);
Bert Belder9483bfe2014-12-09 04:57:172671 } else if (mod->nm_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222672 mod->nm_register_func(exports, module, mod->nm_priv);
2673 } else {
2674 return env->ThrowError("Linked module has no declared entry point.");
2675 }
2676
Phillip Kovalev5c14efb2016-02-20 08:30:432677 auto effective_exports = module->Get(exports_prop);
2678 cache->Set(module_name, effective_exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222679
Phillip Kovalev5c14efb2016-02-20 08:30:432680 args.GetReturnValue().Set(effective_exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222681}
Ryan Dahle742d072009-10-09 11:25:042682
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262683static void ProcessTitleGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442684 const PropertyCallbackInfo<Value>& info) {
Igor Zinkovsky500c8f42011-12-15 20:36:052685 char buffer[512];
2686 uv_get_process_title(buffer, sizeof(buffer));
Ben Noordhuis2e5b87a2015-03-22 23:38:422687 info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
Ryan Dahl5185c152010-06-18 07:26:492688}
2689
2690
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262691static void ProcessTitleSetter(Local<Name> property,
Ryan Dahl5185c152010-06-18 07:26:492692 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:442693 const PropertyCallbackInfo<void>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422694 node::Utf8Value title(info.GetIsolate(), value);
Fedor Indutny8e29ce92013-07-31 18:07:292695 // TODO(piscisaureus): protect with a lock
Igor Zinkovsky500c8f42011-12-15 20:36:052696 uv_set_process_title(*title);
Ryan Dahl5185c152010-06-18 07:26:492697}
2698
2699
AnnaMagab194122016-10-06 20:50:412700static void EnvGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442701 const PropertyCallbackInfo<Value>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422702 Isolate* isolate = info.GetIsolate();
Anna Henningsen3295a7f2016-11-16 01:27:142703 if (property->IsSymbol()) {
2704 return info.GetReturnValue().SetUndefined();
2705 }
Bert Belder077f9d72012-02-15 22:34:182706#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422707 node::Utf8Value key(isolate, property);
Ben Noordhuisb4def482010-10-15 13:48:342708 const char* val = getenv(*key);
2709 if (val) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422710 return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
Ben Noordhuisb4def482010-10-15 13:48:342711 }
Bert Belder077f9d72012-02-15 22:34:182712#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542713 node::TwoByteValue key(isolate, property);
Fedor Indutny8e29ce92013-07-31 18:07:292714 WCHAR buffer[32767]; // The maximum size allowed for environment variables.
Bert Belder077f9d72012-02-15 22:34:182715 DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2716 buffer,
Ben Noordhuisa7581d02016-03-31 10:47:062717 arraysize(buffer));
Bert Belder077f9d72012-02-15 22:34:182718 // If result >= sizeof buffer the buffer was too small. That should never
2719 // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2720 // not found.
2721 if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
Ben Noordhuisa7581d02016-03-31 10:47:062722 result < arraysize(buffer)) {
Ben Noordhuisf674b092013-08-07 19:50:412723 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
Ben Noordhuis2e5b87a2015-03-22 23:38:422724 Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
Ben Noordhuisf674b092013-08-07 19:50:412725 return info.GetReturnValue().Set(rc);
Bert Belder077f9d72012-02-15 22:34:182726 }
2727#endif
Ben Noordhuisb4def482010-10-15 13:48:342728}
2729
2730
AnnaMagab194122016-10-06 20:50:412731static void EnvSetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442732 Local<Value> value,
2733 const PropertyCallbackInfo<Value>& info) {
Bert Belder077f9d72012-02-15 22:34:182734#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422735 node::Utf8Value key(info.GetIsolate(), property);
2736 node::Utf8Value val(info.GetIsolate(), value);
Ben Noordhuisb4def482010-10-15 13:48:342737 setenv(*key, *val, 1);
Bert Belder077f9d72012-02-15 22:34:182738#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542739 node::TwoByteValue key(info.GetIsolate(), property);
2740 node::TwoByteValue val(info.GetIsolate(), value);
Bert Belder077f9d72012-02-15 22:34:182741 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2742 // Environment variables that start with '=' are read-only.
2743 if (key_ptr[0] != L'=') {
2744 SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
Ryan Dahle6b06bc2011-08-11 00:14:232745 }
Bert Belder30bab522010-11-25 00:09:062746#endif
Miguel Angel Asencio Hurtado88323e82016-10-11 08:19:162747 // Whether it worked or not, always return value.
Ben Noordhuis110a9cd2013-07-03 02:23:442748 info.GetReturnValue().Set(value);
Ben Noordhuisb4def482010-10-15 13:48:342749}
2750
2751
AnnaMagab194122016-10-06 20:50:412752static void EnvQuery(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442753 const PropertyCallbackInfo<Integer>& info) {
Ben Noordhuis110a9cd2013-07-03 02:23:442754 int32_t rc = -1; // Not found unless proven otherwise.
Timothy Gue2f151f2017-03-06 06:45:192755 if (property->IsString()) {
Bert Belder077f9d72012-02-15 22:34:182756#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192757 node::Utf8Value key(info.GetIsolate(), property);
2758 if (getenv(*key))
2759 rc = 0;
Bert Belder077f9d72012-02-15 22:34:182760#else // _WIN32
Timothy Gue2f151f2017-03-06 06:45:192761 node::TwoByteValue key(info.GetIsolate(), property);
2762 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2763 if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2764 GetLastError() == ERROR_SUCCESS) {
2765 rc = 0;
2766 if (key_ptr[0] == L'=') {
2767 // Environment variables that start with '=' are hidden and read-only.
2768 rc = static_cast<int32_t>(v8::ReadOnly) |
2769 static_cast<int32_t>(v8::DontDelete) |
2770 static_cast<int32_t>(v8::DontEnum);
2771 }
Bert Belder077f9d72012-02-15 22:34:182772 }
Bert Belder077f9d72012-02-15 22:34:182773#endif
Timothy Gue2f151f2017-03-06 06:45:192774 }
Fedor Indutny2bc30f22013-10-16 16:57:262775 if (rc != -1)
2776 info.GetReturnValue().Set(rc);
Ben Noordhuisb4def482010-10-15 13:48:342777}
2778
2779
AnnaMagab194122016-10-06 20:50:412780static void EnvDeleter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442781 const PropertyCallbackInfo<Boolean>& info) {
Timothy Gue2f151f2017-03-06 06:45:192782 if (property->IsString()) {
Bert Belder30bab522010-11-25 00:09:062783#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192784 node::Utf8Value key(info.GetIsolate(), property);
2785 unsetenv(*key);
Bert Belder30bab522010-11-25 00:09:062786#else
Timothy Gue2f151f2017-03-06 06:45:192787 node::TwoByteValue key(info.GetIsolate(), property);
2788 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2789 SetEnvironmentVariableW(key_ptr, nullptr);
Bert Belder077f9d72012-02-15 22:34:182790#endif
Timothy Gue2f151f2017-03-06 06:45:192791 }
Franziska Hinkelmannff7a8412016-08-04 07:36:502792
2793 // process.env never has non-configurable properties, so always
2794 // return true like the tc39 delete operator.
2795 info.GetReturnValue().Set(true);
Ben Noordhuisb4def482010-10-15 13:48:342796}
2797
2798
Ben Noordhuis110a9cd2013-07-03 02:23:442799static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
Trevor Norris56985ca2015-11-11 19:28:412800 Environment* env = Environment::GetCurrent(info);
2801 Isolate* isolate = env->isolate();
2802 Local<Context> ctx = env->context();
2803 Local<Function> fn = env->push_values_to_array_function();
2804 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2805 size_t idx = 0;
2806
Bert Belder077f9d72012-02-15 22:34:182807#ifdef __POSIX__
Ben Noordhuisb4def482010-10-15 13:48:342808 int size = 0;
Fedor Indutny2bc30f22013-10-16 16:57:262809 while (environ[size])
2810 size++;
Ben Noordhuisb4def482010-10-15 13:48:342811
Trevor Norris56985ca2015-11-11 19:28:412812 Local<Array> envarr = Array::New(isolate);
Ben Noordhuisb4def482010-10-15 13:48:342813
2814 for (int i = 0; i < size; ++i) {
2815 const char* var = environ[i];
2816 const char* s = strchr(var, '=');
2817 const int length = s ? s - var : strlen(var);
Trevor Norris56985ca2015-11-11 19:28:412818 argv[idx] = String::NewFromUtf8(isolate,
2819 var,
2820 String::kNormalString,
2821 length);
Ben Noordhuisa7581d02016-03-31 10:47:062822 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412823 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2824 idx = 0;
2825 }
2826 }
2827 if (idx > 0) {
2828 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
Ben Noordhuisb4def482010-10-15 13:48:342829 }
Bert Belder077f9d72012-02-15 22:34:182830#else // _WIN32
2831 WCHAR* environment = GetEnvironmentStringsW();
Ben Noordhuis2d82cdf2014-10-22 01:29:322832 if (environment == nullptr)
Fedor Indutny2bc30f22013-10-16 16:57:262833 return; // This should not happen.
Ben Noordhuis2e5b87a2015-03-22 23:38:422834 Local<Array> envarr = Array::New(isolate);
Bert Belder077f9d72012-02-15 22:34:182835 WCHAR* p = environment;
Nikolai Vavilovb105f6f2014-10-24 22:36:592836 while (*p) {
Bert Belder077f9d72012-02-15 22:34:182837 WCHAR *s;
2838 if (*p == L'=') {
2839 // If the key starts with '=' it is a hidden environment variable.
2840 p += wcslen(p) + 1;
2841 continue;
2842 } else {
2843 s = wcschr(p, L'=');
2844 }
2845 if (!s) {
2846 s = p + wcslen(p);
2847 }
Ben Noordhuisf674b092013-08-07 19:50:412848 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
Ben Noordhuis78f709d2013-08-09 15:43:102849 const size_t two_byte_buffer_len = s - p;
Trevor Norris56985ca2015-11-11 19:28:412850 argv[idx] = String::NewFromTwoByte(isolate,
2851 two_byte_buffer,
2852 String::kNormalString,
2853 two_byte_buffer_len);
Ben Noordhuisa7581d02016-03-31 10:47:062854 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412855 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2856 idx = 0;
2857 }
Bert Belder077f9d72012-02-15 22:34:182858 p = s + wcslen(s) + 1;
2859 }
Trevor Norris56985ca2015-11-11 19:28:412860 if (idx > 0) {
2861 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2862 }
Bert Belder077f9d72012-02-15 22:34:182863 FreeEnvironmentStringsW(environment);
2864#endif
Ben Noordhuis110a9cd2013-07-03 02:23:442865
Fedor Indutny75adde02014-02-21 13:02:422866 info.GetReturnValue().Set(envarr);
Ben Noordhuisb4def482010-10-15 13:48:342867}
2868
2869
cjihrig3cacd342017-10-30 20:14:152870static void GetParentProcessId(Local<Name> property,
2871 const PropertyCallbackInfo<Value>& info) {
2872 info.GetReturnValue().Set(Integer::New(info.GetIsolate(), uv_os_getppid()));
2873}
2874
2875
Michaël Zasso4abc8962015-07-18 09:34:162876static Local<Object> GetFeatures(Environment* env) {
Fedor Indutnyce04c722014-03-13 16:38:142877 EscapableHandleScope scope(env->isolate());
Ben Noordhuisaa0308d2011-07-23 21:16:482878
Fedor Indutnyce04c722014-03-13 16:38:142879 Local<Object> obj = Object::New(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352880#if defined(DEBUG) && DEBUG
Fedor Indutny75adde02014-02-21 13:02:422881 Local<Value> debug = True(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352882#else
Fedor Indutny75adde02014-02-21 13:02:422883 Local<Value> debug = False(env->isolate());
Fedor Indutny8e29ce92013-07-31 18:07:292884#endif // defined(DEBUG) && DEBUG
2885
Ben Noordhuisb4ea3a02016-08-21 10:31:202886 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
2887 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
Fedor Indutny8e29ce92013-07-31 18:07:292888 // TODO(bnoordhuis) ping libuv
Ben Noordhuisb4ea3a02016-08-21 10:31:202889 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
Ben Noordhuisf674b092013-08-07 19:50:412890
Shigeki Ohtsu02c98f42017-03-02 14:13:192891#ifndef OPENSSL_NO_NEXTPROTONEG
Fedor Indutny75adde02014-02-21 13:02:422892 Local<Boolean> tls_npn = True(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452893#else
Fedor Indutny75adde02014-02-21 13:02:422894 Local<Boolean> tls_npn = False(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452895#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202896 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
Ben Noordhuis8d567f42013-08-27 14:14:452897
Shigeki Ohtsu802a2e72015-04-23 06:25:152898#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2899 Local<Boolean> tls_alpn = True(env->isolate());
2900#else
2901 Local<Boolean> tls_alpn = False(env->isolate());
2902#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202903 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn);
Shigeki Ohtsu802a2e72015-04-23 06:25:152904
Ben Noordhuis8d567f42013-08-27 14:14:452905#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
Fedor Indutny75adde02014-02-21 13:02:422906 Local<Boolean> tls_sni = True(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452907#else
Fedor Indutny75adde02014-02-21 13:02:422908 Local<Boolean> tls_sni = False(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452909#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202910 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni);
Ben Noordhuis8d567f42013-08-27 14:14:452911
Fedor Indutnyb3ef2892014-04-14 17:15:572912#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2913 Local<Boolean> tls_ocsp = True(env->isolate());
2914#else
2915 Local<Boolean> tls_ocsp = False(env->isolate());
2916#endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
Ben Noordhuisb4ea3a02016-08-21 10:31:202917 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp);
Fedor Indutnyb3ef2892014-04-14 17:15:572918
Ben Noordhuisb4ea3a02016-08-21 10:31:202919 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"),
Ben Noordhuis2d82cdf2014-10-22 01:29:322920 Boolean::New(env->isolate(),
2921 get_builtin_module("crypto") != nullptr));
Ben Noordhuisaa0308d2011-07-23 21:16:482922
Fedor Indutnyce04c722014-03-13 16:38:142923 return scope.Escape(obj);
Ben Noordhuisaa0308d2011-07-23 21:16:482924}
2925
2926
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262927static void DebugPortGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442928 const PropertyCallbackInfo<Value>& info) {
Ben Noordhuis399cb252017-05-27 11:31:002929 int port = debug_options.port();
2930#if HAVE_INSPECTOR
2931 if (port == 0) {
2932 Environment* env = Environment::GetCurrent(info);
Sam Robertsc4a61b32017-06-06 18:21:222933 if (auto io = env->inspector_agent()->io())
2934 port = io->port();
Ben Noordhuis399cb252017-05-27 11:31:002935 }
2936#endif // HAVE_INSPECTOR
2937 info.GetReturnValue().Set(port);
Fedor Indutny3f43b1c2012-02-12 15:53:432938}
2939
2940
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262941static void DebugPortSetter(Local<Name> property,
Fedor Indutny3f43b1c2012-02-12 15:53:432942 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:442943 const PropertyCallbackInfo<void>& info) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:222944 debug_options.set_port(value->Int32Value());
Fedor Indutny3f43b1c2012-02-12 15:53:432945}
2946
2947
Ben Noordhuis110a9cd2013-07-03 02:23:442948static void DebugProcess(const FunctionCallbackInfo<Value>& args);
Ben Noordhuis110a9cd2013-07-03 02:23:442949static void DebugEnd(const FunctionCallbackInfo<Value>& args);
Bert Belder829735e2011-11-04 15:23:022950
Anna Henningsen9d522222017-04-12 17:17:242951namespace {
Shigeki Ohtsucd372512013-02-06 02:13:022952
Ben Noordhuisf6496262013-10-03 09:03:462953void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552954 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:422955 env->StartProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:462956}
2957
2958
2959void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552960 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:422961 env->StopProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:462962}
2963
2964
Trevor Norrisc80f8fa2013-08-01 21:53:522965#define READONLY_PROPERTY(obj, str, var) \
2966 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:382967 obj->DefineOwnProperty(env->context(), \
2968 OneByteString(env->isolate(), str), \
2969 var, \
2970 v8::ReadOnly).FromJust(); \
Trevor Norrisc80f8fa2013-08-01 21:53:522971 } while (0)
2972
Petka Antonov872702d2015-02-22 12:44:122973#define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \
2974 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:382975 obj->DefineOwnProperty(env->context(), \
2976 OneByteString(env->isolate(), str), \
2977 var, \
2978 static_cast<v8::PropertyAttribute>(v8::ReadOnly | \
2979 v8::DontEnum)) \
2980 .FromJust(); \
Petka Antonov872702d2015-02-22 12:44:122981 } while (0)
2982
Anna Henningsen9d522222017-04-12 17:17:242983} // anonymous namespace
Trevor Norrisc80f8fa2013-08-01 21:53:522984
Ben Noordhuis756b6222013-08-10 22:26:112985void SetupProcessObject(Environment* env,
2986 int argc,
2987 const char* const* argv,
2988 int exec_argc,
2989 const char* const* exec_argv) {
Fedor Indutny75adde02014-02-21 13:02:422990 HandleScope scope(env->isolate());
Ryan Dahlcd1ec272011-01-02 09:44:422991
Ben Noordhuis756b6222013-08-10 22:26:112992 Local<Object> process = env->process_object();
Ben Noordhuis74a82152012-02-03 15:32:002993
Ben Noordhuisb4ea3a02016-08-21 10:31:202994 auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
2995 CHECK(process->SetAccessor(env->context(),
2996 title_string,
2997 ProcessTitleGetter,
2998 ProcessTitleSetter,
2999 env->as_external()).FromJust());
Ryan Dahl5185c152010-06-18 07:26:493000
Ryan Dahlf4811832009-11-02 23:21:003001 // process.version
Ben Noordhuisf674b092013-08-07 19:50:413002 READONLY_PROPERTY(process,
3003 "version",
Fedor Indutny75adde02014-02-21 13:02:423004 FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
Ryan Dahl39b432e2010-08-17 18:24:103005
Ryan Dahlea9ee1f2011-07-28 02:30:323006 // process.moduleLoadList
Ben Noordhuis756b6222013-08-10 22:26:113007 READONLY_PROPERTY(process,
3008 "moduleLoadList",
3009 env->module_load_list_array());
Ryan Dahlea9ee1f2011-07-28 02:30:323010
Nathan Rajlich35043ad2012-03-13 23:04:173011 // process.versions
Fedor Indutnyce04c722014-03-13 16:38:143012 Local<Object> versions = Object::New(env->isolate());
Trevor Norrisc80f8fa2013-08-01 21:53:523013 READONLY_PROPERTY(process, "versions", versions);
Ben Noordhuisf674b092013-08-07 19:50:413014
3015 const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3016 "."
Johan Bergströmc0a9d1b2015-01-26 23:08:443017 NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
3018 "."
3019 NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
Ben Noordhuisf674b092013-08-07 19:50:413020 READONLY_PROPERTY(versions,
3021 "http_parser",
Fedor Indutny75adde02014-02-21 13:02:423022 FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
Ben Noordhuisf674b092013-08-07 19:50:413023
Ryan Dahl39b432e2010-08-17 18:24:103024 // +1 to get rid of the leading 'v'
Ben Noordhuisf674b092013-08-07 19:50:413025 READONLY_PROPERTY(versions,
3026 "node",
Fedor Indutny75adde02014-02-21 13:02:423027 OneByteString(env->isolate(), NODE_VERSION + 1));
Ben Noordhuisf674b092013-08-07 19:50:413028 READONLY_PROPERTY(versions,
3029 "v8",
Fedor Indutny75adde02014-02-21 13:02:423030 OneByteString(env->isolate(), V8::GetVersion()));
Ben Noordhuisf674b092013-08-07 19:50:413031 READONLY_PROPERTY(versions,
3032 "uv",
Fedor Indutny75adde02014-02-21 13:02:423033 OneByteString(env->isolate(), uv_version_string()));
Ben Noordhuisf674b092013-08-07 19:50:413034 READONLY_PROPERTY(versions,
3035 "zlib",
Fedor Indutny75adde02014-02-21 13:02:423036 FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
Johan Bergström01736dd2015-01-14 00:12:053037 READONLY_PROPERTY(versions,
3038 "ares",
3039 FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
Ben Noordhuisf674b092013-08-07 19:50:413040
3041 const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
Fedor Indutny75adde02014-02-21 13:02:423042 READONLY_PROPERTY(
3043 versions,
3044 "modules",
3045 FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
Ben Noordhuisf674b092013-08-07 19:50:413046
James M Snelle71e71b2017-07-17 17:17:163047 READONLY_PROPERTY(versions,
3048 "nghttp2",
3049 FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
3050
Michael Dawson8938c4c2018-01-09 20:06:283051 const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
3052 READONLY_PROPERTY(
3053 versions,
3054 "napi",
3055 FIXED_ONE_BYTE_STRING(env->isolate(), node_napi_version));
3056
Peter Bright13d6a1f2011-08-06 04:23:253057#if HAVE_OPENSSL
Ryan Dahlcd1ec272011-01-02 09:44:423058 // Stupid code to slice out the version string.
Ben Noordhuis7acdabb2013-11-04 21:42:483059 { // NOLINT(whitespace/braces)
Ben Noordhuis962686b2013-11-03 20:00:373060 size_t i, j, k;
3061 int c;
3062 for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3063 c = OPENSSL_VERSION_TEXT[i];
3064 if ('0' <= c && c <= '9') {
3065 for (j = i + 1; j < k; ++j) {
3066 c = OPENSSL_VERSION_TEXT[j];
3067 if (c == ' ')
3068 break;
3069 }
3070 break;
Ryan Dahlcd1ec272011-01-02 09:44:423071 }
Ryan Dahlcd1ec272011-01-02 09:44:423072 }
Ben Noordhuis962686b2013-11-03 20:00:373073 READONLY_PROPERTY(
3074 versions,
3075 "openssl",
Fedor Indutny75adde02014-02-21 13:02:423076 OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
Ryan Dahlcd1ec272011-01-02 09:44:423077 }
Ryan Dahlcd1ec272011-01-02 09:44:423078#endif
Ryan Dahl39b432e2010-08-17 18:24:103079
Nathan Rajlichb1be5402011-04-26 03:24:513080 // process.arch
Bert Beldere1fe2702015-01-08 12:05:513081 READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
Nathan Rajlichb1be5402011-04-26 03:24:513082
Ryan Dahlf4811832009-11-02 23:21:003083 // process.platform
Vladimir Kurchatkin9f457992015-01-09 12:38:093084 READONLY_PROPERTY(process,
3085 "platform",
3086 OneByteString(env->isolate(), NODE_PLATFORM));
Ryan Dahlf4811832009-11-02 23:21:003087
Rod Vagg04fd4fa2015-01-18 06:41:373088 // process.release
3089 Local<Object> release = Object::New(env->isolate());
3090 READONLY_PROPERTY(process, "release", release);
Anna Henningsen835c3832017-08-08 17:09:283091 READONLY_PROPERTY(release, "name",
3092 OneByteString(env->isolate(), NODE_RELEASE));
Rod Vagg04fd4fa2015-01-18 06:41:373093
Rod Vagg905cd432015-10-06 12:31:143094#if NODE_VERSION_IS_LTS
3095 READONLY_PROPERTY(release, "lts",
3096 OneByteString(env->isolate(), NODE_VERSION_LTS_CODENAME));
3097#endif
3098
Rod Vagg04fd4fa2015-01-18 06:41:373099// if this is a release build and no explicit base has been set
3100// substitute the standard release download URL
3101#ifndef NODE_RELEASE_URLBASE
3102# if NODE_VERSION_IS_RELEASE
cjihriga69ab272015-08-13 16:14:343103# define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
Rod Vagg04fd4fa2015-01-18 06:41:373104# endif
3105#endif
3106
3107#if defined(NODE_RELEASE_URLBASE)
Rod Vagg278a9262015-09-05 04:41:343108# define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
3109# define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
Rod Vagg04fd4fa2015-01-18 06:41:373110
3111 READONLY_PROPERTY(release,
3112 "sourceUrl",
3113 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343114 NODE_RELEASE_URLFPFX ".tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:373115 READONLY_PROPERTY(release,
3116 "headersUrl",
3117 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343118 NODE_RELEASE_URLFPFX "-headers.tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:373119# ifdef _WIN32
3120 READONLY_PROPERTY(release,
3121 "libUrl",
3122 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343123 strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
3124 NODE_ARCH "/node.lib"
3125 : NODE_RELEASE_URLPFX
3126 "win-x86/node.lib"));
Rod Vagg04fd4fa2015-01-18 06:41:373127# endif
3128#endif
3129
Ryan Dahlf3ad6352010-02-03 20:19:083130 // process.argv
Fedor Indutnyce04c722014-03-13 16:38:143131 Local<Array> arguments = Array::New(env->isolate(), argc);
Ben Noordhuis185c5152013-09-02 14:42:013132 for (int i = 0; i < argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:423133 arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
Ryan27b268b2009-06-17 13:05:443134 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203135 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
Ryan27b268b2009-06-17 13:05:443136
Micheil Smith19fd5302012-03-05 17:53:153137 // process.execArgv
Fedor Indutnyce04c722014-03-13 16:38:143138 Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
Ben Noordhuis185c5152013-09-02 14:42:013139 for (int i = 0; i < exec_argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:423140 exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
Micheil Smith19fd5302012-03-05 17:53:153141 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203142 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
3143 exec_arguments);
Micheil Smith19fd5302012-03-05 17:53:153144
Ryan Dahlf3ad6352010-02-03 20:19:083145 // create process.env
Fedor Indutnyce04c722014-03-13 16:38:143146 Local<ObjectTemplate> process_env_template =
3147 ObjectTemplate::New(env->isolate());
AnnaMagab194122016-10-06 20:50:413148 process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3149 EnvGetter,
3150 EnvSetter,
3151 EnvQuery,
3152 EnvDeleter,
3153 EnvEnumerator,
cjihrig1aa595e2016-11-03 16:16:543154 env->as_external()));
AnnaMagab194122016-10-06 20:50:413155
Michaël Zassoad0ce572016-01-26 08:41:293156 Local<Object> process_env =
3157 process_env_template->NewInstance(env->context()).ToLocalChecked();
Ben Noordhuis63c47e72016-10-20 20:36:173158 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
Ryan Dahlf3ad6352010-02-03 20:19:083159
Ben Noordhuis7dc35e92017-11-20 22:37:503160 READONLY_PROPERTY(process, "pid",
cjihriga803bca2017-12-01 14:57:073161 Integer::New(env->isolate(), uv_os_getpid()));
Fedor Indutny75adde02014-02-21 13:02:423162 READONLY_PROPERTY(process, "features", GetFeatures(env));
Ben Noordhuisb4ea3a02016-08-21 10:31:203163
cjihrig2b931512017-11-12 02:10:133164 CHECK(process->SetAccessor(env->context(),
3165 FIXED_ONE_BYTE_STRING(env->isolate(), "ppid"),
3166 GetParentProcessId).FromJust());
cjihrig3cacd342017-10-30 20:14:153167
Anna Henningsen4503da82017-11-20 18:57:203168 auto should_abort_on_uncaught_toggle =
3169 FIXED_ONE_BYTE_STRING(env->isolate(), "_shouldAbortOnUncaughtToggle");
3170 CHECK(process->Set(env->context(),
3171 should_abort_on_uncaught_toggle,
3172 env->should_abort_on_uncaught_toggle().GetJSArray())
3173 .FromJust());
3174
TJ Holowaychuk9481bc12010-10-07 02:05:013175 // -e, --eval
Evan Lucas5b6f5752015-06-01 14:15:103176 if (eval_string) {
Ben Noordhuisf674b092013-08-07 19:50:413177 READONLY_PROPERTY(process,
3178 "_eval",
Evan Lucas5b6f5752015-06-01 14:15:103179 String::NewFromUtf8(env->isolate(), eval_string));
Nathan Rajlichef3a8742012-04-24 08:24:133180 }
3181
3182 // -p, --print
Evan Lucas5b6f5752015-06-01 14:15:103183 if (print_eval) {
Fedor Indutny75adde02014-02-21 13:02:423184 READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
TJ Holowaychuk9481bc12010-10-07 02:05:013185 }
3186
Dave Eddy2e6ece42015-08-17 21:33:133187 // -c, --check
3188 if (syntax_check_only) {
3189 READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
3190 }
3191
Nathan Rajlich6292df62012-04-24 08:32:333192 // -i, --interactive
Evan Lucas5b6f5752015-06-01 14:15:103193 if (force_repl) {
Fedor Indutny75adde02014-02-21 13:02:423194 READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
Nathan Rajlichfeaa8a42012-03-21 07:05:253195 }
3196
Sam Robertse505c072017-04-05 21:04:443197 // -r, --require
Sam Robertscecdf7c2017-04-05 18:45:523198 if (!preload_modules.empty()) {
Ali Ijaz Sheikh1514b822015-02-17 22:37:373199 Local<Array> array = Array::New(env->isolate());
Sam Robertscecdf7c2017-04-05 18:45:523200 for (unsigned int i = 0; i < preload_modules.size(); ++i) {
Evan Lucas5b6f5752015-06-01 14:15:103201 Local<String> module = String::NewFromUtf8(env->isolate(),
Sam Robertscecdf7c2017-04-05 18:45:523202 preload_modules[i].c_str());
Ali Ijaz Sheikh1514b822015-02-17 22:37:373203 array->Set(i, module);
3204 }
3205 READONLY_PROPERTY(process,
3206 "_preload_modules",
3207 array);
Ali Ijaz Sheikhf06b16f2015-03-25 19:19:463208
Sam Robertscecdf7c2017-04-05 18:45:523209 preload_modules.clear();
Ali Ijaz Sheikh1514b822015-02-17 22:37:373210 }
3211
isaacs5b399292012-06-21 18:42:333212 // --no-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103213 if (no_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423214 READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:333215 }
3216
Sam Robertse505c072017-04-05 21:04:443217 // --no-warnings
James M Snellc6656db2016-01-20 19:38:353218 if (no_process_warnings) {
3219 READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
3220 }
3221
Sam Robertse505c072017-04-05 21:04:443222 // --trace-warnings
James M Snellc6656db2016-01-20 19:38:353223 if (trace_warnings) {
3224 READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate()));
3225 }
3226
isaacs5038f402013-03-06 01:46:373227 // --throw-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103228 if (throw_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423229 READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
isaacs5038f402013-03-06 01:46:373230 }
3231
Fedor Indutny8363ede2016-03-23 01:05:543232#ifdef NODE_NO_BROWSER_GLOBALS
3233 // configure --no-browser-globals
3234 READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate()));
3235#endif // NODE_NO_BROWSER_GLOBALS
3236
Matt Loring49440b72015-11-25 14:08:583237 // --prof-process
3238 if (prof_process) {
3239 READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
3240 }
3241
isaacs5b399292012-06-21 18:42:333242 // --trace-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103243 if (trace_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423244 READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:333245 }
3246
cjihrigdf5d8e02017-06-05 02:06:573247 // TODO(refack): move the following 3 to `node_config`
Ben Noordhuise0b076a2017-04-18 20:10:353248 // --inspect-brk
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223249 if (debug_options.wait_for_connect()) {
Refael Ackermann16689e32017-05-29 03:28:013250 READONLY_DONT_ENUM_PROPERTY(process,
3251 "_breakFirstLine", True(env->isolate()));
3252 }
3253
3254 // --inspect --debug-brk
3255 if (debug_options.deprecated_invocation()) {
3256 READONLY_DONT_ENUM_PROPERTY(process,
3257 "_deprecatedDebugBrk", True(env->isolate()));
3258 }
3259
3260 // --debug or, --debug-brk without --inspect
3261 if (debug_options.invalid_invocation()) {
3262 READONLY_DONT_ENUM_PROPERTY(process,
3263 "_invalidDebug", True(env->isolate()));
Ali Ijaz Sheikh4d4cfb22016-05-05 15:31:343264 }
3265
James M Snelld3875912016-02-04 01:16:103266 // --security-revert flags
3267#define V(code, _, __) \
3268 do { \
James M Snell35f6e592017-08-16 16:34:373269 if (IsReverted(SECURITY_REVERT_ ## code)) { \
James M Snelld3875912016-02-04 01:16:103270 READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate())); \
3271 } \
3272 } while (0);
James M Snell35f6e592017-08-16 16:34:373273 SECURITY_REVERSIONS(V)
James M Snelld3875912016-02-04 01:16:103274#undef V
3275
Ben Noordhuisf674b092013-08-07 19:50:413276 size_t exec_path_len = 2 * PATH_MAX;
3277 char* exec_path = new char[exec_path_len];
3278 Local<String> exec_path_value;
3279 if (uv_exepath(exec_path, &exec_path_len) == 0) {
Fedor Indutny75adde02014-02-21 13:02:423280 exec_path_value = String::NewFromUtf8(env->isolate(),
Ben Noordhuisf674b092013-08-07 19:50:413281 exec_path,
3282 String::kNormalString,
3283 exec_path_len);
Marshall Culpepperca35ba62010-06-22 06:31:193284 } else {
Fedor Indutny75adde02014-02-21 13:02:423285 exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
Marshall Culpepperca35ba62010-06-22 06:31:193286 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203287 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"),
3288 exec_path_value);
Ben Noordhuisf674b092013-08-07 19:50:413289 delete[] exec_path;
Marshall Culpepperca35ba62010-06-22 06:31:193290
Ben Noordhuisb4ea3a02016-08-21 10:31:203291 auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort");
3292 CHECK(process->SetAccessor(env->context(),
3293 debug_port_string,
3294 DebugPortGetter,
3295 DebugPortSetter,
3296 env->as_external()).FromJust());
Fedor Indutny3f43b1c2012-02-12 15:53:433297
Ryan Dahl38814552009-10-09 15:15:473298 // define various internal methods
Ben Noordhuisd3c317e2014-10-13 13:19:553299 env->SetMethod(process,
3300 "_startProfilerIdleNotifier",
3301 StartProfilerIdleNotifier);
3302 env->SetMethod(process,
3303 "_stopProfilerIdleNotifier",
3304 StopProfilerIdleNotifier);
3305 env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
3306 env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
3307 env->SetMethod(process, "reallyExit", Exit);
3308 env->SetMethod(process, "abort", Abort);
3309 env->SetMethod(process, "chdir", Chdir);
3310 env->SetMethod(process, "cwd", Cwd);
Bert Belder30bab522010-11-25 00:09:063311
Ben Noordhuisd3c317e2014-10-13 13:19:553312 env->SetMethod(process, "umask", Umask);
Ryan Dahlacc120a2011-08-09 20:53:563313
Ed Schouten78dbcbe2017-10-30 10:58:133314#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
Ben Noordhuisd3c317e2014-10-13 13:19:553315 env->SetMethod(process, "getuid", GetUid);
Evan Lucas3c92ca22015-04-27 16:24:193316 env->SetMethod(process, "geteuid", GetEUid);
Ben Noordhuisd3c317e2014-10-13 13:19:553317 env->SetMethod(process, "setuid", SetUid);
Evan Lucas3c92ca22015-04-27 16:24:193318 env->SetMethod(process, "seteuid", SetEUid);
James Duncandf1c1e52010-02-23 22:45:023319
Ben Noordhuisd3c317e2014-10-13 13:19:553320 env->SetMethod(process, "setgid", SetGid);
Evan Lucas3c92ca22015-04-27 16:24:193321 env->SetMethod(process, "setegid", SetEGid);
Ben Noordhuisd3c317e2014-10-13 13:19:553322 env->SetMethod(process, "getgid", GetGid);
Evan Lucas3c92ca22015-04-27 16:24:193323 env->SetMethod(process, "getegid", GetEGid);
Ben Noordhuis3ece1302012-12-04 05:36:233324
Ben Noordhuisd3c317e2014-10-13 13:19:553325 env->SetMethod(process, "getgroups", GetGroups);
3326 env->SetMethod(process, "setgroups", SetGroups);
3327 env->SetMethod(process, "initgroups", InitGroups);
Ed Schouten78dbcbe2017-10-30 10:58:133328#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
James Duncandf1c1e52010-02-23 22:45:023329
Ben Noordhuisd3c317e2014-10-13 13:19:553330 env->SetMethod(process, "_kill", Kill);
Bert Belder30bab522010-11-25 00:09:063331
Ben Noordhuisd3c317e2014-10-13 13:19:553332 env->SetMethod(process, "_debugProcess", DebugProcess);
Ben Noordhuisd3c317e2014-10-13 13:19:553333 env->SetMethod(process, "_debugEnd", DebugEnd);
Bert Belder829735e2011-11-04 15:23:023334
Ben Noordhuisd3c317e2014-10-13 13:19:553335 env->SetMethod(process, "hrtime", Hrtime);
Nathan Rajlich07c886f2012-03-05 16:51:583336
Patrick Mueller52cb4102016-04-05 13:17:483337 env->SetMethod(process, "cpuUsage", CPUUsage);
3338
Ben Noordhuisd3c317e2014-10-13 13:19:553339 env->SetMethod(process, "dlopen", DLOpen);
Bert Belderdd93c532011-10-28 10:05:093340
Ben Noordhuisd3c317e2014-10-13 13:19:553341 env->SetMethod(process, "uptime", Uptime);
3342 env->SetMethod(process, "memoryUsage", MemoryUsage);
Ryan27b268b2009-06-17 13:05:443343
Ben Noordhuisd3c317e2014-10-13 13:19:553344 env->SetMethod(process, "binding", Binding);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:223345 env->SetMethod(process, "_linkedBinding", LinkedBinding);
Bradley Fariasa36aa042017-10-03 15:07:483346 env->SetMethod(process, "_internalBinding", InternalBinding);
Ryan Dahl627fb5a2010-03-15 20:48:033347
Trevor Norris494227b2015-10-14 20:58:523348 env->SetMethod(process, "_setupProcessObject", SetupProcessObject);
Ben Noordhuisd3c317e2014-10-13 13:19:553349 env->SetMethod(process, "_setupNextTick", SetupNextTick);
Petka Antonov872702d2015-02-22 12:44:123350 env->SetMethod(process, "_setupPromises", SetupPromises);
Ben Noordhuisd3c317e2014-10-13 13:19:553351 env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
Dean McNameef67e8f22011-03-15 22:39:163352}
3353
3354
Trevor Norrisc80f8fa2013-08-01 21:53:523355#undef READONLY_PROPERTY
3356
3357
Anna Henningsen0815b942016-05-08 01:28:473358void SignalExit(int signo) {
Ryan Dahl4e43afd2011-09-30 20:11:473359 uv_tty_reset_mode();
misterpoeba4847e2016-08-05 21:04:253360 if (trace_enabled) {
Myk Melez046f66a2017-01-31 17:56:093361 v8_platform.StopTracingAgent();
misterpoeba4847e2016-08-05 21:04:253362 }
Fedor Indutnyb64983d2015-03-20 05:03:343363#ifdef __FreeBSD__
3364 // FreeBSD has a nasty bug, see RegisterSignalHandler for details
3365 struct sigaction sa;
3366 memset(&sa, 0, sizeof(sa));
3367 sa.sa_handler = SIG_DFL;
3368 CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
3369#endif
Geir Haugec61b0e92014-03-31 07:52:033370 raise(signo);
Dean McNameef67e8f22011-03-15 22:39:163371}
3372
3373
isaacs906a1752013-08-21 22:36:503374// Most of the time, it's best to use `console.error` to write
3375// to the process.stderr stream. However, in some cases, such as
3376// when debugging the stream.Writable class or the process.nextTick
3377// function, it is useful to bypass JavaScript entirely.
3378static void RawDebug(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis5fdff382014-10-11 14:52:073379 CHECK(args.Length() == 1 && args[0]->IsString() &&
3380 "must be called with a single string");
Trevor Norriscbf76c12015-01-07 22:13:353381 node::Utf8Value message(args.GetIsolate(), args[0]);
Brian White2d356072015-10-13 21:18:153382 PrintErrorString("%s\n", *message);
isaacs906a1752013-08-21 22:36:503383 fflush(stderr);
3384}
3385
Fedor Indutny6a610a02014-10-04 14:44:393386void LoadEnvironment(Environment* env) {
Fedor Indutny75adde02014-02-21 13:02:423387 HandleScope handle_scope(env->isolate());
Ben Noordhuis34b0a362013-07-29 03:07:073388
Michaël Zasso79d74752016-01-26 08:06:433389 TryCatch try_catch(env->isolate());
Ryan Dahl9f5643f2010-01-31 07:22:343390
Miroslav Bajtosc16963b2013-06-17 19:19:593391 // Disable verbose mode to stop FatalException() handler from trying
3392 // to handle the exception. Errors this early in the start-up phase
3393 // are not safe to ignore.
3394 try_catch.SetVerbose(false);
3395
Daniel Bevenius81b68822016-06-12 11:14:343396 // Execute the lib/internal/bootstrap_node.js file which was included as a
3397 // static C string in node_natives.h by node_js2c.
3398 // 'internal_bootstrap_node_native' is the string containing that source code.
3399 Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),
3400 "bootstrap_node.js");
Fedor Indutny75adde02014-02-21 13:02:423401 Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
Ryan Dahl9f5643f2010-01-31 07:22:343402 if (try_catch.HasCaught()) {
Fedor Indutnyf1de13b2014-02-05 16:38:333403 ReportException(env, try_catch);
Ryan Dahl9f5643f2010-01-31 07:22:343404 exit(10);
3405 }
Daniel Bevenius0441f2a2016-08-03 08:08:473406 // The bootstrap_node.js file returns a function 'f'
Ben Noordhuis5fdff382014-10-11 14:52:073407 CHECK(f_value->IsFunction());
guybedfordd21a11d2017-09-03 11:20:063408
Ryan Dahl9f5643f2010-01-31 07:22:343409 Local<Function> f = Local<Function>::Cast(f_value);
3410
Ryan Dahlf8ce8482010-09-17 07:01:073411 // Add a reference to the global object
Ben Noordhuis756b6222013-08-10 22:26:113412 Local<Object> global = env->context()->Global();
Zoran Tomicicd98ea702010-02-22 05:15:443413
Ben Noordhuisc4def502013-10-28 19:18:593414#if defined HAVE_DTRACE || defined HAVE_ETW
Fedor Indutny75adde02014-02-21 13:02:423415 InitDTrace(env, global);
Ryan Dahle9257b82011-02-10 02:50:263416#endif
Ryan Dahl068b7332011-01-25 01:50:103417
Glen Keane5e825d12015-01-22 12:35:163418#if defined HAVE_LTTNG
3419 InitLTTNG(env, global);
3420#endif
3421
Scott Blomquistf657ce62012-11-20 23:27:223422#if defined HAVE_PERFCTR
Fedor Indutny75adde02014-02-21 13:02:423423 InitPerfCounters(env, global);
Scott Blomquistf657ce62012-11-20 23:27:223424#endif
3425
Miroslav Bajtosc16963b2013-06-17 19:19:593426 // Enable handling of uncaught exceptions
3427 // (FatalException(), break on uncaught exception in debugger)
3428 //
3429 // This is not strictly necessary since it's almost impossible
Benjamin Fleischer4897ae22017-02-06 01:18:463430 // to attach the debugger fast enough to break on exception
Miroslav Bajtosc16963b2013-06-17 19:19:593431 // thrown during process startup.
3432 try_catch.SetVerbose(true);
Ryan Dahl9f5643f2010-01-31 07:22:343433
Ben Noordhuisd3c317e2014-10-13 13:19:553434 env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
isaacs906a1752013-08-21 22:36:503435
Jeremiah Senkpiel21d66d62016-03-23 22:09:103436 // Expose the global object as a property on itself
3437 // (Allows you to set stuff on `global` from anywhere in JavaScript.)
3438 global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
3439
Daniel Beveniusa01e8bc2016-09-04 18:49:093440 // Now we call 'f' with the 'process' variable that we've built up with
Daniel Bevenius8afde122016-09-06 07:31:023441 // all our bindings. Inside bootstrap_node.js and internal/process we'll
3442 // take care of assigning things to their places.
Daniel Beveniusa01e8bc2016-09-04 18:49:093443
3444 // We start the process this way in order to be more modular. Developers
Daniel Bevenius8afde122016-09-06 07:31:023445 // who do not like how bootstrap_node.js sets up the module system but do
Daniel Beveniusa01e8bc2016-09-04 18:49:093446 // like Node's I/O bindings may want to replace 'f' with their own function.
Ben Noordhuis756b6222013-08-10 22:26:113447 Local<Value> arg = env->process_object();
guybedfordd21a11d2017-09-03 11:20:063448
Trevor Norris92d7e812017-09-22 07:49:493449 auto ret = f->Call(env->context(), Null(env->isolate()), 1, &arg);
3450 // If there was an error during bootstrap then it was either handled by the
3451 // FatalException handler or it's unrecoverable (e.g. max call stack
3452 // exceeded). Either way, clear the stack so that the AsyncCallbackScope
3453 // destructor doesn't fail on the id check.
3454 // There are only two ways to have a stack size > 1: 1) the user manually
3455 // called MakeCallback or 2) user awaited during bootstrap, which triggered
3456 // _tickCallback().
3457 if (ret.IsEmpty())
3458 env->async_hooks()->clear_async_id_stack();
Ryan27b268b2009-06-17 13:05:443459}
3460
Evan Lucas5b6f5752015-06-01 14:15:103461static void PrintHelp() {
Jeremiah Senkpiel91cf55b2016-03-18 17:26:413462 // XXX: If you add an option here, please also add it to doc/node.1 and
Robert Jefe Lindstaedt0800c0a2016-04-20 22:12:403463 // doc/api/cli.md
Ebrahim Byagowi594b5d72017-05-13 07:58:183464 printf("Usage: node [options] [ -e script | script.js | - ] [arguments]\n"
Ali Ijaz Sheikha235ccd2017-03-14 21:20:383465 " node inspect script.js [arguments]\n"
Evan Lucas5b6f5752015-06-01 14:15:103466 "\n"
3467 "Options:\n"
Aashil Patel5d27cc12017-01-21 22:44:293468 " -v, --version print Node.js version\n"
3469 " -e, --eval script evaluate script\n"
3470 " -p, --print evaluate script and print result\n"
3471 " -c, --check syntax check script without executing\n"
3472 " -i, --interactive always enter the REPL even if stdin\n"
3473 " does not appear to be a terminal\n"
3474 " -r, --require module to preload (option can be "
misterpoeba4847e2016-08-05 21:04:253475 "repeated)\n"
Ebrahim Byagowi594b5d72017-05-13 07:58:183476 " - script read from stdin (default; "
Josh Ferge7f545f02017-05-30 21:13:133477 "interactive mode if a tty)\n"
Josh Gavant6ff3b032016-12-15 04:18:153478#if HAVE_INSPECTOR
Gibson Fahnestock2d2970e2017-03-28 15:54:303479 " --inspect[=[host:]port] activate inspector on host:port\n"
Aashil Patel5d27cc12017-01-21 22:44:293480 " (default: 127.0.0.1:9229)\n"
Gibson Fahnestock2d2970e2017-03-28 15:54:303481 " --inspect-brk[=[host:]port]\n"
3482 " activate inspector on host:port\n"
Josh Gavant6ff3b032016-12-15 04:18:153483 " and break at start of user script\n"
Sam Roberts3954ea92017-04-22 03:34:543484 " --inspect-port=[host:]port\n"
3485 " set host:port for inspector\n"
Josh Gavant6ff3b032016-12-15 04:18:153486#endif
Aashil Patel5d27cc12017-01-21 22:44:293487 " --no-deprecation silence deprecation warnings\n"
3488 " --trace-deprecation show stack traces on deprecations\n"
3489 " --throw-deprecation throw an exception on deprecations\n"
Ruslan Bekenev896be832017-04-30 16:00:283490 " --pending-deprecation emit pending deprecation warnings\n"
Aashil Patel5d27cc12017-01-21 22:44:293491 " --no-warnings silence all process warnings\n"
Gabriel Schulhofa8c0a432017-08-18 10:30:053492 " --napi-modules load N-API modules (no-op - option\n"
3493 " kept for compatibility)\n"
Sam Roberts388e5522017-06-26 18:00:343494 " --abort-on-uncaught-exception\n"
3495 " aborting instead of exiting causes a\n"
3496 " core file to be generated for analysis\n"
Aashil Patel5d27cc12017-01-21 22:44:293497 " --trace-warnings show stack traces on process warnings\n"
Sam Robertsa886b172017-05-19 17:53:383498 " --redirect-warnings=file\n"
3499 " write warnings to file instead of\n"
James M Snell03e89b32016-12-04 18:38:353500 " stderr\n"
Aashil Patel5d27cc12017-01-21 22:44:293501 " --trace-sync-io show stack trace when use of sync IO\n"
3502 " is detected after the first tick\n"
Andreas Madsen23a39112017-10-19 12:15:083503 " --no-force-async-hooks-checks\n"
3504 " disable checks for async_hooks\n"
Aashil Patel5d27cc12017-01-21 22:44:293505 " --trace-events-enabled track trace events\n"
3506 " --trace-event-categories comma separated list of trace event\n"
3507 " categories to record\n"
3508 " --track-heap-objects track heap object allocations for heap "
Bradley Meckcf14a242015-07-09 16:15:263509 "snapshots\n"
Aashil Patel5d27cc12017-01-21 22:44:293510 " --prof-process process v8 profiler output generated\n"
3511 " using --prof\n"
3512 " --zero-fill-buffers automatically zero-fill all newly "
misterpoeba4847e2016-08-05 21:04:253513 "allocated\n"
Aashil Patel5d27cc12017-01-21 22:44:293514 " Buffer and SlowBuffer instances\n"
3515 " --v8-options print v8 command line options\n"
3516 " --v8-pool-size=num set v8's thread pool size\n"
James M Snell5ba868f2015-08-17 22:51:513517#if HAVE_OPENSSL
Aashil Patel5d27cc12017-01-21 22:44:293518 " --tls-cipher-list=val use an alternative default TLS cipher "
misterpoeba4847e2016-08-05 21:04:253519 "list\n"
Aashil Patel5d27cc12017-01-21 22:44:293520 " --use-bundled-ca use bundled CA store"
Adam Majer33012e92016-12-21 10:16:393521#if !defined(NODE_OPENSSL_CERT_STORE)
3522 " (default)"
3523#endif
3524 "\n"
Aashil Patel5d27cc12017-01-21 22:44:293525 " --use-openssl-ca use OpenSSL's default CA store"
Adam Majer33012e92016-12-21 10:16:393526#if defined(NODE_OPENSSL_CERT_STORE)
3527 " (default)"
3528#endif
3529 "\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093530#if NODE_FIPS_MODE
Aashil Patel5d27cc12017-01-21 22:44:293531 " --enable-fips enable FIPS crypto at startup\n"
3532 " --force-fips force FIPS crypto (cannot be disabled)\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093533#endif /* NODE_FIPS_MODE */
Sam Roberts59afa272017-01-25 22:13:343534 " --openssl-config=file load OpenSSL configuration from the\n"
3535 " specified file (overrides\n"
3536 " OPENSSL_CONF)\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093537#endif /* HAVE_OPENSSL */
Evan Lucas5b6f5752015-06-01 14:15:103538#if defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293539 " --icu-data-dir=dir set ICU data load path to dir\n"
3540 " (overrides NODE_ICU_DATA)\n"
Evan Lucas5b6f5752015-06-01 14:15:103541#if !defined(NODE_HAVE_SMALL_ICU)
Aashil Patel5d27cc12017-01-21 22:44:293542 " note: linked-in ICU data is present\n"
Evan Lucas5b6f5752015-06-01 14:15:103543#endif
Aashil Patel5d27cc12017-01-21 22:44:293544 " --preserve-symlinks preserve symbolic links when resolving\n"
Bradley Fariasc8a389e2017-06-06 00:44:563545 " --experimental-modules experimental ES Module support\n"
Aashil Patel5d27cc12017-01-21 22:44:293546 " and caching modules\n"
Evan Lucas5b6f5752015-06-01 14:15:103547#endif
3548 "\n"
3549 "Environment variables:\n"
Aashil Patel5d27cc12017-01-21 22:44:293550 "NODE_DEBUG ','-separated list of core modules\n"
3551 " that should print debug information\n"
3552 "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n"
3553 "NODE_EXTRA_CA_CERTS path to additional CA certificates\n"
3554 " file\n"
Evan Lucas5b6f5752015-06-01 14:15:103555#if defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293556 "NODE_ICU_DATA data path for ICU (Intl object) data\n"
Evan Lucas5b6f5752015-06-01 14:15:103557#if !defined(NODE_HAVE_SMALL_ICU)
Aashil Patel5d27cc12017-01-21 22:44:293558 " (will extend linked-in data)\n"
Evan Lucas5b6f5752015-06-01 14:15:103559#endif
3560#endif
Aashil Patel5d27cc12017-01-21 22:44:293561 "NODE_NO_WARNINGS set to 1 to silence process warnings\n"
Sam Robertsf2282bb2017-02-20 14:18:433562#if !defined(NODE_WITHOUT_NODE_OPTIONS)
3563 "NODE_OPTIONS set CLI options in the environment\n"
Gabriel Schulhof6fe72c82017-08-09 06:58:003564 " via a space-separated list\n"
Sam Robertsf2282bb2017-02-20 14:18:433565#endif
Roman Reiss2d235622016-12-22 06:10:223566#ifdef _WIN32
Aashil Patel5d27cc12017-01-21 22:44:293567 "NODE_PATH ';'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223568#else
Aashil Patel5d27cc12017-01-21 22:44:293569 "NODE_PATH ':'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223570#endif
Aashil Patel5d27cc12017-01-21 22:44:293571 " prefixed to the module search path\n"
Thomas Corbière28a0af32017-09-25 12:45:433572 "NODE_PENDING_DEPRECATION set to 1 to emit pending deprecation\n"
3573 " warnings\n"
Aashil Patel5d27cc12017-01-21 22:44:293574 "NODE_REPL_HISTORY path to the persistent REPL history\n"
3575 " file\n"
James M Snell03e89b32016-12-04 18:38:353576 "NODE_REDIRECT_WARNINGS write warnings to path instead of\n"
3577 " stderr\n"
Sam Roberts59afa272017-01-25 22:13:343578 "OPENSSL_CONF load OpenSSL configuration from file\n"
3579 "\n"
cjihriga69ab272015-08-13 16:14:343580 "Documentation can be found at https://nodejs.org/\n");
Evan Lucas5b6f5752015-06-01 14:15:103581}
3582
3583
Sam Roberts97a6aa92017-07-05 21:25:553584static bool ArgIsAllowed(const char* arg, const char* allowed) {
3585 for (; *arg && *allowed; arg++, allowed++) {
3586 // Like normal strcmp(), except that a '_' in `allowed` matches either a '-'
3587 // or '_' in `arg`.
3588 if (*allowed == '_') {
3589 if (!(*arg == '_' || *arg == '-'))
3590 return false;
3591 } else {
3592 if (*arg != *allowed)
3593 return false;
3594 }
3595 }
3596
3597 // "--some-arg=val" is allowed for "--some-arg"
3598 if (*arg == '=')
3599 return true;
3600
3601 // Both must be null, or one string is just a prefix of the other, not a
3602 // match.
3603 return !*arg && !*allowed;
3604}
3605
3606
Sam Robertsf2282bb2017-02-20 14:18:433607static void CheckIfAllowedInEnv(const char* exe, bool is_env,
3608 const char* arg) {
3609 if (!is_env)
3610 return;
3611
Sam Robertsf2282bb2017-02-20 14:18:433612 static const char* whitelist[] = {
Sam Robertsb6593852017-05-23 16:02:073613 // Node options, sorted in `node --help` order for ease of comparison.
Sam Robertsd6cd4662017-05-12 19:39:113614 "--require", "-r",
3615 "--inspect",
3616 "--inspect-brk",
3617 "--inspect-port",
Sam Robertsf2282bb2017-02-20 14:18:433618 "--no-deprecation",
Sam Robertsd6cd4662017-05-12 19:39:113619 "--trace-deprecation",
3620 "--throw-deprecation",
Thomas Corbière3d7f7b2a2017-09-20 13:08:193621 "--pending-deprecation",
Sam Robertsf2282bb2017-02-20 14:18:433622 "--no-warnings",
Sam Robertsd6cd4662017-05-12 19:39:113623 "--napi-modules",
James M Snellf55ee6e2017-09-21 17:07:563624 "--expose-http2", // keep as a non-op through v9.x
guybedfordd21a11d2017-09-03 11:20:063625 "--experimental-modules",
3626 "--loader",
Sam Robertsf2282bb2017-02-20 14:18:433627 "--trace-warnings",
3628 "--redirect-warnings",
Sam Robertsf2282bb2017-02-20 14:18:433629 "--trace-sync-io",
Andreas Madsen23a39112017-10-19 12:15:083630 "--no-force-async-hooks-checks",
Sam Robertsf2282bb2017-02-20 14:18:433631 "--trace-events-enabled",
Evan Lucas701dc9a2017-11-28 11:46:353632 "--trace-event-categories",
Sam Robertsf2282bb2017-02-20 14:18:433633 "--track-heap-objects",
Sam Robertsf2282bb2017-02-20 14:18:433634 "--zero-fill-buffers",
3635 "--v8-pool-size",
Sam Robertsb6593852017-05-23 16:02:073636 "--tls-cipher-list",
Sam Robertsf2282bb2017-02-20 14:18:433637 "--use-bundled-ca",
Sam Robertsd6cd4662017-05-12 19:39:113638 "--use-openssl-ca",
Sam Robertsf2282bb2017-02-20 14:18:433639 "--enable-fips",
3640 "--force-fips",
3641 "--openssl-config",
3642 "--icu-data-dir",
3643
Sam Roberts97a6aa92017-07-05 21:25:553644 // V8 options (define with '_', which allows '-' or '_')
3645 "--abort_on_uncaught_exception",
Sam Robertsf2282bb2017-02-20 14:18:433646 "--max_old_space_size",
Anna Henningsen89b32282017-10-25 17:51:583647 "--stack_trace_limit",
Sam Robertsf2282bb2017-02-20 14:18:433648 };
3649
3650 for (unsigned i = 0; i < arraysize(whitelist); i++) {
3651 const char* allowed = whitelist[i];
Sam Roberts97a6aa92017-07-05 21:25:553652 if (ArgIsAllowed(arg, allowed))
Sam Robertsf2282bb2017-02-20 14:18:433653 return;
3654 }
3655
3656 fprintf(stderr, "%s: %s is not allowed in NODE_OPTIONS\n", exe, arg);
3657 exit(9);
3658}
3659
3660
Evan Lucas5b6f5752015-06-01 14:15:103661// Parse command line arguments.
3662//
3663// argv is modified in place. exec_argv and v8_argv are out arguments that
3664// ParseArgs() allocates memory for and stores a pointer to the output
3665// vector in. The caller should free them with delete[].
3666//
3667// On exit:
3668//
3669// * argv contains the arguments with node and V8 options filtered out.
3670// * exec_argv contains both node and V8 options and nothing else.
3671// * v8_argv contains argv[0] plus any V8 options
3672static void ParseArgs(int* argc,
3673 const char** argv,
3674 int* exec_argc,
3675 const char*** exec_argv,
3676 int* v8_argc,
Sam Robertsf2282bb2017-02-20 14:18:433677 const char*** v8_argv,
3678 bool is_env) {
Evan Lucas5b6f5752015-06-01 14:15:103679 const unsigned int nargs = static_cast<unsigned int>(*argc);
3680 const char** new_exec_argv = new const char*[nargs];
3681 const char** new_v8_argv = new const char*[nargs];
3682 const char** new_argv = new const char*[nargs];
Daniel Beveniusde168b42017-04-10 13:13:243683#if HAVE_OPENSSL
Daniel Bevenius8a7db9d2017-03-28 06:56:393684 bool use_bundled_ca = false;
3685 bool use_openssl_ca = false;
Daniel Bevenius892ce062017-04-27 03:45:343686#endif // HAVE_OPENSSL
Evan Lucas5b6f5752015-06-01 14:15:103687
3688 for (unsigned int i = 0; i < nargs; ++i) {
3689 new_exec_argv[i] = nullptr;
3690 new_v8_argv[i] = nullptr;
3691 new_argv[i] = nullptr;
Evan Lucas5b6f5752015-06-01 14:15:103692 }
3693
3694 // exec_argv starts with the first option, the other two start with argv[0].
3695 unsigned int new_exec_argc = 0;
3696 unsigned int new_v8_argc = 1;
3697 unsigned int new_argc = 1;
3698 new_v8_argv[0] = argv[0];
3699 new_argv[0] = argv[0];
3700
3701 unsigned int index = 1;
Matt Loring49440b72015-11-25 14:08:583702 bool short_circuit = false;
3703 while (index < nargs && argv[index][0] == '-' && !short_circuit) {
Evan Lucas5b6f5752015-06-01 14:15:103704 const char* const arg = argv[index];
3705 unsigned int args_consumed = 1;
3706
Sam Robertsf2282bb2017-02-20 14:18:433707 CheckIfAllowedInEnv(argv[0], is_env, arg);
3708
Sam Roberts3954ea92017-04-22 03:34:543709 if (debug_options.ParseOption(argv[0], arg)) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223710 // Done, consumed by DebugOptions::ParseOption().
Evan Lucas5b6f5752015-06-01 14:15:103711 } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3712 printf("%s\n", NODE_VERSION);
3713 exit(0);
3714 } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3715 PrintHelp();
3716 exit(0);
3717 } else if (strcmp(arg, "--eval") == 0 ||
3718 strcmp(arg, "-e") == 0 ||
3719 strcmp(arg, "--print") == 0 ||
3720 strcmp(arg, "-pe") == 0 ||
3721 strcmp(arg, "-p") == 0) {
3722 bool is_eval = strchr(arg, 'e') != nullptr;
3723 bool is_print = strchr(arg, 'p') != nullptr;
3724 print_eval = print_eval || is_print;
3725 // --eval, -e and -pe always require an argument.
3726 if (is_eval == true) {
3727 args_consumed += 1;
3728 eval_string = argv[index + 1];
3729 if (eval_string == nullptr) {
3730 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3731 exit(9);
3732 }
3733 } else if ((index + 1 < nargs) &&
3734 argv[index + 1] != nullptr &&
3735 argv[index + 1][0] != '-') {
3736 args_consumed += 1;
3737 eval_string = argv[index + 1];
3738 if (strncmp(eval_string, "\\-", 2) == 0) {
3739 // Starts with "\\-": escaped expression, drop the backslash.
3740 eval_string += 1;
3741 }
3742 }
3743 } else if (strcmp(arg, "--require") == 0 ||
3744 strcmp(arg, "-r") == 0) {
3745 const char* module = argv[index + 1];
3746 if (module == nullptr) {
3747 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3748 exit(9);
3749 }
3750 args_consumed += 1;
Sam Robertscecdf7c2017-04-05 18:45:523751 preload_modules.push_back(module);
Dave Eddy2e6ece42015-08-17 21:33:133752 } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3753 syntax_check_only = true;
Evan Lucas5b6f5752015-06-01 14:15:103754 } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3755 force_repl = true;
3756 } else if (strcmp(arg, "--no-deprecation") == 0) {
3757 no_deprecation = true;
Jason Ginchereau56e881d2017-03-20 21:55:263758 } else if (strcmp(arg, "--napi-modules") == 0) {
Gabriel Schulhofa8c0a432017-08-18 10:30:053759 // no-op
James M Snellc6656db2016-01-20 19:38:353760 } else if (strcmp(arg, "--no-warnings") == 0) {
3761 no_process_warnings = true;
3762 } else if (strcmp(arg, "--trace-warnings") == 0) {
3763 trace_warnings = true;
James M Snell03e89b32016-12-04 18:38:353764 } else if (strncmp(arg, "--redirect-warnings=", 20) == 0) {
3765 config_warning_file = arg + 20;
Evan Lucas5b6f5752015-06-01 14:15:103766 } else if (strcmp(arg, "--trace-deprecation") == 0) {
3767 trace_deprecation = true;
3768 } else if (strcmp(arg, "--trace-sync-io") == 0) {
3769 trace_sync_io = true;
Andreas Madsen23a39112017-10-19 12:15:083770 } else if (strcmp(arg, "--no-force-async-hooks-checks") == 0) {
3771 no_force_async_hooks_checks = true;
misterpoeba4847e2016-08-05 21:04:253772 } else if (strcmp(arg, "--trace-events-enabled") == 0) {
3773 trace_enabled = true;
3774 } else if (strcmp(arg, "--trace-event-categories") == 0) {
3775 const char* categories = argv[index + 1];
3776 if (categories == nullptr) {
3777 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3778 exit(9);
3779 }
3780 args_consumed += 1;
3781 trace_enabled_categories = categories;
Bradley Meckcf14a242015-07-09 16:15:263782 } else if (strcmp(arg, "--track-heap-objects") == 0) {
3783 track_heap_objects = true;
Evan Lucas5b6f5752015-06-01 14:15:103784 } else if (strcmp(arg, "--throw-deprecation") == 0) {
3785 throw_deprecation = true;
James M Snelld3875912016-02-04 01:16:103786 } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3787 const char* cve = arg + 18;
3788 Revert(cve);
James M Snell5d38d542016-05-02 23:31:203789 } else if (strcmp(arg, "--preserve-symlinks") == 0) {
3790 config_preserve_symlinks = true;
Bradley Fariasc8a389e2017-06-06 00:44:563791 } else if (strcmp(arg, "--experimental-modules") == 0) {
3792 config_experimental_modules = true;
guybedfordd21a11d2017-09-03 11:20:063793 } else if (strcmp(arg, "--loader") == 0) {
3794 const char* module = argv[index + 1];
3795 if (!config_experimental_modules) {
3796 fprintf(stderr, "%s: %s requires --experimental-modules be enabled\n",
3797 argv[0], arg);
3798 exit(9);
3799 }
3800 if (module == nullptr) {
3801 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3802 exit(9);
3803 }
3804 args_consumed += 1;
3805 config_userland_loader = module;
Matt Loring49440b72015-11-25 14:08:583806 } else if (strcmp(arg, "--prof-process") == 0) {
3807 prof_process = true;
3808 short_circuit = true;
James M Snell85ab4a52016-01-25 23:00:063809 } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
3810 zero_fill_all_buffers = true;
James M Snella16b5702017-03-11 20:18:533811 } else if (strcmp(arg, "--pending-deprecation") == 0) {
3812 config_pending_deprecation = true;
Evan Lucas5b6f5752015-06-01 14:15:103813 } else if (strcmp(arg, "--v8-options") == 0) {
3814 new_v8_argv[new_v8_argc] = "--help";
3815 new_v8_argc += 1;
Tom Gallacher03e07d32015-12-18 12:24:563816 } else if (strncmp(arg, "--v8-pool-size=", 15) == 0) {
3817 v8_thread_pool_size = atoi(arg + 15);
James M Snell5ba868f2015-08-17 22:51:513818#if HAVE_OPENSSL
3819 } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) {
3820 default_cipher_list = arg + 18;
Adam Majer33012e92016-12-21 10:16:393821 } else if (strncmp(arg, "--use-openssl-ca", 16) == 0) {
3822 ssl_openssl_cert_store = true;
Daniel Bevenius8a7db9d2017-03-28 06:56:393823 use_openssl_ca = true;
Adam Majer33012e92016-12-21 10:16:393824 } else if (strncmp(arg, "--use-bundled-ca", 16) == 0) {
Daniel Bevenius8a7db9d2017-03-28 06:56:393825 use_bundled_ca = true;
Adam Majer33012e92016-12-21 10:16:393826 ssl_openssl_cert_store = false;
Stefan Budeanu7c48cb52016-01-22 23:10:093827#if NODE_FIPS_MODE
3828 } else if (strcmp(arg, "--enable-fips") == 0) {
3829 enable_fips_crypto = true;
3830 } else if (strcmp(arg, "--force-fips") == 0) {
3831 force_fips_crypto = true;
3832#endif /* NODE_FIPS_MODE */
Fedor Indutnydb411cf2016-09-29 08:53:303833 } else if (strncmp(arg, "--openssl-config=", 17) == 0) {
Sam Roberts59afa272017-01-25 22:13:343834 openssl_config.assign(arg + 17);
Stefan Budeanu7c48cb52016-01-22 23:10:093835#endif /* HAVE_OPENSSL */
Evan Lucas5b6f5752015-06-01 14:15:103836#if defined(NODE_HAVE_I18N_SUPPORT)
3837 } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
Ben Noordhuis291b5992017-02-11 13:04:583838 icu_data_dir.assign(arg + 15);
Evan Lucas5b6f5752015-06-01 14:15:103839#endif
3840 } else if (strcmp(arg, "--expose-internals") == 0 ||
3841 strcmp(arg, "--expose_internals") == 0) {
Sam Roberts8086cb62017-04-05 21:06:523842 config_expose_internals = true;
James M Snelle71e71b2017-07-17 17:17:163843 } else if (strcmp(arg, "--expose-http2") == 0 ||
3844 strcmp(arg, "--expose_http2") == 0) {
James M Snellf55ee6e2017-09-21 17:07:563845 // Keep as a non-op through v9.x
Ebrahim Byagowi594b5d72017-05-13 07:58:183846 } else if (strcmp(arg, "-") == 0) {
3847 break;
John Barboza0a9f3602016-12-30 05:28:383848 } else if (strcmp(arg, "--") == 0) {
3849 index += 1;
3850 break;
Sam Roberts53dae832017-05-12 19:47:473851 } else if (strcmp(arg, "--abort-on-uncaught-exception") == 0 ||
3852 strcmp(arg, "--abort_on_uncaught_exception") == 0) {
Trevor Norrisc0bde732017-03-07 19:40:183853 abort_on_uncaught_exception = true;
3854 // Also a V8 option. Pass through as-is.
3855 new_v8_argv[new_v8_argc] = arg;
3856 new_v8_argc += 1;
Evan Lucas5b6f5752015-06-01 14:15:103857 } else {
3858 // V8 option. Pass through as-is.
3859 new_v8_argv[new_v8_argc] = arg;
3860 new_v8_argc += 1;
3861 }
3862
3863 memcpy(new_exec_argv + new_exec_argc,
3864 argv + index,
3865 args_consumed * sizeof(*argv));
3866
3867 new_exec_argc += args_consumed;
3868 index += args_consumed;
3869 }
3870
Daniel Bevenius8a7db9d2017-03-28 06:56:393871#if HAVE_OPENSSL
3872 if (use_openssl_ca && use_bundled_ca) {
3873 fprintf(stderr,
3874 "%s: either --use-openssl-ca or --use-bundled-ca can be used, "
3875 "not both\n",
3876 argv[0]);
3877 exit(9);
3878 }
3879#endif
3880
Teddy Katza5f91ab2017-03-30 06:35:033881 if (eval_string != nullptr && syntax_check_only) {
3882 fprintf(stderr,
3883 "%s: either --check or --eval can be used, not both\n", argv[0]);
3884 exit(9);
3885 }
3886
Evan Lucas5b6f5752015-06-01 14:15:103887 // Copy remaining arguments.
3888 const unsigned int args_left = nargs - index;
Sam Robertsf2282bb2017-02-20 14:18:433889
3890 if (is_env && args_left) {
3891 fprintf(stderr, "%s: %s is not supported in NODE_OPTIONS\n",
3892 argv[0], argv[index]);
3893 exit(9);
3894 }
3895
Evan Lucas5b6f5752015-06-01 14:15:103896 memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3897 new_argc += args_left;
3898
3899 *exec_argc = new_exec_argc;
3900 *exec_argv = new_exec_argv;
3901 *v8_argc = new_v8_argc;
3902 *v8_argv = new_v8_argv;
3903
3904 // Copy new_argv over argv and update argc.
3905 memcpy(argv, new_argv, new_argc * sizeof(*argv));
3906 delete[] new_argv;
3907 *argc = static_cast<int>(new_argc);
Evan Lucas5b6f5752015-06-01 14:15:103908}
3909
Bert Belder829735e2011-11-04 15:23:023910
Sam Roberts26ab7692017-05-30 23:34:593911static void StartInspector(Environment* env, const char* path,
3912 DebugOptions debug_options) {
Eugene Ostroukhov7599b0e2016-12-13 01:08:313913#if HAVE_INSPECTOR
Eugene Ostroukhov5c263782017-05-01 20:31:143914 CHECK(!env->inspector_agent()->IsStarted());
3915 v8_platform.StartInspector(env, path, debug_options);
Eugene Ostroukhov7599b0e2016-12-13 01:08:313916#endif // HAVE_INSPECTOR
Ryan Dahl2a7e7b12010-12-18 19:17:293917}
3918
3919
Fedor Indutny82d0ac72011-09-24 13:51:593920#ifdef __POSIX__
Anna Henningsen0815b942016-05-08 01:28:473921void RegisterSignalHandler(int signal,
3922 void (*handler)(int signal),
3923 bool reset_handler) {
Tom Hughesf61b1102010-10-12 21:01:583924 struct sigaction sa;
Tom Hughesf61b1102010-10-12 21:01:583925 memset(&sa, 0, sizeof(sa));
3926 sa.sa_handler = handler;
Fedor Indutnyb64983d2015-03-20 05:03:343927#ifndef __FreeBSD__
3928 // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
3929 // in turn set for a libthr wrapper. This leads to a crash.
3930 // Work around the issue by manually setting SIG_DFL in the signal handler
Geir Haugec61b0e92014-03-31 07:52:033931 sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
Fedor Indutnyb64983d2015-03-20 05:03:343932#endif
Tom Hughesf61b1102010-10-12 21:01:583933 sigfillset(&sa.sa_mask);
Ben Noordhuis2d82cdf2014-10-22 01:29:323934 CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
Bert Belder829735e2011-11-04 15:23:023935}
3936
3937
Ben Noordhuis110a9cd2013-07-03 02:23:443938void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553939 Environment* env = Environment::GetCurrent(args);
Bert Belder829735e2011-11-04 15:23:023940
3941 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423942 return env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023943 }
3944
3945 pid_t pid;
3946 int r;
3947
3948 pid = args[0]->IntegerValue();
3949 r = kill(pid, SIGUSR1);
3950 if (r != 0) {
Fedor Indutny75adde02014-02-21 13:02:423951 return env->ThrowErrnoException(errno, "kill");
Bert Belder829735e2011-11-04 15:23:023952 }
Tom Hughesf61b1102010-10-12 21:01:583953}
Fedor Indutny8e29ce92013-07-31 18:07:293954#endif // __POSIX__
Tom Hughesf61b1102010-10-12 21:01:583955
3956
Bert Belder829735e2011-11-04 15:23:023957#ifdef _WIN32
Bert Belder8f2694b2012-02-16 21:19:483958static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
3959 size_t buf_len) {
3960 return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
Bert Belder829735e2011-11-04 15:23:023961}
3962
3963
Ben Noordhuis110a9cd2013-07-03 02:23:443964static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553965 Environment* env = Environment::GetCurrent(args);
Alexis Campailla440b9e22014-02-24 18:55:273966 Isolate* isolate = args.GetIsolate();
Bert Belder829735e2011-11-04 15:23:023967 DWORD pid;
Ben Noordhuis2d82cdf2014-10-22 01:29:323968 HANDLE process = nullptr;
3969 HANDLE thread = nullptr;
3970 HANDLE mapping = nullptr;
Bert Belder8f2694b2012-02-16 21:19:483971 wchar_t mapping_name[32];
Ben Noordhuis2d82cdf2014-10-22 01:29:323972 LPTHREAD_START_ROUTINE* handler = nullptr;
Bert Belder829735e2011-11-04 15:23:023973
3974 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423975 env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023976 goto out;
3977 }
3978
3979 pid = (DWORD) args[0]->IntegerValue();
3980
Bert Belder68db2062012-02-03 14:37:463981 process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
Bert Belder829735e2011-11-04 15:23:023982 PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
3983 PROCESS_VM_READ,
3984 FALSE,
3985 pid);
Ben Noordhuis2d82cdf2014-10-22 01:29:323986 if (process == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273987 isolate->ThrowException(
3988 WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
Bert Belder829735e2011-11-04 15:23:023989 goto out;
3990 }
3991
3992 if (GetDebugSignalHandlerMappingName(pid,
3993 mapping_name,
Ben Noordhuisa7581d02016-03-31 10:47:063994 arraysize(mapping_name)) < 0) {
Fedor Indutny75adde02014-02-21 13:02:423995 env->ThrowErrnoException(errno, "sprintf");
Bert Belder829735e2011-11-04 15:23:023996 goto out;
3997 }
3998
Bert Belder8f2694b2012-02-16 21:19:483999 mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
Ben Noordhuis2d82cdf2014-10-22 01:29:324000 if (mapping == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274001 isolate->ThrowException(WinapiErrnoException(isolate,
Fedor Indutny75adde02014-02-21 13:02:424002 GetLastError(),
4003 "OpenFileMappingW"));
Bert Belder829735e2011-11-04 15:23:024004 goto out;
4005 }
4006
Bert Belder8f2694b2012-02-16 21:19:484007 handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
4008 MapViewOfFile(mapping,
4009 FILE_MAP_READ,
4010 0,
4011 0,
4012 sizeof *handler));
Ben Noordhuis2d82cdf2014-10-22 01:29:324013 if (handler == nullptr || *handler == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274014 isolate->ThrowException(
4015 WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
Bert Belder829735e2011-11-04 15:23:024016 goto out;
4017 }
4018
Bert Belder68db2062012-02-03 14:37:464019 thread = CreateRemoteThread(process,
Ben Noordhuis2d82cdf2014-10-22 01:29:324020 nullptr,
Bert Belder829735e2011-11-04 15:23:024021 0,
4022 *handler,
Ben Noordhuis2d82cdf2014-10-22 01:29:324023 nullptr,
Bert Belder829735e2011-11-04 15:23:024024 0,
Ben Noordhuis2d82cdf2014-10-22 01:29:324025 nullptr);
4026 if (thread == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274027 isolate->ThrowException(WinapiErrnoException(isolate,
4028 GetLastError(),
4029 "CreateRemoteThread"));
Bert Belder829735e2011-11-04 15:23:024030 goto out;
4031 }
4032
4033 // Wait for the thread to terminate
4034 if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
Alexis Campailla440b9e22014-02-24 18:55:274035 isolate->ThrowException(WinapiErrnoException(isolate,
4036 GetLastError(),
4037 "WaitForSingleObject"));
Bert Belder829735e2011-11-04 15:23:024038 goto out;
4039 }
4040
4041 out:
Ben Noordhuis2d82cdf2014-10-22 01:29:324042 if (process != nullptr)
Fedor Indutny8e29ce92013-07-31 18:07:294043 CloseHandle(process);
Ben Noordhuis2d82cdf2014-10-22 01:29:324044 if (thread != nullptr)
Bert Belder829735e2011-11-04 15:23:024045 CloseHandle(thread);
Ben Noordhuis2d82cdf2014-10-22 01:29:324046 if (handler != nullptr)
Bert Belder829735e2011-11-04 15:23:024047 UnmapViewOfFile(handler);
Ben Noordhuis2d82cdf2014-10-22 01:29:324048 if (mapping != nullptr)
Bert Belder829735e2011-11-04 15:23:024049 CloseHandle(mapping);
Bert Belder829735e2011-11-04 15:23:024050}
Fedor Indutny8e29ce92013-07-31 18:07:294051#endif // _WIN32
Bert Belder829735e2011-11-04 15:23:024052
4053
Ben Noordhuis110a9cd2013-07-03 02:23:444054static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
Michaël Zasso719247f2017-04-24 13:35:564055#if HAVE_INSPECTOR
Eugene Ostroukhov5c263782017-05-01 20:31:144056 Environment* env = Environment::GetCurrent(args);
4057 if (env->inspector_agent()->IsStarted()) {
Michaël Zasso719247f2017-04-24 13:35:564058 env->inspector_agent()->Stop();
Fedor Indutny3f43b1c2012-02-12 15:53:434059 }
Eugene Ostroukhov5c263782017-05-01 20:31:144060#endif
Fedor Indutny3f43b1c2012-02-12 15:53:434061}
4062
4063
Ben Noordhuis5756f922015-01-26 22:15:204064inline void PlatformInit() {
4065#ifdef __POSIX__
Daniel Bevenius65a6e052017-04-07 06:48:324066#if HAVE_INSPECTOR
Ben Noordhuis63ae1d22015-01-26 22:26:334067 sigset_t sigmask;
4068 sigemptyset(&sigmask);
4069 sigaddset(&sigmask, SIGUSR1);
Ben Noordhuisb5f25a92015-02-18 02:43:294070 const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
Daniel Bevenius65a6e052017-04-07 06:48:324071#endif // HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:294072
4073 // Make sure file descriptors 0-2 are valid before we start logging anything.
4074 for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
4075 struct stat ignored;
4076 if (fstat(fd, &ignored) == 0)
4077 continue;
4078 // Anything but EBADF means something is seriously wrong. We don't
4079 // have to special-case EINTR, fstat() is not interruptible.
4080 if (errno != EBADF)
Evan Lucas870229e2015-09-16 15:12:414081 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:294082 if (fd != open("/dev/null", O_RDWR))
Evan Lucas870229e2015-09-16 15:12:414083 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:294084 }
4085
Daniel Bevenius65a6e052017-04-07 06:48:324086#if HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:294087 CHECK_EQ(err, 0);
Daniel Bevenius65a6e052017-04-07 06:48:324088#endif // HAVE_INSPECTOR
Ben Noordhuisdd47a8c2015-01-26 23:07:344089
Stewart X Addison0f0f3d32016-12-30 12:44:464090#ifndef NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:344091 // Restore signal dispositions, the parent process may have changed them.
4092 struct sigaction act;
4093 memset(&act, 0, sizeof(act));
4094
4095 // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
4096 // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
4097 // Counting up to SIGRTMIN doesn't work for the same reason.
Eugene Ostroukhov66269192016-06-08 21:09:284098 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
Ben Noordhuisdd47a8c2015-01-26 23:07:344099 if (nr == SIGKILL || nr == SIGSTOP)
4100 continue;
4101 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
4102 CHECK_EQ(0, sigaction(nr, &act, nullptr));
4103 }
Stewart X Addison0f0f3d32016-12-30 12:44:464104#endif // !NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:344105
Ben Noordhuis63ae1d22015-01-26 22:26:334106 RegisterSignalHandler(SIGINT, SignalExit, true);
4107 RegisterSignalHandler(SIGTERM, SignalExit, true);
Ben Noordhuisdd47a8c2015-01-26 23:07:344108
Ben Noordhuis5756f922015-01-26 22:15:204109 // Raise the open file descriptor limit.
4110 struct rlimit lim;
4111 if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
4112 // Do a binary search for the limit.
4113 rlim_t min = lim.rlim_cur;
4114 rlim_t max = 1 << 20;
4115 // But if there's a defined upper bound, don't search, just set it.
4116 if (lim.rlim_max != RLIM_INFINITY) {
4117 min = lim.rlim_max;
4118 max = lim.rlim_max;
4119 }
4120 do {
4121 lim.rlim_cur = min + (max - min) / 2;
4122 if (setrlimit(RLIMIT_NOFILE, &lim)) {
4123 max = lim.rlim_cur;
4124 } else {
4125 min = lim.rlim_cur;
4126 }
4127 } while (min + 1 < max);
4128 }
Ben Noordhuis5756f922015-01-26 22:15:204129#endif // __POSIX__
Bartosz Sosnowskibd496e02017-03-14 17:22:534130#ifdef _WIN32
4131 for (int fd = 0; fd <= 2; ++fd) {
4132 auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
4133 if (handle == INVALID_HANDLE_VALUE ||
4134 GetFileType(handle) == FILE_TYPE_UNKNOWN) {
4135 // Ignore _close result. If it fails or not depends on used Windows
4136 // version. We will just check _open result.
4137 _close(fd);
4138 if (fd != _open("nul", _O_RDWR))
4139 ABORT();
4140 }
4141 }
4142#endif // _WIN32
Ben Noordhuis5756f922015-01-26 22:15:204143}
4144
4145
Sam Robertsf2282bb2017-02-20 14:18:434146void ProcessArgv(int* argc,
4147 const char** argv,
4148 int* exec_argc,
4149 const char*** exec_argv,
4150 bool is_env = false) {
4151 // Parse a few arguments which are specific to Node.
4152 int v8_argc;
4153 const char** v8_argv;
4154 ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv, is_env);
4155
4156 // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
4157 // manually? That would give us a little more control over its runtime
4158 // behavior but it could also interfere with the user's intentions in ways
4159 // we fail to anticipate. Dillema.
4160 for (int i = 1; i < v8_argc; ++i) {
4161 if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
4162 v8_is_profiling = true;
4163 break;
4164 }
4165 }
4166
4167#ifdef __POSIX__
4168 // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the
4169 // performance penalty of frequent EINTR wakeups when the profiler is running.
4170 // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
4171 if (v8_is_profiling) {
4172 uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
4173 }
4174#endif
4175
4176 // The const_cast doesn't violate conceptual const-ness. V8 doesn't modify
4177 // the argv array or the elements it points to.
4178 if (v8_argc > 1)
4179 V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
4180
4181 // Anything that's still in v8_argv is not a V8 or a node option.
4182 for (int i = 1; i < v8_argc; i++) {
4183 fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
4184 }
4185 delete[] v8_argv;
4186 v8_argv = nullptr;
4187
4188 if (v8_argc > 1) {
4189 exit(9);
4190 }
4191}
4192
4193
Ben Noordhuis185c5152013-09-02 14:42:014194void Init(int* argc,
4195 const char** argv,
4196 int* exec_argc,
4197 const char*** exec_argv) {
Ben Noordhuis74a82152012-02-03 15:32:004198 // Initialize prog_start_time to get relative uptime.
Rasmus Christian Pedersen734fb492014-09-18 12:10:534199 prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
Ben Noordhuis74a82152012-02-03 15:32:004200
Yihong Wang8680bb92017-10-22 06:16:504201 // Register built-in modules
4202 node::RegisterBuiltinModules();
4203
Bert Belder09be3602012-06-13 23:28:514204 // Make inherited handles noninheritable.
4205 uv_disable_stdio_inheritance();
4206
Ben Noordhuis490d5ab2014-03-31 12:22:494207#if defined(NODE_V8_OPTIONS)
4208 // Should come before the call to V8::SetFlagsFromCommandLine()
4209 // so the user can disable a flag --foo at run-time by passing
4210 // --no_foo from the command line.
4211 V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
4212#endif
Fedor Indutnyb55c9d62014-03-26 20:30:494213
James M Snella16b5702017-03-11 20:18:534214 {
4215 std::string text;
4216 config_pending_deprecation =
4217 SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1';
4218 }
4219
Marc Udoffd3b1a2b2016-09-20 22:21:444220 // Allow for environment set preserving symlinks.
Ben Noordhuisa8734af2017-01-28 12:27:024221 {
4222 std::string text;
4223 config_preserve_symlinks =
4224 SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
Marc Udoffd3b1a2b2016-09-20 22:21:444225 }
4226
Ben Noordhuisa8734af2017-01-28 12:27:024227 if (config_warning_file.empty())
4228 SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file);
James M Snell03e89b32016-12-04 18:38:354229
Daniel Beveniuse1d88992017-02-28 19:04:124230#if HAVE_OPENSSL
Sam Roberts59afa272017-01-25 22:13:344231 if (openssl_config.empty())
4232 SafeGetenv("OPENSSL_CONF", &openssl_config);
Daniel Beveniuse1d88992017-02-28 19:04:124233#endif
Sam Roberts59afa272017-01-25 22:13:344234
Sam Robertsf2282bb2017-02-20 14:18:434235#if !defined(NODE_WITHOUT_NODE_OPTIONS)
4236 std::string node_options;
4237 if (SafeGetenv("NODE_OPTIONS", &node_options)) {
4238 // Smallest tokens are 2-chars (a not space and a space), plus 2 extra
4239 // pointers, for the prepended executable name, and appended NULL pointer.
4240 size_t max_len = 2 + (node_options.length() + 1) / 2;
4241 const char** argv_from_env = new const char*[max_len];
4242 int argc_from_env = 0;
4243 // [0] is expected to be the program name, fill it in from the real argv.
4244 argv_from_env[argc_from_env++] = argv[0];
Evan Lucas5b6f5752015-06-01 14:15:104245
Sam Robertsf2282bb2017-02-20 14:18:434246 char* cstr = strdup(node_options.c_str());
4247 char* initptr = cstr;
4248 char* token;
4249 while ((token = strtok(initptr, " "))) { // NOLINT(runtime/threadsafe_fn)
4250 initptr = nullptr;
4251 argv_from_env[argc_from_env++] = token;
Ben Noordhuis9566fe82013-10-03 08:45:324252 }
Sam Robertsf2282bb2017-02-20 14:18:434253 argv_from_env[argc_from_env] = nullptr;
4254 int exec_argc_;
4255 const char** exec_argv_ = nullptr;
4256 ProcessArgv(&argc_from_env, argv_from_env, &exec_argc_, &exec_argv_, true);
4257 delete[] exec_argv_;
4258 delete[] argv_from_env;
4259 free(cstr);
Oleksandr Chekhovskyi8e141352015-08-07 13:03:044260 }
4261#endif
4262
Sam Robertsf2282bb2017-02-20 14:18:434263 ProcessArgv(argc, argv, exec_argc, exec_argv);
4264
Steven R. Loomisac2857b2014-09-05 05:03:244265#if defined(NODE_HAVE_I18N_SUPPORT)
Ben Noordhuisa8734af2017-01-28 12:27:024266 // If the parameter isn't given, use the env variable.
4267 if (icu_data_dir.empty())
4268 SafeGetenv("NODE_ICU_DATA", &icu_data_dir);
Steven R. Loomisac2857b2014-09-05 05:03:244269 // Initialize ICU.
Ben Noordhuisa8734af2017-01-28 12:27:024270 // If icu_data_dir is empty here, it will load the 'minimal' data.
Steven R. Loomisac2857b2014-09-05 05:03:244271 if (!i18n::InitializeICUDirectory(icu_data_dir)) {
Ben Noordhuis46e773c2017-05-16 13:15:144272 fprintf(stderr,
4273 "%s: could not initialize ICU "
Timothy Gu93308352017-06-26 03:59:444274 "(check NODE_ICU_DATA or --icu-data-dir parameters)\n",
Ben Noordhuis46e773c2017-05-16 13:15:144275 argv[0]);
4276 exit(9);
Steven R. Loomisac2857b2014-09-05 05:03:244277 }
4278#endif
Tom Hughes78da9cb2010-10-18 22:50:564279
Ben Noordhuis05948d82017-11-23 23:13:444280 // Needed for access to V8 intrinsics. Disabled again during bootstrapping,
4281 // see lib/internal/bootstrap_node.js.
4282 const char allow_natives_syntax[] = "--allow_natives_syntax";
4283 V8::SetFlagsFromString(allow_natives_syntax,
4284 sizeof(allow_natives_syntax) - 1);
4285
Cheng Zhao22e1aea2015-01-12 21:31:254286 // We should set node_is_initialized here instead of in node::Start,
4287 // otherwise embedders using node::Init to initialize everything will not be
4288 // able to set it and native modules will not load for them.
4289 node_is_initialized = true;
Ben Noordhuis5866f1a2011-12-09 18:02:334290}
Ben Noordhuis356992f2011-11-22 16:10:094291
Ben Noordhuis5866f1a2011-12-09 18:02:334292
Ben Noordhuis756b6222013-08-10 22:26:114293void RunAtExit(Environment* env) {
Daniel Beveniusec539212017-03-21 07:06:434294 env->RunAtExitCallbacks();
Ben Noordhuise4a8d262012-04-21 05:13:254295}
4296
4297
Anna Henningsenc0f3bc22017-11-17 21:13:184298uv_loop_t* GetCurrentEventLoop(v8::Isolate* isolate) {
4299 HandleScope handle_scope(isolate);
4300 auto context = isolate->GetCurrentContext();
4301 if (context.IsEmpty())
4302 return nullptr;
4303 return Environment::GetCurrent(context)->event_loop();
4304}
4305
4306
Daniel Beveniusec539212017-03-21 07:06:434307static uv_key_t thread_local_env;
4308
4309
Ben Noordhuise4a8d262012-04-21 05:13:254310void AtExit(void (*cb)(void* arg), void* arg) {
Daniel Beveniusec539212017-03-21 07:06:434311 auto env = static_cast<Environment*>(uv_key_get(&thread_local_env));
4312 AtExit(env, cb, arg);
4313}
4314
4315
4316void AtExit(Environment* env, void (*cb)(void* arg), void* arg) {
4317 CHECK_NE(env, nullptr);
4318 env->AtExit(cb, arg);
Ben Noordhuise4a8d262012-04-21 05:13:254319}
4320
4321
Anatoli Papirovski8803b692018-01-18 21:52:514322void RunBeforeExit(Environment* env) {
4323 env->RunBeforeExitCallbacks();
4324
4325 if (!uv_loop_alive(env->event_loop()))
4326 EmitBeforeExit(env);
4327}
4328
4329
Ben Noordhuisa2eeb432013-10-07 13:39:394330void EmitBeforeExit(Environment* env) {
Ben Noordhuisa2eeb432013-10-07 13:39:394331 HandleScope handle_scope(env->isolate());
Fedor Indutnye2c90402015-03-12 21:19:164332 Context::Scope context_scope(env->context());
Ben Noordhuisa2eeb432013-10-07 13:39:394333 Local<Object> process_object = env->process_object();
4334 Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(), "exitCode");
4335 Local<Value> args[] = {
4336 FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
Leko19221d12017-11-27 07:16:324337 process_object->Get(exit_code)->ToInteger(env->context()).ToLocalChecked()
Ben Noordhuisa2eeb432013-10-07 13:39:394338 };
Anna Henningsena86323d2017-05-21 17:39:524339 MakeCallback(env->isolate(),
4340 process_object, "emit", arraysize(args), args,
Andreas Madsenc6ce5002017-07-06 06:20:034341 {0, 0}).ToLocalChecked();
Ben Noordhuisa2eeb432013-10-07 13:39:394342}
4343
4344
Fedor Indutnye57ab7b2014-01-18 22:49:334345int EmitExit(Environment* env) {
Ben Noordhuis5866f1a2011-12-09 18:02:334346 // process.emit('exit')
Ben Noordhuis756b6222013-08-10 22:26:114347 HandleScope handle_scope(env->isolate());
Ben Noordhuis27f115d2013-11-11 09:53:004348 Context::Scope context_scope(env->context());
Ben Noordhuis756b6222013-08-10 22:26:114349 Local<Object> process_object = env->process_object();
Fedor Indutny75adde02014-02-21 13:02:424350 process_object->Set(env->exiting_string(), True(env->isolate()));
isaacsa5dba822013-09-06 23:46:354351
Michaël Zasso4abc8962015-07-18 09:34:164352 Local<String> exitCode = env->exit_code_string();
Rasmus Christian Pedersen734fb492014-09-18 12:10:534353 int code = process_object->Get(exitCode)->Int32Value();
isaacsa5dba822013-09-06 23:46:354354
Ben Noordhuisf674b092013-08-07 19:50:414355 Local<Value> args[] = {
Fedor Indutny75adde02014-02-21 13:02:424356 env->exit_string(),
Fedor Indutnyce04c722014-03-13 16:38:144357 Integer::New(env->isolate(), code)
Ben Noordhuisf674b092013-08-07 19:50:414358 };
isaacsa5dba822013-09-06 23:46:354359
Anna Henningsena86323d2017-05-21 17:39:524360 MakeCallback(env->isolate(),
4361 process_object, "emit", arraysize(args), args,
Andreas Madsenc6ce5002017-07-06 06:20:034362 {0, 0}).ToLocalChecked();
Fedor Indutnyc0d81f92014-02-09 10:40:574363
4364 // Reload exit code, it may be changed by `emit('exit')`
Rasmus Christian Pedersen734fb492014-09-18 12:10:534365 return process_object->Get(exitCode)->Int32Value();
Ben Noordhuis756b6222013-08-10 22:26:114366}
4367
4368
Ben Noordhuisc3cd4532016-05-31 14:42:524369IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) {
Anna Henningsenc7ad7292017-09-14 11:05:484370 return new IsolateData(isolate, loop, nullptr);
4371}
4372
4373IsolateData* CreateIsolateData(
4374 Isolate* isolate,
4375 uv_loop_t* loop,
4376 MultiIsolatePlatform* platform) {
4377 return new IsolateData(isolate, loop, platform);
Ben Noordhuisc3cd4532016-05-31 14:42:524378}
4379
4380
4381void FreeIsolateData(IsolateData* isolate_data) {
4382 delete isolate_data;
4383}
4384
4385
4386Environment* CreateEnvironment(IsolateData* isolate_data,
Michaël Zasso4abc8962015-07-18 09:34:164387 Local<Context> context,
Fedor Indutny6a610a02014-10-04 14:44:394388 int argc,
4389 const char* const* argv,
4390 int exec_argc,
4391 const char* const* exec_argv) {
Ben Noordhuisc3cd4532016-05-31 14:42:524392 Isolate* isolate = context->GetIsolate();
Ben Noordhuis756b6222013-08-10 22:26:114393 HandleScope handle_scope(isolate);
Ben Noordhuis756b6222013-08-10 22:26:114394 Context::Scope context_scope(context);
Ben Noordhuisaac79df2016-06-01 09:18:024395 auto env = new Environment(isolate_data, context);
Ben Noordhuis58cec4e2016-06-01 08:54:424396 env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
Ben Noordhuis756b6222013-08-10 22:26:114397 return env;
Ben Noordhuis5866f1a2011-12-09 18:02:334398}
4399
Micheil Smith19fd5302012-03-05 17:53:154400
Ben Noordhuisaac79df2016-06-01 09:18:024401void FreeEnvironment(Environment* env) {
4402 delete env;
4403}
4404
4405
Cheng Zhao27281122017-11-13 02:41:204406MultiIsolatePlatform* CreatePlatform(
4407 int thread_pool_size,
4408 v8::TracingController* tracing_controller) {
4409 return new NodePlatform(thread_pool_size, tracing_controller);
4410}
4411
4412
4413void FreePlatform(MultiIsolatePlatform* platform) {
4414 delete platform;
4415}
4416
4417
Ben Noordhuis668ad442017-09-07 11:26:474418Local<Context> NewContext(Isolate* isolate,
4419 Local<ObjectTemplate> object_template) {
4420 auto context = Context::New(isolate, nullptr, object_template);
4421 if (context.IsEmpty()) return context;
4422 HandleScope handle_scope(isolate);
4423 auto intl_key = FIXED_ONE_BYTE_STRING(isolate, "Intl");
4424 auto break_iter_key = FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
4425 Local<Value> intl_v;
Ben Noordhuis668ad442017-09-07 11:26:474426 if (context->Global()->Get(context, intl_key).ToLocal(&intl_v) &&
Timothy Gu2146c88b2017-10-17 05:29:414427 intl_v->IsObject()) {
4428 Local<Object> intl = intl_v.As<Object>();
Ben Noordhuis668ad442017-09-07 11:26:474429 intl->Delete(context, break_iter_key).FromJust();
4430 }
4431 return context;
4432}
4433
4434
Ben Noordhuisceb60232016-10-21 12:24:484435inline int Start(Isolate* isolate, IsolateData* isolate_data,
4436 int argc, const char* const* argv,
4437 int exec_argc, const char* const* exec_argv) {
4438 HandleScope handle_scope(isolate);
Ben Noordhuis668ad442017-09-07 11:26:474439 Local<Context> context = NewContext(isolate);
Ben Noordhuisceb60232016-10-21 12:24:484440 Context::Scope context_scope(context);
4441 Environment env(isolate_data, context);
Daniel Beveniusec539212017-03-21 07:06:434442 CHECK_EQ(0, uv_key_create(&thread_local_env));
4443 uv_key_set(&thread_local_env, &env);
Ben Noordhuisceb60232016-10-21 12:24:484444 env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4445
Eugene Ostroukhov7599b0e2016-12-13 01:08:314446 const char* path = argc > 1 ? argv[1] : nullptr;
Sam Roberts26ab7692017-05-30 23:34:594447 StartInspector(&env, path, debug_options);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:224448
Eugene Ostroukhov5c263782017-05-01 20:31:144449 if (debug_options.inspector_enabled() && !v8_platform.InspectorStarted(&env))
Eugene Ostroukhov7599b0e2016-12-13 01:08:314450 return 12; // Signal internal error.
Ben Noordhuisceb60232016-10-21 12:24:484451
Trevor Norrisc0bde732017-03-07 19:40:184452 env.set_abort_on_uncaught_exception(abort_on_uncaught_exception);
4453
Andreas Madsen23a39112017-10-19 12:15:084454 if (no_force_async_hooks_checks) {
4455 env.async_hooks()->no_force_checks();
Andreas Madsen7c079d12017-10-19 10:43:404456 }
4457
Ben Noordhuisceb60232016-10-21 12:24:484458 {
4459 Environment::AsyncCallbackScope callback_scope(&env);
Andreas Madsen3a69ef52017-09-26 13:50:104460 env.async_hooks()->push_async_ids(1, 0);
Ben Noordhuisceb60232016-10-21 12:24:484461 LoadEnvironment(&env);
Andreas Madsen3a69ef52017-09-26 13:50:104462 env.async_hooks()->pop_async_id(1);
Ben Noordhuisceb60232016-10-21 12:24:484463 }
4464
4465 env.set_trace_sync_io(trace_sync_io);
4466
Ben Noordhuisceb60232016-10-21 12:24:484467 {
4468 SealHandleScope seal(isolate);
4469 bool more;
James M Snell67269fd2017-08-07 22:53:244470 PERFORMANCE_MARK(&env, LOOP_START);
Ben Noordhuisceb60232016-10-21 12:24:484471 do {
Matt Loring9e086952017-03-13 22:17:574472 uv_run(env.event_loop(), UV_RUN_DEFAULT);
Ben Noordhuisceb60232016-10-21 12:24:484473
Anna Henningsenc7ad7292017-09-14 11:05:484474 v8_platform.DrainVMTasks(isolate);
Anna Henningsenf27b5e42017-09-15 13:03:484475
4476 more = uv_loop_alive(env.event_loop());
4477 if (more)
4478 continue;
4479
Anatoli Papirovski8803b692018-01-18 21:52:514480 RunBeforeExit(&env);
Ben Noordhuisceb60232016-10-21 12:24:484481
Matt Loring9e086952017-03-13 22:17:574482 // Emit `beforeExit` if the loop became alive either after emitting
4483 // event, or after running some callbacks.
4484 more = uv_loop_alive(env.event_loop());
Ben Noordhuisceb60232016-10-21 12:24:484485 } while (more == true);
James M Snell67269fd2017-08-07 22:53:244486 PERFORMANCE_MARK(&env, LOOP_EXIT);
Ben Noordhuisceb60232016-10-21 12:24:484487 }
4488
4489 env.set_trace_sync_io(false);
4490
4491 const int exit_code = EmitExit(&env);
4492 RunAtExit(&env);
Daniel Beveniusec539212017-03-21 07:06:434493 uv_key_delete(&thread_local_env);
Ben Noordhuisceb60232016-10-21 12:24:484494
Anna Henningsenc7ad7292017-09-14 11:05:484495 v8_platform.DrainVMTasks(isolate);
Anna Henningsen2cedff92017-10-22 22:52:554496 v8_platform.CancelVMTasks(isolate);
Ben Noordhuisceb60232016-10-21 12:24:484497 WaitForInspectorDisconnect(&env);
4498#if defined(LEAK_SANITIZER)
4499 __lsan_do_leak_check();
4500#endif
4501
4502 return exit_code;
4503}
4504
Ben Noordhuisd77e8182016-10-21 11:47:494505inline int Start(uv_loop_t* event_loop,
4506 int argc, const char* const* argv,
4507 int exec_argc, const char* const* exec_argv) {
Ben Noordhuis9a03ae62015-07-01 21:47:374508 Isolate::CreateParams params;
Ben Noordhuisceb60232016-10-21 12:24:484509 ArrayBufferAllocator allocator;
4510 params.array_buffer_allocator = &allocator;
Chunyang Daia881b532015-10-21 16:24:124511#ifdef NODE_ENABLE_VTUNE_PROFILING
4512 params.code_event_handler = vTune::GetVtuneCodeEventHandler();
4513#endif
Ben Noordhuisceb60232016-10-21 12:24:484514
4515 Isolate* const isolate = Isolate::New(params);
4516 if (isolate == nullptr)
4517 return 12; // Signal internal error.
4518
4519 isolate->AddMessageListener(OnMessage);
4520 isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
4521 isolate->SetAutorunMicrotasks(false);
4522 isolate->SetFatalErrorHandler(OnFatalError);
4523
Ben Noordhuisd7087df2016-06-17 23:39:054524 {
4525 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuisd77e8182016-10-21 11:47:494526 CHECK_EQ(node_isolate, nullptr);
4527 node_isolate = isolate;
Ben Noordhuis844f0a92016-03-25 16:59:074528 }
Ben Noordhuis844f0a92016-03-25 16:59:074529
Ben Noordhuisd77e8182016-10-21 11:47:494530 int exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474531 {
4532 Locker locker(isolate);
4533 Isolate::Scope isolate_scope(isolate);
4534 HandleScope handle_scope(isolate);
Anna Henningsenc7ad7292017-09-14 11:05:484535 IsolateData isolate_data(
4536 isolate,
4537 event_loop,
4538 v8_platform.Platform(),
4539 allocator.zero_fill_field());
Hannes Payer91d13122017-11-22 13:43:424540 if (track_heap_objects) {
4541 isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
4542 }
Ben Noordhuisceb60232016-10-21 12:24:484543 exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
Petka Antonov4ae64b22015-03-03 20:25:474544 }
4545
Ben Noordhuisd7087df2016-06-17 23:39:054546 {
4547 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuisceb60232016-10-21 12:24:484548 CHECK_EQ(node_isolate, isolate);
4549 node_isolate = nullptr;
Ben Noordhuisd7087df2016-06-17 23:39:054550 }
Ben Noordhuis53e64bb2015-10-26 13:11:034551
Petka Antonov4ae64b22015-03-03 20:25:474552 isolate->Dispose();
Ben Noordhuisd77e8182016-10-21 11:47:494553
4554 return exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474555}
4556
Ben Noordhuis185c5152013-09-02 14:42:014557int Start(int argc, char** argv) {
Ben Noordhuisceb60232016-10-21 12:24:484558 atexit([] () { uv_tty_reset_mode(); });
Ben Noordhuis5756f922015-01-26 22:15:204559 PlatformInit();
James M Snell67269fd2017-08-07 22:53:244560 node::performance::performance_node_start = PERFORMANCE_NOW();
Ben Noordhuis5756f922015-01-26 22:15:204561
Ben Noordhuis5fdff382014-10-11 14:52:074562 CHECK_GT(argc, 0);
Micheil Smith19fd5302012-03-05 17:53:154563
Ben Noordhuis185c5152013-09-02 14:42:014564 // Hack around with the argv pointer. Used for process.title = "blah".
Ben Noordhuis1a979982012-03-15 22:10:324565 argv = uv_setup_args(argc, argv);
4566
Ben Noordhuis185c5152013-09-02 14:42:014567 // This needs to run *before* V8::Initialize(). The const_cast is not
4568 // optional, in case you're wondering.
4569 int exec_argc;
4570 const char** exec_argv;
4571 Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
Ben Noordhuis5866f1a2011-12-09 18:02:334572
Ben Noordhuis7ac23912013-09-20 20:01:494573#if HAVE_OPENSSL
Ben Noordhuisa8734af2017-01-28 12:27:024574 {
4575 std::string extra_ca_certs;
4576 if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
4577 crypto::UseExtraCaCerts(extra_ca_certs);
4578 }
Stefan Budeanu7c48cb52016-01-22 23:10:094579#ifdef NODE_FIPS_MODE
4580 // In the case of FIPS builds we should make sure
4581 // the random source is properly initialized first.
4582 OPENSSL_init();
4583#endif // NODE_FIPS_MODE
Ben Noordhuis7ac23912013-09-20 20:01:494584 // V8 on Windows doesn't have a good source of entropy. Seed it from
4585 // OpenSSL's pool.
4586 V8::SetEntropySource(crypto::EntropySource);
Ben Noordhuisa8734af2017-01-28 12:27:024587#endif // HAVE_OPENSSL
Ben Noordhuis7ac23912013-09-20 20:01:494588
Anna Henningsenc7ad7292017-09-14 11:05:484589 v8_platform.Initialize(v8_thread_pool_size);
misterpoeba4847e2016-08-05 21:04:254590 // Enable tracing when argv has --trace-events-enabled.
4591 if (trace_enabled) {
4592 fprintf(stderr, "Warning: Trace event is an experimental feature "
4593 "and could change at any time.\n");
Myk Melez046f66a2017-01-31 17:56:094594 v8_platform.StartTracingAgent();
misterpoeba4847e2016-08-05 21:04:254595 }
Ben Noordhuis75ea5662013-09-23 12:27:264596 V8::Initialize();
James M Snell67269fd2017-08-07 22:53:244597 node::performance::performance_v8_start = PERFORMANCE_NOW();
Anna Henningsen72c60e82016-09-10 16:21:204598 v8_initialized = true;
Ben Noordhuisd77e8182016-10-21 11:47:494599 const int exit_code =
4600 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
misterpoeba4847e2016-08-05 21:04:254601 if (trace_enabled) {
Myk Melez046f66a2017-01-31 17:56:094602 v8_platform.StopTracingAgent();
misterpoeba4847e2016-08-05 21:04:254603 }
Anna Henningsen72c60e82016-09-10 16:21:204604 v8_initialized = false;
Ryan27b268b2009-06-17 13:05:444605 V8::Dispose();
Igor Zinkovskya58b6432011-07-07 20:54:304606
Matt Loring9e086952017-03-13 22:17:574607 // uv_run cannot be called from the time before the beforeExit callback
4608 // runs until the program exits unless the event loop has any referenced
4609 // handles after beforeExit terminates. This prevents unrefed timers
4610 // that happen to terminate during shutdown from being run unsafely.
4611 // Since uv_run cannot be called, uv_async handles held by the platform
4612 // will never be fully cleaned up.
Stefan Budeanu410296c2016-03-27 00:17:554613 v8_platform.Dispose();
Ben Noordhuis4a801c22015-04-02 21:51:014614
Ben Noordhuis185c5152013-09-02 14:42:014615 delete[] exec_argv;
Ben Noordhuis2d82cdf2014-10-22 01:29:324616 exec_argv = nullptr;
Micheil Smith19fd5302012-03-05 17:53:154617
Petka Antonov4ae64b22015-03-03 20:25:474618 return exit_code;
Ryan19478ed2009-03-03 00:56:154619}
Ryan Dahl124fbed2010-09-19 20:13:574620
Yihong Wang8680bb92017-10-22 06:16:504621// Call built-in modules' _register_<module name> function to
4622// do module registration explicitly.
4623void RegisterBuiltinModules() {
4624#define V(modname) _register_##modname();
4625 NODE_BUILTIN_MODULES(V)
4626#undef V
4627}
Ryan Dahl124fbed2010-09-19 20:13:574628
4629} // namespace node
Eugene Ostroukhov3f48ab32017-04-25 21:55:554630
4631#if !HAVE_INSPECTOR
Yihong Wang8680bb92017-10-22 06:16:504632void InitEmptyBindings() {}
Eugene Ostroukhov3f48ab32017-04-25 21:55:554633
Yihong Wang8680bb92017-10-22 06:16:504634NODE_BUILTIN_MODULE_CONTEXT_AWARE(inspector, InitEmptyBindings)
Eugene Ostroukhov3f48ab32017-04-25 21:55:554635#endif // !HAVE_INSPECTOR