blob: 21296a1418ad34adc19818730a58ed3e67adaa7d [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 Noordhuisff4a9d32012-03-09 23:11:1122#include "node.h"
Ben Noordhuis02cab972013-07-31 21:16:0823#include "node_buffer.h"
24#include "node_constants.h"
Ben Noordhuis02cab972013-07-31 21:16:0825#include "node_javascript.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"
Ben Noordhuis02cab972013-07-31 21:16:0830
31#if defined HAVE_PERFCTR
32#include "node_counters.h"
33#endif
34
35#if HAVE_OPENSSL
36#include "node_crypto.h"
37#endif
38
Steven R. Loomisac2857b2014-09-05 05:03:2439#if defined(NODE_HAVE_I18N_SUPPORT)
40#include "node_i18n.h"
41#endif
42
Ben Noordhuisc4def502013-10-28 19:18:5943#if defined HAVE_DTRACE || defined HAVE_ETW
Ben Noordhuis02cab972013-07-31 21:16:0844#include "node_dtrace.h"
45#endif
46
Glen Keane5e825d12015-01-22 12:35:1647#if defined HAVE_LTTNG
48#include "node_lttng.h"
49#endif
50
Bert Belder22d03c92012-08-06 23:48:1551#include "ares.h"
Trevor Norrisefa62fd2013-09-24 21:12:1152#include "async-wrap.h"
53#include "async-wrap-inl.h"
Ben Noordhuis756b6222013-08-10 22:26:1154#include "env.h"
55#include "env-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0856#include "handle_wrap.h"
Ben Noordhuis38dc0cd2015-01-30 11:54:5357#include "req-wrap.h"
58#include "req-wrap-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0859#include "string_bytes.h"
misterpoeba4847e2016-08-05 21:04:2560#include "tracing/agent.h"
Timothy J Fontaine1a09da62014-06-10 23:36:0461#include "util.h"
Ben Noordhuisff4a9d32012-03-09 23:11:1162#include "uv.h"
Stefan Budeanu410296c2016-03-27 00:17:5563#if NODE_USE_V8_PLATFORM
Ben Noordhuis4a801c22015-04-02 21:51:0164#include "libplatform/libplatform.h"
Stefan Budeanu410296c2016-03-27 00:17:5565#endif // NODE_USE_V8_PLATFORM
Ben Noordhuisff4a9d32012-03-09 23:11:1166#include "v8-debug.h"
Ben Noordhuis57231d52013-10-02 04:37:4467#include "v8-profiler.h"
Ben Noordhuis02cab972013-07-31 21:16:0868#include "zlib.h"
Ryan Dahl4635ed72010-03-11 20:40:1969
Chunyang Daia881b532015-10-21 16:24:1270#ifdef NODE_ENABLE_VTUNE_PROFILING
71#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
72#endif
73
Ben Noordhuis02cab972013-07-31 21:16:0874#include <errno.h>
75#include <limits.h> // PATH_MAX
Bert Beldere0f47be2011-01-17 23:22:3676#include <locale.h>
Bert Belder9cec08e2011-05-23 23:42:2277#include <signal.h>
Ryan19478ed2009-03-03 00:56:1578#include <stdio.h>
Ryan34a6f102009-05-28 12:47:1679#include <stdlib.h>
Ryan Dahlc90e44e2010-05-10 23:38:4780#include <string.h>
Ben Noordhuis02cab972013-07-31 21:16:0881#include <sys/types.h>
Ben Noordhuisc5c28c32015-10-10 13:01:4982
83#include <string>
Brian White2d356072015-10-13 21:18:1584#include <vector>
Ben Noordhuis02cab972013-07-31 21:16:0885
Evan Lucas30b8bb02015-09-27 15:59:0286#if defined(NODE_HAVE_I18N_SUPPORT)
87#include <unicode/uvernum.h>
88#endif
89
Karl Skomski6ed06032015-08-14 08:07:1890#if defined(LEAK_SANITIZER)
91#include <sanitizer/lsan_interface.h>
92#endif
93
Ben Noordhuis02cab972013-07-31 21:16:0894#if defined(_MSC_VER)
Peter Bright13d6a1f2011-08-06 04:23:2595#include <direct.h>
Peter Brightb9d77772011-08-11 01:45:5696#include <io.h>
Ben Noordhuise6e78912015-12-04 23:31:4997#define getpid GetCurrentProcessId
Peter Brightb9d77772011-08-11 01:45:5698#define umask _umask
99typedef int mode_t;
Ben Noordhuis02cab972013-07-31 21:16:08100#else
Ben Noordhuis844f0a92016-03-25 16:59:07101#include <pthread.h>
Ben Noordhuis68200542013-10-02 10:17:57102#include <sys/resource.h> // getrlimit, setrlimit
Ben Noordhuis02cab972013-07-31 21:16:08103#include <unistd.h> // setuid, getuid
Peter Bright13d6a1f2011-08-06 04:23:25104#endif
Ryane02b71e2009-03-03 23:31:37105
Linus MÃ¥rtensson5e4e8ec2013-05-08 12:10:07106#if defined(__POSIX__) && !defined(__ANDROID__)
Ben Noordhuis02cab972013-07-31 21:16:08107#include <pwd.h> // getpwnam()
108#include <grp.h> // getgrnam()
Bert Beldera177d602010-11-25 00:02:55109#endif
110
Fedor Indutny8e29ce92013-07-31 18:07:29111#ifdef __APPLE__
Ben Noordhuis02cab972013-07-31 21:16:08112#include <crt_externs.h>
113#define environ (*_NSGetEnviron())
Fedor Indutny8e29ce92013-07-31 18:07:29114#elif !defined(_MSC_VER)
Ryan3e4fc9f2009-09-10 14:48:38115extern char **environ;
Fedor Indutny8e29ce92013-07-31 18:07:29116#endif
Ryan3e4fc9f2009-09-10 14:48:38117
Ryand6c9d312009-09-11 14:02:29118namespace node {
119
Ben Noordhuis110a9cd2013-07-03 02:23:44120using v8::Array;
Ben Noordhuis0693d222013-06-29 06:16:25121using v8::ArrayBuffer;
Ben Noordhuis110a9cd2013-07-03 02:23:44122using v8::Boolean;
123using v8::Context;
Fedor Indutnyce04c722014-03-13 16:38:14124using v8::EscapableHandleScope;
Ben Noordhuis110a9cd2013-07-03 02:23:44125using v8::Exception;
Patrick Mueller52cb4102016-04-05 13:17:48126using v8::Float64Array;
Ben Noordhuis110a9cd2013-07-03 02:23:44127using v8::Function;
128using v8::FunctionCallbackInfo;
Ben Noordhuis110a9cd2013-07-03 02:23:44129using v8::HandleScope;
130using v8::HeapStatistics;
131using v8::Integer;
132using v8::Isolate;
Ben Noordhuis511af4d2013-07-30 19:28:43133using v8::Local;
Ben Noordhuis110a9cd2013-07-03 02:23:44134using v8::Locker;
Michaël Zasso023c3172016-02-08 21:34:05135using v8::MaybeLocal;
Ben Noordhuis110a9cd2013-07-03 02:23:44136using v8::Message;
Ali Ijaz Sheikhc1649a72016-02-12 08:58:26137using v8::Name;
AnnaMagab194122016-10-06 20:50:41138using v8::NamedPropertyHandlerConfiguration;
Jeremiah Senkpiel21d66d62016-03-23 22:09:10139using v8::Null;
Ben Noordhuis110a9cd2013-07-03 02:23:44140using v8::Number;
141using v8::Object;
142using v8::ObjectTemplate;
Petka Antonov872702d2015-02-22 12:44:12143using v8::Promise;
144using v8::PromiseRejectMessage;
Ben Noordhuis110a9cd2013-07-03 02:23:44145using v8::PropertyCallbackInfo;
Michaël Zasso023c3172016-02-08 21:34:05146using v8::ScriptOrigin;
Fedor Indutnya07c6912015-04-11 14:02:33147using v8::SealHandleScope;
Ben Noordhuis511af4d2013-07-30 19:28:43148using v8::String;
Ben Noordhuis110a9cd2013-07-03 02:23:44149using v8::TryCatch;
Ben Noordhuis70d1f322015-06-19 11:23:56150using v8::Uint32Array;
Ben Noordhuis110a9cd2013-07-03 02:23:44151using v8::V8;
152using v8::Value;
Ben Noordhuis110a9cd2013-07-03 02:23:44153
Evan Lucas5b6f5752015-06-01 14:15:10154static bool print_eval = false;
155static bool force_repl = false;
Dave Eddy2e6ece42015-08-17 21:33:13156static bool syntax_check_only = false;
Evan Lucas5b6f5752015-06-01 14:15:10157static bool trace_deprecation = false;
158static bool throw_deprecation = false;
Evan Lucas5b6f5752015-06-01 14:15:10159static bool trace_sync_io = false;
Bradley Meckcf14a242015-07-09 16:15:26160static bool track_heap_objects = false;
Evan Lucas5b6f5752015-06-01 14:15:10161static const char* eval_string = nullptr;
Sam Robertscecdf7c2017-04-05 18:45:52162static std::vector<std::string> preload_modules;
Tom Gallacher03e07d32015-12-18 12:24:56163static const int v8_default_thread_pool_size = 4;
164static int v8_thread_pool_size = v8_default_thread_pool_size;
Matt Loring49440b72015-11-25 14:08:58165static bool prof_process = false;
Ben Noordhuis9566fe82013-10-03 08:45:32166static bool v8_is_profiling = false;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22167static bool node_is_initialized = false;
Keith M Wesolowski76b98462013-12-17 00:00:44168static node_module* modpending;
169static node_module* modlist_builtin;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:22170static node_module* modlist_linked;
Keith M Wesolowski76b98462013-12-17 00:00:44171static node_module* modlist_addon;
misterpoeba4847e2016-08-05 21:04:25172static bool trace_enabled = false;
Sam Roberts809ca2f2017-04-05 19:09:32173static std::string trace_enabled_categories; // NOLINT(runtime/string)
Ben Noordhuis74a82152012-02-03 15:32:00174
Evan Lucas5b6f5752015-06-01 14:15:10175#if defined(NODE_HAVE_I18N_SUPPORT)
176// Path to ICU data (for i18n / Intl)
Ben Noordhuis46345b92017-02-11 13:00:22177std::string icu_data_dir; // NOLINT(runtime/string)
Evan Lucas5b6f5752015-06-01 14:15:10178#endif
Steven R. Loomisac2857b2014-09-05 05:03:24179
Jason Ginchereau56e881d2017-03-20 21:55:26180// N-API is in experimental state, disabled by default.
181bool load_napi_modules = false;
182
isaacs48c3d202012-06-21 19:20:23183// used by C++ modules as well
184bool no_deprecation = false;
185
Fedor Indutnydb411cf2016-09-29 08:53:30186#if HAVE_OPENSSL
Adam Majer33012e92016-12-21 10:16:39187// use OpenSSL's cert store instead of bundled certs
188bool ssl_openssl_cert_store =
189#if defined(NODE_OPENSSL_CERT_STORE)
190 true;
191#else
192 false;
193#endif
194
Fedor Indutnydb411cf2016-09-29 08:53:30195# if NODE_FIPS_MODE
Stefan Budeanu7c48cb52016-01-22 23:10:09196// used by crypto module
197bool enable_fips_crypto = false;
198bool force_fips_crypto = false;
Fedor Indutnydb411cf2016-09-29 08:53:30199# endif // NODE_FIPS_MODE
Sam Roberts59afa272017-01-25 22:13:34200std::string openssl_config; // NOLINT(runtime/string)
Fedor Indutnydb411cf2016-09-29 08:53:30201#endif // HAVE_OPENSSL
Stefan Budeanu7c48cb52016-01-22 23:10:09202
James M Snellc6656db2016-01-20 19:38:35203// true if process warnings should be suppressed
204bool no_process_warnings = false;
205bool trace_warnings = false;
206
James M Snell5d38d542016-05-02 23:31:20207// Set in node.cc by ParseArgs when --preserve-symlinks is used.
208// Used in node_config.cc to set a constant on process.binding('config')
209// that is used by lib/module.js
210bool config_preserve_symlinks = false;
211
James M Snella16b5702017-03-11 20:18:53212// Set by ParseArgs when --pending-deprecation or NODE_PENDING_DEPRECATION
213// is used.
214bool config_pending_deprecation = false;
215
James M Snell03e89b32016-12-04 18:38:35216// Set in node.cc by ParseArgs when --redirect-warnings= is used.
Ben Noordhuisa8734af2017-01-28 12:27:02217std::string config_warning_file; // NOLINT(runtime/string)
James M Snell03e89b32016-12-04 18:38:35218
Sam Roberts8086cb62017-04-05 21:06:52219// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
220// used.
221// Used in node_config.cc to set a constant on process.binding('config')
222// that is used by lib/internal/bootstrap_node.js
223bool config_expose_internals = false;
224
Anna Henningsen72c60e82016-09-10 16:21:20225bool v8_initialized = false;
226
Ben Noordhuis74a82152012-02-03 15:32:00227// process-relative uptime base, initialized at start-up
228static double prog_start_time;
Ben Noordhuisca363cf2013-10-15 21:32:18229static bool debugger_running;
Ben Noordhuis5d0816b2013-01-06 22:06:48230static uv_async_t dispatch_debug_messages_async;
231
Ben Noordhuisd7087df2016-06-17 23:39:05232static Mutex node_isolate_mutex;
Ben Noordhuis844f0a92016-03-25 16:59:07233static v8::Isolate* node_isolate;
Stefan Budeanu410296c2016-03-27 00:17:55234
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22235static node::DebugOptions debug_options;
236
Stefan Budeanu410296c2016-03-27 00:17:55237static struct {
238#if NODE_USE_V8_PLATFORM
239 void Initialize(int thread_pool_size) {
240 platform_ = v8::platform::CreateDefaultPlatform(thread_pool_size);
241 V8::InitializePlatform(platform_);
misterpoeba4847e2016-08-05 21:04:25242 tracing::TraceEventHelper::SetCurrentPlatform(platform_);
Stefan Budeanu410296c2016-03-27 00:17:55243 }
244
245 void PumpMessageLoop(Isolate* isolate) {
246 v8::platform::PumpMessageLoop(platform_, isolate);
247 }
248
249 void Dispose() {
250 delete platform_;
251 platform_ = nullptr;
252 }
253
Ben Noordhuisc5c28c32015-10-10 13:01:49254#if HAVE_INSPECTOR
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22255 bool StartInspector(Environment *env, const char* script_path,
256 const node::DebugOptions& options) {
257 return env->inspector_agent()->Start(platform_, script_path, options);
Ben Noordhuisc5c28c32015-10-10 13:01:49258 }
Eugene Ostroukhovf9aadfb2016-11-18 21:52:22259#endif // HAVE_INSPECTOR
Stefan Budeanu410296c2016-03-27 00:17:55260
Myk Melez046f66a2017-01-31 17:56:09261 void StartTracingAgent() {
262 CHECK(tracing_agent_ == nullptr);
263 tracing_agent_ = new tracing::Agent();
264 tracing_agent_->Start(platform_, trace_enabled_categories);
265 }
266
267 void StopTracingAgent() {
268 tracing_agent_->Stop();
269 }
270
Stefan Budeanu410296c2016-03-27 00:17:55271 v8::Platform* platform_;
Myk Melez046f66a2017-01-31 17:56:09272 tracing::Agent* tracing_agent_;
Stefan Budeanu410296c2016-03-27 00:17:55273#else // !NODE_USE_V8_PLATFORM
274 void Initialize(int thread_pool_size) {}
275 void PumpMessageLoop(Isolate* isolate) {}
276 void Dispose() {}
Eugene Ostroukhov609a2652016-06-10 01:00:08277 bool StartInspector(Environment *env, const char* script_path,
Myk Melez046f66a2017-01-31 17:56:09278 const node::DebugOptions& options) {
Stefan Budeanu410296c2016-03-27 00:17:55279 env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
Eugene Ostroukhov7599b0e2016-12-13 01:08:31280 return true;
Stefan Budeanu410296c2016-03-27 00:17:55281 }
Myk Melez046f66a2017-01-31 17:56:09282
283 void StartTracingAgent() {
284 fprintf(stderr, "Node compiled with NODE_USE_V8_PLATFORM=0, "
285 "so event tracing is not available.\n");
286 }
287 void StopTracingAgent() {}
Stefan Budeanu410296c2016-03-27 00:17:55288#endif // !NODE_USE_V8_PLATFORM
289} v8_platform;
Ben Noordhuis5d0816b2013-01-06 22:06:48290
Ben Noordhuis844f0a92016-03-25 16:59:07291#ifdef __POSIX__
Eugene Ostroukhov66269192016-06-08 21:09:28292static const unsigned kMaxSignal = 32;
Ben Noordhuis844f0a92016-03-25 16:59:07293#endif
294
Brian White2d356072015-10-13 21:18:15295static void PrintErrorString(const char* format, ...) {
296 va_list ap;
297 va_start(ap, format);
298#ifdef _WIN32
299 HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
300
301 // Check if stderr is something other than a tty/console
302 if (stderr_handle == INVALID_HANDLE_VALUE ||
303 stderr_handle == nullptr ||
304 uv_guess_handle(_fileno(stderr)) != UV_TTY) {
305 vfprintf(stderr, format, ap);
Ömer Fadıl Usta44a298b2015-10-28 12:49:51306 va_end(ap);
Brian White2d356072015-10-13 21:18:15307 return;
308 }
309
310 // Fill in any placeholders
311 int n = _vscprintf(format, ap);
312 std::vector<char> out(n + 1);
313 vsprintf(out.data(), format, ap);
314
315 // Get required wide buffer size
316 n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
317
318 std::vector<wchar_t> wbuf(n);
319 MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
Nikolai Vavilov09f861f2016-07-16 17:06:47320
321 // Don't include the null character in the output
322 CHECK_GT(n, 0);
323 WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
Brian White2d356072015-10-13 21:18:15324#else
325 vfprintf(stderr, format, ap);
326#endif
327 va_end(ap);
328}
329
330
Saúl Ibarra Corretgé42b93432014-03-12 23:08:29331static void CheckImmediate(uv_check_t* handle) {
Ben Noordhuis756b6222013-08-10 22:26:11332 Environment* env = Environment::from_immediate_check_handle(handle);
Fedor Indutny75adde02014-02-21 13:02:42333 HandleScope scope(env->isolate());
Ben Noordhuis756b6222013-08-10 22:26:11334 Context::Scope context_scope(env->context());
335 MakeCallback(env, env->process_object(), env->immediate_callback_string());
Shigeki Ohtsucd372512013-02-06 02:13:02336}
337
338
Saúl Ibarra Corretgé42b93432014-03-12 23:08:29339static void IdleImmediateDummy(uv_idle_t* handle) {
Ben Noordhuis756b6222013-08-10 22:26:11340 // Do nothing. Only for maintaining event loop.
Ben Noordhuis2d82cdf2014-10-22 01:29:32341 // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
Shigeki Ohtsucd372512013-02-06 02:13:02342}
343
344
Ryan Dahlc9e27b12010-04-23 00:53:45345static inline const char *errno_string(int errorno) {
346#define ERRNO_CASE(e) case e: return #e;
347 switch (errorno) {
Ryan Dahlc9e27b12010-04-23 00:53:45348#ifdef EACCES
349 ERRNO_CASE(EACCES);
350#endif
351
352#ifdef EADDRINUSE
353 ERRNO_CASE(EADDRINUSE);
354#endif
355
356#ifdef EADDRNOTAVAIL
357 ERRNO_CASE(EADDRNOTAVAIL);
358#endif
359
360#ifdef EAFNOSUPPORT
361 ERRNO_CASE(EAFNOSUPPORT);
362#endif
363
364#ifdef EAGAIN
365 ERRNO_CASE(EAGAIN);
Ryan Dahl9b2aac62010-04-28 19:58:00366#endif
367
368#ifdef EWOULDBLOCK
369# if EAGAIN != EWOULDBLOCK
Ryan Dahlc9e27b12010-04-23 00:53:45370 ERRNO_CASE(EWOULDBLOCK);
371# endif
372#endif
373
374#ifdef EALREADY
375 ERRNO_CASE(EALREADY);
376#endif
377
378#ifdef EBADF
379 ERRNO_CASE(EBADF);
380#endif
381
382#ifdef EBADMSG
383 ERRNO_CASE(EBADMSG);
384#endif
385
386#ifdef EBUSY
387 ERRNO_CASE(EBUSY);
388#endif
389
390#ifdef ECANCELED
391 ERRNO_CASE(ECANCELED);
392#endif
393
394#ifdef ECHILD
395 ERRNO_CASE(ECHILD);
396#endif
397
398#ifdef ECONNABORTED
399 ERRNO_CASE(ECONNABORTED);
400#endif
401
402#ifdef ECONNREFUSED
403 ERRNO_CASE(ECONNREFUSED);
404#endif
405
406#ifdef ECONNRESET
407 ERRNO_CASE(ECONNRESET);
408#endif
409
410#ifdef EDEADLK
411 ERRNO_CASE(EDEADLK);
412#endif
413
414#ifdef EDESTADDRREQ
415 ERRNO_CASE(EDESTADDRREQ);
416#endif
417
418#ifdef EDOM
419 ERRNO_CASE(EDOM);
420#endif
421
422#ifdef EDQUOT
423 ERRNO_CASE(EDQUOT);
424#endif
425
426#ifdef EEXIST
427 ERRNO_CASE(EEXIST);
428#endif
429
430#ifdef EFAULT
431 ERRNO_CASE(EFAULT);
432#endif
433
434#ifdef EFBIG
435 ERRNO_CASE(EFBIG);
436#endif
437
438#ifdef EHOSTUNREACH
439 ERRNO_CASE(EHOSTUNREACH);
440#endif
441
442#ifdef EIDRM
443 ERRNO_CASE(EIDRM);
444#endif
445
446#ifdef EILSEQ
447 ERRNO_CASE(EILSEQ);
448#endif
449
450#ifdef EINPROGRESS
451 ERRNO_CASE(EINPROGRESS);
452#endif
453
454#ifdef EINTR
455 ERRNO_CASE(EINTR);
456#endif
457
458#ifdef EINVAL
459 ERRNO_CASE(EINVAL);
460#endif
461
462#ifdef EIO
463 ERRNO_CASE(EIO);
464#endif
465
466#ifdef EISCONN
467 ERRNO_CASE(EISCONN);
468#endif
469
470#ifdef EISDIR
471 ERRNO_CASE(EISDIR);
472#endif
473
474#ifdef ELOOP
475 ERRNO_CASE(ELOOP);
476#endif
477
478#ifdef EMFILE
479 ERRNO_CASE(EMFILE);
480#endif
481
482#ifdef EMLINK
483 ERRNO_CASE(EMLINK);
484#endif
485
486#ifdef EMSGSIZE
487 ERRNO_CASE(EMSGSIZE);
488#endif
489
490#ifdef EMULTIHOP
491 ERRNO_CASE(EMULTIHOP);
492#endif
493
494#ifdef ENAMETOOLONG
495 ERRNO_CASE(ENAMETOOLONG);
496#endif
497
498#ifdef ENETDOWN
499 ERRNO_CASE(ENETDOWN);
500#endif
501
502#ifdef ENETRESET
503 ERRNO_CASE(ENETRESET);
504#endif
505
506#ifdef ENETUNREACH
507 ERRNO_CASE(ENETUNREACH);
508#endif
509
510#ifdef ENFILE
511 ERRNO_CASE(ENFILE);
512#endif
513
514#ifdef ENOBUFS
515 ERRNO_CASE(ENOBUFS);
516#endif
517
518#ifdef ENODATA
519 ERRNO_CASE(ENODATA);
520#endif
521
522#ifdef ENODEV
523 ERRNO_CASE(ENODEV);
524#endif
525
526#ifdef ENOENT
527 ERRNO_CASE(ENOENT);
528#endif
529
530#ifdef ENOEXEC
531 ERRNO_CASE(ENOEXEC);
532#endif
533
Ryan Dahlc9e27b12010-04-23 00:53:45534#ifdef ENOLINK
535 ERRNO_CASE(ENOLINK);
536#endif
537
Ryan Dahl3bb21b52010-04-28 22:07:15538#ifdef ENOLCK
539# if ENOLINK != ENOLCK
540 ERRNO_CASE(ENOLCK);
541# endif
542#endif
543
Ryan Dahlc9e27b12010-04-23 00:53:45544#ifdef ENOMEM
545 ERRNO_CASE(ENOMEM);
546#endif
547
548#ifdef ENOMSG
549 ERRNO_CASE(ENOMSG);
550#endif
551
552#ifdef ENOPROTOOPT
553 ERRNO_CASE(ENOPROTOOPT);
554#endif
555
556#ifdef ENOSPC
557 ERRNO_CASE(ENOSPC);
558#endif
559
560#ifdef ENOSR
561 ERRNO_CASE(ENOSR);
562#endif
563
564#ifdef ENOSTR
565 ERRNO_CASE(ENOSTR);
566#endif
567
568#ifdef ENOSYS
569 ERRNO_CASE(ENOSYS);
570#endif
571
572#ifdef ENOTCONN
573 ERRNO_CASE(ENOTCONN);
574#endif
575
576#ifdef ENOTDIR
577 ERRNO_CASE(ENOTDIR);
578#endif
579
580#ifdef ENOTEMPTY
Michael Dawson2a17c7f2015-08-12 15:53:33581# if ENOTEMPTY != EEXIST
Ryan Dahlc9e27b12010-04-23 00:53:45582 ERRNO_CASE(ENOTEMPTY);
Michael Dawson2a17c7f2015-08-12 15:53:33583# endif
Ryan Dahlc9e27b12010-04-23 00:53:45584#endif
585
586#ifdef ENOTSOCK
587 ERRNO_CASE(ENOTSOCK);
588#endif
589
590#ifdef ENOTSUP
591 ERRNO_CASE(ENOTSUP);
592#else
593# ifdef EOPNOTSUPP
594 ERRNO_CASE(EOPNOTSUPP);
595# endif
596#endif
597
598#ifdef ENOTTY
599 ERRNO_CASE(ENOTTY);
600#endif
601
602#ifdef ENXIO
603 ERRNO_CASE(ENXIO);
604#endif
605
606
607#ifdef EOVERFLOW
608 ERRNO_CASE(EOVERFLOW);
609#endif
610
611#ifdef EPERM
612 ERRNO_CASE(EPERM);
613#endif
614
615#ifdef EPIPE
616 ERRNO_CASE(EPIPE);
617#endif
618
619#ifdef EPROTO
620 ERRNO_CASE(EPROTO);
621#endif
622
623#ifdef EPROTONOSUPPORT
624 ERRNO_CASE(EPROTONOSUPPORT);
625#endif
626
627#ifdef EPROTOTYPE
628 ERRNO_CASE(EPROTOTYPE);
629#endif
630
631#ifdef ERANGE
632 ERRNO_CASE(ERANGE);
633#endif
634
635#ifdef EROFS
636 ERRNO_CASE(EROFS);
637#endif
638
639#ifdef ESPIPE
640 ERRNO_CASE(ESPIPE);
641#endif
642
643#ifdef ESRCH
644 ERRNO_CASE(ESRCH);
645#endif
646
647#ifdef ESTALE
648 ERRNO_CASE(ESTALE);
649#endif
650
651#ifdef ETIME
652 ERRNO_CASE(ETIME);
653#endif
654
655#ifdef ETIMEDOUT
656 ERRNO_CASE(ETIMEDOUT);
657#endif
658
659#ifdef ETXTBSY
660 ERRNO_CASE(ETXTBSY);
661#endif
662
663#ifdef EXDEV
664 ERRNO_CASE(EXDEV);
665#endif
666
667 default: return "";
668 }
669}
670
Felix Geisendörferf8a3cf92010-04-28 13:04:08671const char *signo_string(int signo) {
672#define SIGNO_CASE(e) case e: return #e;
673 switch (signo) {
Felix Geisendörferf8a3cf92010-04-28 13:04:08674#ifdef SIGHUP
675 SIGNO_CASE(SIGHUP);
676#endif
677
678#ifdef SIGINT
679 SIGNO_CASE(SIGINT);
680#endif
681
682#ifdef SIGQUIT
683 SIGNO_CASE(SIGQUIT);
684#endif
685
686#ifdef SIGILL
687 SIGNO_CASE(SIGILL);
688#endif
689
690#ifdef SIGTRAP
691 SIGNO_CASE(SIGTRAP);
692#endif
693
694#ifdef SIGABRT
695 SIGNO_CASE(SIGABRT);
696#endif
697
698#ifdef SIGIOT
699# if SIGABRT != SIGIOT
700 SIGNO_CASE(SIGIOT);
701# endif
702#endif
703
704#ifdef SIGBUS
705 SIGNO_CASE(SIGBUS);
706#endif
707
708#ifdef SIGFPE
709 SIGNO_CASE(SIGFPE);
710#endif
711
712#ifdef SIGKILL
713 SIGNO_CASE(SIGKILL);
714#endif
715
716#ifdef SIGUSR1
717 SIGNO_CASE(SIGUSR1);
718#endif
719
720#ifdef SIGSEGV
721 SIGNO_CASE(SIGSEGV);
722#endif
723
724#ifdef SIGUSR2
725 SIGNO_CASE(SIGUSR2);
726#endif
727
728#ifdef SIGPIPE
729 SIGNO_CASE(SIGPIPE);
730#endif
731
732#ifdef SIGALRM
733 SIGNO_CASE(SIGALRM);
734#endif
735
736 SIGNO_CASE(SIGTERM);
Bert Belderdcc35082010-11-25 00:04:31737
738#ifdef SIGCHLD
Felix Geisendörferf8a3cf92010-04-28 13:04:08739 SIGNO_CASE(SIGCHLD);
Bert Belderdcc35082010-11-25 00:04:31740#endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08741
742#ifdef SIGSTKFLT
743 SIGNO_CASE(SIGSTKFLT);
744#endif
745
746
747#ifdef SIGCONT
748 SIGNO_CASE(SIGCONT);
749#endif
750
751#ifdef SIGSTOP
752 SIGNO_CASE(SIGSTOP);
753#endif
754
755#ifdef SIGTSTP
756 SIGNO_CASE(SIGTSTP);
757#endif
758
Bert Belder600a6462012-08-20 21:59:21759#ifdef SIGBREAK
760 SIGNO_CASE(SIGBREAK);
761#endif
762
Felix Geisendörferf8a3cf92010-04-28 13:04:08763#ifdef SIGTTIN
764 SIGNO_CASE(SIGTTIN);
765#endif
766
767#ifdef SIGTTOU
768 SIGNO_CASE(SIGTTOU);
769#endif
770
771#ifdef SIGURG
772 SIGNO_CASE(SIGURG);
773#endif
774
775#ifdef SIGXCPU
776 SIGNO_CASE(SIGXCPU);
777#endif
778
779#ifdef SIGXFSZ
780 SIGNO_CASE(SIGXFSZ);
781#endif
782
783#ifdef SIGVTALRM
784 SIGNO_CASE(SIGVTALRM);
785#endif
786
787#ifdef SIGPROF
788 SIGNO_CASE(SIGPROF);
789#endif
790
791#ifdef SIGWINCH
792 SIGNO_CASE(SIGWINCH);
793#endif
794
795#ifdef SIGIO
796 SIGNO_CASE(SIGIO);
797#endif
798
799#ifdef SIGPOLL
Ryan Dahl3bb21b52010-04-28 22:07:15800# if SIGPOLL != SIGIO
Felix Geisendörferf8a3cf92010-04-28 13:04:08801 SIGNO_CASE(SIGPOLL);
Ryan Dahl3bb21b52010-04-28 22:07:15802# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08803#endif
804
805#ifdef SIGLOST
Michael Dawson2a17c7f2015-08-12 15:53:33806# if SIGLOST != SIGABRT
Felix Geisendörferf8a3cf92010-04-28 13:04:08807 SIGNO_CASE(SIGLOST);
Michael Dawson2a17c7f2015-08-12 15:53:33808# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08809#endif
810
811#ifdef SIGPWR
Raffaele Senab3b81d62010-06-09 04:08:05812# if SIGPWR != SIGLOST
Felix Geisendörferf8a3cf92010-04-28 13:04:08813 SIGNO_CASE(SIGPWR);
Raffaele Senab3b81d62010-06-09 04:08:05814# endif
Felix Geisendörferf8a3cf92010-04-28 13:04:08815#endif
816
James Reggiofb5f66a2016-04-07 01:00:04817#ifdef SIGINFO
818# if !defined(SIGPWR) || SIGINFO != SIGPWR
819 SIGNO_CASE(SIGINFO);
820# endif
821#endif
822
Felix Geisendörferf8a3cf92010-04-28 13:04:08823#ifdef SIGSYS
824 SIGNO_CASE(SIGSYS);
825#endif
826
Felix Geisendörferf8a3cf92010-04-28 13:04:08827 default: return "";
828 }
829}
830
Ryan Dahlc9e27b12010-04-23 00:53:45831
Fedor Indutny75adde02014-02-21 13:02:42832Local<Value> ErrnoException(Isolate* isolate,
833 int errorno,
Ryan Dahlc9e27b12010-04-23 00:53:45834 const char *syscall,
visionmedia45948e02010-05-14 14:52:49835 const char *msg,
836 const char *path) {
Fedor Indutny75adde02014-02-21 13:02:42837 Environment* env = Environment::GetCurrent(isolate);
Ben Noordhuis756b6222013-08-10 22:26:11838
visionmedia45948e02010-05-14 14:52:49839 Local<Value> e;
Fedor Indutny75adde02014-02-21 13:02:42840 Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
Ben Noordhuis2d82cdf2014-10-22 01:29:32841 if (msg == nullptr || msg[0] == '\0') {
Bert Belder2ce09612011-01-17 21:47:59842 msg = strerror(errorno);
Bert Belder2ce09612011-01-17 21:47:59843 }
Fedor Indutny75adde02014-02-21 13:02:42844 Local<String> message = OneByteString(env->isolate(), msg);
Ryan Dahlc9e27b12010-04-23 00:53:45845
Ben Noordhuis4f394992015-03-13 18:15:18846 Local<String> cons =
Fedor Indutny75adde02014-02-21 13:02:42847 String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
Ben Noordhuis4f394992015-03-13 18:15:18848 cons = String::Concat(cons, message);
Ryan Dahlc9e27b12010-04-23 00:53:45849
Ben Noordhuis4f394992015-03-13 18:15:18850 Local<String> path_string;
851 if (path != nullptr) {
852 // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
853 path_string = String::NewFromUtf8(env->isolate(), path);
visionmedia45948e02010-05-14 14:52:49854 }
855
Ben Noordhuis4f394992015-03-13 18:15:18856 if (path_string.IsEmpty() == false) {
857 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
858 cons = String::Concat(cons, path_string);
859 cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
860 }
861 e = Exception::Error(cons);
862
Trevor Norrisd5533862015-01-07 21:29:58863 Local<Object> obj = e->ToObject(env->isolate());
Fedor Indutnyce04c722014-03-13 16:38:14864 obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
Ben Noordhuis756b6222013-08-10 22:26:11865 obj->Set(env->code_string(), estring);
visionmedia45948e02010-05-14 14:52:49866
Ben Noordhuis4f394992015-03-13 18:15:18867 if (path_string.IsEmpty() == false) {
868 obj->Set(env->path_string(), path_string);
Ben Noordhuis756b6222013-08-10 22:26:11869 }
870
Ben Noordhuis2d82cdf2014-10-22 01:29:32871 if (syscall != nullptr) {
Fedor Indutny75adde02014-02-21 13:02:42872 obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
Ben Noordhuis756b6222013-08-10 22:26:11873 }
874
Ryan Dahlc9e27b12010-04-23 00:53:45875 return e;
876}
877
878
Bert Belderbc2c85c2015-01-31 10:48:34879static Local<String> StringFromPath(Isolate* isolate, const char* path) {
880#ifdef _WIN32
881 if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
882 return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
883 String::NewFromUtf8(isolate, path + 8));
884 } else if (strncmp(path, "\\\\?\\", 4) == 0) {
885 return String::NewFromUtf8(isolate, path + 4);
886 }
887#endif
888
889 return String::NewFromUtf8(isolate, path);
890}
891
892
Fedor Indutny75adde02014-02-21 13:02:42893Local<Value> UVException(Isolate* isolate,
894 int errorno,
Bert Belderbc2c85c2015-01-31 10:48:34895 const char* syscall,
896 const char* msg,
897 const char* path) {
898 return UVException(isolate, errorno, syscall, msg, path, nullptr);
899}
900
901
902Local<Value> UVException(Isolate* isolate,
903 int errorno,
904 const char* syscall,
905 const char* msg,
906 const char* path,
907 const char* dest) {
Fedor Indutny75adde02014-02-21 13:02:42908 Environment* env = Environment::GetCurrent(isolate);
Bert Belder823a4432011-12-01 23:02:51909
910 if (!msg || !msg[0])
Ben Noordhuisca9eb712013-07-18 21:18:50911 msg = uv_strerror(errorno);
Bert Belder823a4432011-12-01 23:02:51912
Bert Belderbc2c85c2015-01-31 10:48:34913 Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
914 Local<String> js_syscall = OneByteString(isolate, syscall);
915 Local<String> js_path;
916 Local<String> js_dest;
Bert Belder823a4432011-12-01 23:02:51917
Bert Belderbc2c85c2015-01-31 10:48:34918 Local<String> js_msg = js_code;
919 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
920 js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
921 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
922 js_msg = String::Concat(js_msg, js_syscall);
Ben Noordhuis756b6222013-08-10 22:26:11923
Ben Noordhuis2d82cdf2014-10-22 01:29:32924 if (path != nullptr) {
Bert Belderbc2c85c2015-01-31 10:48:34925 js_path = StringFromPath(isolate, path);
926
927 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
928 js_msg = String::Concat(js_msg, js_path);
929 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
Ben Noordhuis756b6222013-08-10 22:26:11930 }
931
Bert Belderbc2c85c2015-01-31 10:48:34932 if (dest != nullptr) {
933 js_dest = StringFromPath(isolate, dest);
934
935 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
936 js_msg = String::Concat(js_msg, js_dest);
937 js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
Ben Noordhuis756b6222013-08-10 22:26:11938 }
939
Bert Belderbc2c85c2015-01-31 10:48:34940 Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
941
942 // TODO(piscisaureus) errno should probably go; the user has no way of
943 // knowing which uv errno value maps to which error.
944 e->Set(env->errno_string(), Integer::New(isolate, errorno));
945 e->Set(env->code_string(), js_code);
946 e->Set(env->syscall_string(), js_syscall);
947 if (!js_path.IsEmpty())
948 e->Set(env->path_string(), js_path);
949 if (!js_dest.IsEmpty())
950 e->Set(env->dest_string(), js_dest);
951
Bert Belder823a4432011-12-01 23:02:51952 return e;
953}
954
955
Ben Noordhuis8f6c5872014-10-11 19:48:25956// Look up environment variable unless running as setuid root.
Sam Roberts901e9262017-01-27 19:49:14957bool SafeGetenv(const char* key, std::string* text) {
Ben Noordhuis8f6c5872014-10-11 19:48:25958#ifndef _WIN32
Ben Noordhuisa8734af2017-01-28 12:27:02959 // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE)
960 // is non-zero on Linux.
961 if (getuid() != geteuid() || getgid() != getegid()) {
962 text->clear();
963 return false;
964 }
Ben Noordhuis8f6c5872014-10-11 19:48:25965#endif
Ben Noordhuisa8734af2017-01-28 12:27:02966 if (const char* value = getenv(key)) {
967 *text = value;
968 return true;
969 }
970 text->clear();
971 return false;
Ben Noordhuis8f6c5872014-10-11 19:48:25972}
973
974
Bert Belder6ee73a22011-11-04 15:10:48975#ifdef _WIN32
Igor Zinkovsky500c8f42011-12-15 20:36:05976// Does about the same as strerror(),
977// but supports all windows error messages
Alexis Campailla93f3b642014-08-05 13:33:16978static const char *winapi_strerror(const int errorno, bool* must_free) {
Ben Noordhuis2d82cdf2014-10-22 01:29:32979 char *errmsg = nullptr;
Igor Zinkovsky500c8f42011-12-15 20:36:05980
981 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
Ben Noordhuis2d82cdf2014-10-22 01:29:32982 FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
983 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
Igor Zinkovsky500c8f42011-12-15 20:36:05984
985 if (errmsg) {
Alexis Campailla93f3b642014-08-05 13:33:16986 *must_free = true;
987
Igor Zinkovsky500c8f42011-12-15 20:36:05988 // Remove trailing newlines
989 for (int i = strlen(errmsg) - 1;
990 i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
991 errmsg[i] = '\0';
992 }
993
994 return errmsg;
995 } else {
996 // FormatMessage failed
Alexis Campailla93f3b642014-08-05 13:33:16997 *must_free = false;
Igor Zinkovsky500c8f42011-12-15 20:36:05998 return "Unknown error";
999 }
1000}
1001
1002
Alexis Campailla440b9e22014-02-24 18:55:271003Local<Value> WinapiErrnoException(Isolate* isolate,
Fedor Indutny75adde02014-02-21 13:02:421004 int errorno,
Bert Belder829735e2011-11-04 15:23:021005 const char* syscall,
1006 const char* msg,
1007 const char* path) {
Alexis Campailla440b9e22014-02-24 18:55:271008 Environment* env = Environment::GetCurrent(isolate);
Bert Belder6ee73a22011-11-04 15:10:481009 Local<Value> e;
Alexis Campailla93f3b642014-08-05 13:33:161010 bool must_free = false;
Bert Belder829735e2011-11-04 15:23:021011 if (!msg || !msg[0]) {
Alexis Campailla93f3b642014-08-05 13:33:161012 msg = winapi_strerror(errorno, &must_free);
Bert Belder6ee73a22011-11-04 15:10:481013 }
Fedor Indutny75adde02014-02-21 13:02:421014 Local<String> message = OneByteString(env->isolate(), msg);
Bert Belder6ee73a22011-11-04 15:10:481015
Bert Belder6ee73a22011-11-04 15:10:481016 if (path) {
Ben Noordhuisf674b092013-08-07 19:50:411017 Local<String> cons1 =
Alexis Campailla440b9e22014-02-24 18:55:271018 String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
Ben Noordhuisf674b092013-08-07 19:50:411019 Local<String> cons2 =
Alexis Campailla440b9e22014-02-24 18:55:271020 String::Concat(cons1, String::NewFromUtf8(isolate, path));
Ben Noordhuisf674b092013-08-07 19:50:411021 Local<String> cons3 =
Alexis Campailla440b9e22014-02-24 18:55:271022 String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
Bert Belder6ee73a22011-11-04 15:10:481023 e = Exception::Error(cons3);
1024 } else {
1025 e = Exception::Error(message);
1026 }
1027
Trevor Norrisd5533862015-01-07 21:29:581028 Local<Object> obj = e->ToObject(env->isolate());
Fedor Indutnyce04c722014-03-13 16:38:141029 obj->Set(env->errno_string(), Integer::New(isolate, errorno));
Bert Belder6ee73a22011-11-04 15:10:481030
Ben Noordhuis2d82cdf2014-10-22 01:29:321031 if (path != nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:271032 obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
Ben Noordhuis756b6222013-08-10 22:26:111033 }
1034
Ben Noordhuis2d82cdf2014-10-22 01:29:321035 if (syscall != nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:271036 obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
Ben Noordhuis756b6222013-08-10 22:26:111037 }
1038
Alexis Campailla93f3b642014-08-05 13:33:161039 if (must_free)
1040 LocalFree((HLOCAL)msg);
1041
Bert Belder6ee73a22011-11-04 15:10:481042 return e;
1043}
1044#endif
1045
1046
Trevor Norris74178a52015-09-14 22:31:101047void* ArrayBufferAllocator::Allocate(size_t size) {
Ben Noordhuis27e84dd2016-05-31 18:58:311048 if (zero_fill_field_ || zero_fill_all_buffers)
Anna Henningsenea940862016-09-10 16:19:241049 return node::UncheckedCalloc(size);
Ben Noordhuis3a399632016-06-01 13:53:011050 else
Anna Henningsenea940862016-09-10 16:19:241051 return node::UncheckedMalloc(size);
Trevor Norris74178a52015-09-14 22:31:101052}
1053
Anna Henningsen9d522222017-04-12 17:17:241054namespace {
1055
1056bool DomainHasErrorHandler(const Environment* env,
1057 const Local<Object>& domain) {
Julien Gilli425a3542015-11-03 01:56:241058 HandleScope scope(env->isolate());
Trevor Norris74178a52015-09-14 22:31:101059
Julien Gilli425a3542015-11-03 01:56:241060 Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
1061 if (!domain_event_listeners_v->IsObject())
1062 return false;
1063
1064 Local<Object> domain_event_listeners_o =
1065 domain_event_listeners_v.As<Object>();
1066
1067 Local<Value> domain_error_listeners_v =
1068 domain_event_listeners_o->Get(env->error_string());
1069
1070 if (domain_error_listeners_v->IsFunction() ||
1071 (domain_error_listeners_v->IsArray() &&
1072 domain_error_listeners_v.As<Array>()->Length() > 0))
1073 return true;
1074
1075 return false;
1076}
1077
Anna Henningsen9d522222017-04-12 17:17:241078bool DomainsStackHasErrorHandler(const Environment* env) {
Julien Gilli425a3542015-11-03 01:56:241079 HandleScope scope(env->isolate());
1080
Jeremy Whitlock77a10ed2015-10-05 20:08:531081 if (!env->using_domains())
1082 return false;
1083
Julien Gilli425a3542015-11-03 01:56:241084 Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
1085 if (domains_stack_array->Length() == 0)
Jeremy Whitlock77a10ed2015-10-05 20:08:531086 return false;
1087
Julien Gilli425a3542015-11-03 01:56:241088 uint32_t domains_stack_length = domains_stack_array->Length();
1089 for (uint32_t i = domains_stack_length; i > 0; --i) {
1090 Local<Value> domain_v = domains_stack_array->Get(i - 1);
1091 if (!domain_v->IsObject())
1092 return false;
1093
1094 Local<Object> domain = domain_v.As<Object>();
1095 if (DomainHasErrorHandler(env, domain))
1096 return true;
1097 }
1098
1099 return false;
Jeremy Whitlock77a10ed2015-10-05 20:08:531100}
1101
1102
Anna Henningsen9d522222017-04-12 17:17:241103bool ShouldAbortOnUncaughtException(Isolate* isolate) {
Jeremy Whitlock77a10ed2015-10-05 20:08:531104 HandleScope scope(isolate);
1105
1106 Environment* env = Environment::GetCurrent(isolate);
1107 Local<Object> process_object = env->process_object();
1108 Local<String> emitting_top_level_domain_error_key =
1109 env->emitting_top_level_domain_error_string();
1110 bool isEmittingTopLevelDomainError =
1111 process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1112
Julien Gilli425a3542015-11-03 01:56:241113 return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env);
Jeremy Whitlock77a10ed2015-10-05 20:08:531114}
1115
1116
Trevor Norris828f1452014-01-09 19:11:401117void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551118 Environment* env = Environment::GetCurrent(args);
Trevor Norris828f1452014-01-09 19:11:401119
1120 if (env->using_domains())
1121 return;
1122 env->set_using_domains(true);
1123
Fedor Indutny75adde02014-02-21 13:02:421124 HandleScope scope(env->isolate());
Trevor Norris828f1452014-01-09 19:11:401125 Local<Object> process_object = env->process_object();
1126
Fedor Indutny75adde02014-02-21 13:02:421127 Local<String> tick_callback_function_key = env->tick_domain_cb_string();
Trevor Norris828f1452014-01-09 19:11:401128 Local<Function> tick_callback_function =
1129 process_object->Get(tick_callback_function_key).As<Function>();
1130
1131 if (!tick_callback_function->IsFunction()) {
1132 fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
Evan Lucas870229e2015-09-16 15:12:411133 ABORT();
Trevor Norris828f1452014-01-09 19:11:401134 }
1135
Fedor Indutny75adde02014-02-21 13:02:421136 process_object->Set(env->tick_callback_string(), tick_callback_function);
Trevor Norris828f1452014-01-09 19:11:401137 env->set_tick_callback_function(tick_callback_function);
1138
Ben Noordhuis5fdff382014-10-11 14:52:071139 CHECK(args[0]->IsArray());
Trevor Norris828f1452014-01-09 19:11:401140 env->set_domain_array(args[0].As<Array>());
1141
Julien Gilli425a3542015-11-03 01:56:241142 CHECK(args[1]->IsArray());
1143 env->set_domains_stack_array(args[1].As<Array>());
1144
Trevor Norris828f1452014-01-09 19:11:401145 // Do a little housekeeping.
1146 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:041147 env->context(),
1148 FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust();
Ben Noordhuis70d1f322015-06-19 11:23:561149
1150 uint32_t* const fields = env->domain_flag()->fields();
1151 uint32_t const fields_count = env->domain_flag()->fields_count();
1152
1153 Local<ArrayBuffer> array_buffer =
1154 ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1155
1156 args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
Trevor Norris828f1452014-01-09 19:11:401157}
1158
Vladimir Kurchatkin30bd7b62014-09-04 16:02:041159void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
1160 args.GetIsolate()->RunMicrotasks();
1161}
1162
Trevor Norris828f1452014-01-09 19:11:401163
Trevor Norris494227b2015-10-14 20:58:521164void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
1165 Environment* env = Environment::GetCurrent(args);
1166
1167 CHECK(args[0]->IsFunction());
1168
Trevor Norris83524b32015-11-10 09:58:511169 env->set_push_values_to_array_function(args[0].As<Function>());
Trevor Norris494227b2015-10-14 20:58:521170 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:041171 env->context(),
1172 FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust();
Trevor Norris494227b2015-10-14 20:58:521173}
1174
1175
Trevor Norrisefa62fd2013-09-24 21:12:111176void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551177 Environment* env = Environment::GetCurrent(args);
Trevor Norrisefa62fd2013-09-24 21:12:111178
Ben Noordhuis70d1f322015-06-19 11:23:561179 CHECK(args[0]->IsFunction());
1180 CHECK(args[1]->IsObject());
Trevor Norrisefa62fd2013-09-24 21:12:111181
Ben Noordhuis70d1f322015-06-19 11:23:561182 env->set_tick_callback_function(args[0].As<Function>());
Trevor Norrisefa62fd2013-09-24 21:12:111183
Ben Noordhuis70d1f322015-06-19 11:23:561184 env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks);
Vladimir Kurchatkin30bd7b62014-09-04 16:02:041185
Trevor Norrisefa62fd2013-09-24 21:12:111186 // Do a little housekeeping.
1187 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:041188 env->context(),
1189 FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick")).FromJust();
Ben Noordhuis70d1f322015-06-19 11:23:561190
1191 // Values use to cross communicate with processNextTick.
1192 uint32_t* const fields = env->tick_info()->fields();
1193 uint32_t const fields_count = env->tick_info()->fields_count();
1194
1195 Local<ArrayBuffer> array_buffer =
1196 ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1197
1198 args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
Trevor Norris3f5d5842013-08-07 00:01:441199}
1200
Petka Antonov872702d2015-02-22 12:44:121201void PromiseRejectCallback(PromiseRejectMessage message) {
1202 Local<Promise> promise = message.GetPromise();
1203 Isolate* isolate = promise->GetIsolate();
1204 Local<Value> value = message.GetValue();
1205 Local<Integer> event = Integer::New(isolate, message.GetEvent());
1206
1207 Environment* env = Environment::GetCurrent(isolate);
1208 Local<Function> callback = env->promise_reject_function();
1209
1210 if (value.IsEmpty())
1211 value = Undefined(isolate);
1212
1213 Local<Value> args[] = { event, promise, value };
1214 Local<Object> process = env->process_object();
1215
Ben Noordhuisa7581d02016-03-31 10:47:061216 callback->Call(process, arraysize(args), args);
Petka Antonov872702d2015-02-22 12:44:121217}
1218
1219void SetupPromises(const FunctionCallbackInfo<Value>& args) {
1220 Environment* env = Environment::GetCurrent(args);
1221 Isolate* isolate = env->isolate();
1222
1223 CHECK(args[0]->IsFunction());
1224
1225 isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1226 env->set_promise_reject_function(args[0].As<Function>());
1227
1228 env->process_object()->Delete(
Michaël Zassod45045f2016-02-08 21:42:041229 env->context(),
1230 FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises")).FromJust();
Petka Antonov872702d2015-02-22 12:44:121231}
1232
Anna Henningsen9d522222017-04-12 17:17:241233} // anonymous namespace
1234
Trevor Norris3f5d5842013-08-07 00:01:441235
Michaël Zasso4abc8962015-07-18 09:34:161236Local<Value> MakeCallback(Environment* env,
Trevor Norrisf86a3a22016-02-11 20:10:471237 Local<Value> recv,
1238 const Local<Function> callback,
1239 int argc,
1240 Local<Value> argv[]) {
Trevor Norrisefa62fd2013-09-24 21:12:111241 // If you hit this assertion, you forgot to enter the v8::Context first.
Ben Noordhuis5fdff382014-10-11 14:52:071242 CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
Trevor Norrisefa62fd2013-09-24 21:12:111243
Trevor Norrisaeee9562015-10-02 00:57:361244 Local<Function> pre_fn = env->async_hooks_pre_function();
1245 Local<Function> post_fn = env->async_hooks_post_function();
Trevor Norrisa1da0242014-12-09 04:24:591246 Local<Object> object, domain;
Trevor Norrisaeee9562015-10-02 00:57:361247 bool ran_init_callback = false;
Trevor Norrisa1da0242014-12-09 04:24:591248 bool has_domain = false;
1249
Trevor Norrise9192242016-01-05 22:33:211250 Environment::AsyncCallbackScope callback_scope(env);
1251
Trevor Norrisaeee9562015-10-02 00:57:361252 // TODO(trevnorris): Adding "_asyncQueue" to the "this" in the init callback
1253 // is a horrible way to detect usage. Rethink how detection should happen.
Trevor Norrisb9e60322014-12-09 04:10:441254 if (recv->IsObject()) {
1255 object = recv.As<Object>();
1256 Local<Value> async_queue_v = object->Get(env->async_queue_string());
1257 if (async_queue_v->IsObject())
Trevor Norrisaeee9562015-10-02 00:57:361258 ran_init_callback = true;
Trevor Norrisb9e60322014-12-09 04:10:441259 }
1260
Trevor Norrisa1da0242014-12-09 04:24:591261 if (env->using_domains()) {
1262 CHECK(recv->IsObject());
Trevor Norrisa1da0242014-12-09 04:24:591263 Local<Value> domain_v = object->Get(env->domain_string());
1264 has_domain = domain_v->IsObject();
1265 if (has_domain) {
1266 domain = domain_v.As<Object>();
1267 if (domain->Get(env->disposed_string())->IsTrue())
1268 return Undefined(env->isolate());
1269 }
1270 }
Trevor Norrisefa62fd2013-09-24 21:12:111271
Trevor Norrisa1da0242014-12-09 04:24:591272 if (has_domain) {
1273 Local<Value> enter_v = domain->Get(env->enter_string());
1274 if (enter_v->IsFunction()) {
Trevor Norris95afe282016-02-11 20:57:261275 if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1276 FatalError("node::MakeCallback",
1277 "domain enter callback threw, please report this");
1278 }
Trevor Norrisa1da0242014-12-09 04:24:591279 }
1280 }
1281
Trevor Norrisaeee9562015-10-02 00:57:361282 if (ran_init_callback && !pre_fn.IsEmpty()) {
Trevor Norrisa17200b2016-03-14 18:35:221283 TryCatch try_catch(env->isolate());
1284 MaybeLocal<Value> ar = pre_fn->Call(env->context(), object, 0, nullptr);
1285 if (ar.IsEmpty()) {
1286 ClearFatalExceptionHandlers(env);
1287 FatalException(env->isolate(), try_catch);
1288 return Local<Value>();
1289 }
Trevor Norrisb9e60322014-12-09 04:10:441290 }
1291
Ben Noordhuis1f2f3fa2014-01-27 02:58:161292 Local<Value> ret = callback->Call(recv, argc, argv);
isaacs10ce3d12012-04-13 23:27:231293
Trevor Norrisaeee9562015-10-02 00:57:361294 if (ran_init_callback && !post_fn.IsEmpty()) {
Trevor Norris20337ad2016-02-23 05:50:561295 Local<Value> did_throw = Boolean::New(env->isolate(), ret.IsEmpty());
1296 // Currently there's no way to retrieve an uid from node::MakeCallback().
1297 // This needs to be fixed.
1298 Local<Value> vals[] =
1299 { Undefined(env->isolate()).As<Value>(), did_throw };
Trevor Norrisa17200b2016-03-14 18:35:221300 TryCatch try_catch(env->isolate());
1301 MaybeLocal<Value> ar =
Ben Noordhuisa7581d02016-03-31 10:47:061302 post_fn->Call(env->context(), object, arraysize(vals), vals);
Trevor Norrisa17200b2016-03-14 18:35:221303 if (ar.IsEmpty()) {
1304 ClearFatalExceptionHandlers(env);
1305 FatalException(env->isolate(), try_catch);
1306 return Local<Value>();
1307 }
Trevor Norris575b84e2016-02-11 20:09:521308 }
1309
Trevor Norris575b84e2016-02-11 20:09:521310 if (ret.IsEmpty()) {
Trevor Norris2dadd892016-03-23 23:02:041311 // NOTE: For backwards compatibility with public API we return Undefined()
1312 // if the top level call threw.
1313 return callback_scope.in_makecallback() ?
1314 ret : Undefined(env->isolate()).As<Value>();
Trevor Norrisb9e60322014-12-09 04:10:441315 }
1316
Trevor Norrisa1da0242014-12-09 04:24:591317 if (has_domain) {
1318 Local<Value> exit_v = domain->Get(env->exit_string());
1319 if (exit_v->IsFunction()) {
Trevor Norris95afe282016-02-11 20:57:261320 if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1321 FatalError("node::MakeCallback",
1322 "domain exit callback threw, please report this");
1323 }
Trevor Norrisa1da0242014-12-09 04:24:591324 }
1325 }
Trevor Norrisa1da0242014-12-09 04:24:591326
Trevor Norris41f333e2016-03-11 19:55:591327 if (callback_scope.in_makecallback()) {
1328 return ret;
1329 }
1330
1331 Environment::TickInfo* tick_info = env->tick_info();
1332
1333 if (tick_info->length() == 0) {
1334 env->isolate()->RunMicrotasks();
1335 }
1336
1337 Local<Object> process = env->process_object();
1338
1339 if (tick_info->length() == 0) {
1340 tick_info->set_index(0);
Trevor Norris8f8db142016-12-15 00:17:101341 return ret;
Trevor Norris41f333e2016-03-11 19:55:591342 }
1343
1344 if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
Fedor Indutny75adde02014-02-21 13:02:421345 return Undefined(env->isolate());
Trevor Norris95afe282016-02-11 20:57:261346 }
Trevor Norris86c07452013-02-07 01:26:181347
Trevor Norrisa0867e12013-03-17 04:59:471348 return ret;
1349}
1350
1351
Michaël Zasso4abc8962015-07-18 09:34:161352Local<Value> MakeCallback(Environment* env,
1353 Local<Object> recv,
1354 Local<String> symbol,
Ben Noordhuis756b6222013-08-10 22:26:111355 int argc,
Michaël Zasso4abc8962015-07-18 09:34:161356 Local<Value> argv[]) {
Trevor Norrisa1da0242014-12-09 04:24:591357 Local<Value> cb_v = recv->Get(symbol);
1358 CHECK(cb_v->IsFunction());
1359 return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
Trevor Norris86c07452013-02-07 01:26:181360}
1361
1362
Michaël Zasso4abc8962015-07-18 09:34:161363Local<Value> MakeCallback(Environment* env,
1364 Local<Object> recv,
Ben Noordhuis756b6222013-08-10 22:26:111365 const char* method,
1366 int argc,
Michaël Zasso4abc8962015-07-18 09:34:161367 Local<Value> argv[]) {
Fedor Indutny75adde02014-02-21 13:02:421368 Local<String> method_string = OneByteString(env->isolate(), method);
Ben Noordhuis1f2f3fa2014-01-27 02:58:161369 return MakeCallback(env, recv, method_string, argc, argv);
Ben Noordhuis756b6222013-08-10 22:26:111370}
Trevor Norris86c07452013-02-07 01:26:181371
Ben Noordhuis756b6222013-08-10 22:26:111372
Michaël Zasso4abc8962015-07-18 09:34:161373Local<Value> MakeCallback(Isolate* isolate,
Ben Noordhuis921d2b02016-10-21 09:57:201374 Local<Object> recv,
1375 const char* method,
1376 int argc,
1377 Local<Value> argv[]) {
Fedor Indutnyce04c722014-03-13 16:38:141378 EscapableHandleScope handle_scope(isolate);
Ben Noordhuis921d2b02016-10-21 09:57:201379 Local<String> method_string = OneByteString(isolate, method);
Fedor Indutnyce04c722014-03-13 16:38:141380 return handle_scope.Escape(
Ben Noordhuis921d2b02016-10-21 09:57:201381 MakeCallback(isolate, recv, method_string, argc, argv));
Ben Noordhuis756b6222013-08-10 22:26:111382}
1383
1384
Michaël Zasso4abc8962015-07-18 09:34:161385Local<Value> MakeCallback(Isolate* isolate,
Ben Noordhuis921d2b02016-10-21 09:57:201386 Local<Object> recv,
1387 Local<String> symbol,
1388 int argc,
1389 Local<Value> argv[]) {
Fedor Indutnyce04c722014-03-13 16:38:141390 EscapableHandleScope handle_scope(isolate);
Ben Noordhuis921d2b02016-10-21 09:57:201391 Local<Value> callback_v = recv->Get(symbol);
1392 if (callback_v.IsEmpty()) return Local<Value>();
1393 if (!callback_v->IsFunction()) return Local<Value>();
1394 Local<Function> callback = callback_v.As<Function>();
1395 return handle_scope.Escape(MakeCallback(isolate, recv, callback, argc, argv));
Ben Noordhuis756b6222013-08-10 22:26:111396}
1397
1398
Michaël Zasso4abc8962015-07-18 09:34:161399Local<Value> MakeCallback(Isolate* isolate,
Ben Noordhuis921d2b02016-10-21 09:57:201400 Local<Object> recv,
1401 Local<Function> callback,
1402 int argc,
1403 Local<Value> argv[]) {
1404 // Observe the following two subtleties:
1405 //
1406 // 1. The environment is retrieved from the callback function's context.
1407 // 2. The context to enter is retrieved from the environment.
1408 //
1409 // Because of the AssignToContext() call in src/node_contextify.cc,
1410 // the two contexts need not be the same.
Fedor Indutnyce04c722014-03-13 16:38:141411 EscapableHandleScope handle_scope(isolate);
Ben Noordhuis921d2b02016-10-21 09:57:201412 Environment* env = Environment::GetCurrent(callback->CreationContext());
1413 Context::Scope context_scope(env->context());
1414 return handle_scope.Escape(
1415 MakeCallback(env, recv.As<Value>(), callback, argc, argv));
Ben Noordhuis1f2f3fa2014-01-27 02:58:161416}
1417
1418
Fedor Indutnyc6367e72015-01-30 12:05:281419enum encoding ParseEncoding(const char* encoding,
1420 enum encoding default_encoding) {
1421 switch (encoding[0]) {
1422 case 'u':
1423 // utf8, utf16le
1424 if (encoding[1] == 't' && encoding[2] == 'f') {
1425 // Skip `-`
1426 encoding += encoding[3] == '-' ? 4 : 3;
1427 if (encoding[0] == '8' && encoding[1] == '\0')
1428 return UTF8;
1429 if (strncmp(encoding, "16le", 4) == 0)
1430 return UCS2;
Ryan Dahl07792af2009-09-21 10:27:221431
Fedor Indutnyc6367e72015-01-30 12:05:281432 // ucs2
1433 } else if (encoding[1] == 'c' && encoding[2] == 's') {
1434 encoding += encoding[3] == '-' ? 4 : 3;
1435 if (encoding[0] == '2' && encoding[1] == '\0')
1436 return UCS2;
1437 }
1438 break;
Trevor Norris54cc7212016-06-02 16:55:361439 case 'l':
1440 // latin1
1441 if (encoding[1] == 'a') {
1442 if (strncmp(encoding + 2, "tin1", 4) == 0)
1443 return LATIN1;
1444 }
Ben Noordhuis6b483242016-06-10 09:36:421445 break;
Fedor Indutnyc6367e72015-01-30 12:05:281446 case 'b':
1447 // binary
1448 if (encoding[1] == 'i') {
1449 if (strncmp(encoding + 2, "nary", 4) == 0)
Trevor Norris54cc7212016-06-02 16:55:361450 return LATIN1;
Ryan Dahl07792af2009-09-21 10:27:221451
Fedor Indutnyc6367e72015-01-30 12:05:281452 // buffer
1453 } else if (encoding[1] == 'u') {
1454 if (strncmp(encoding + 2, "ffer", 4) == 0)
1455 return BUFFER;
1456 }
1457 break;
1458 case '\0':
1459 return default_encoding;
1460 default:
1461 break;
1462 }
Ryan Dahl07792af2009-09-21 10:27:221463
Ben Noordhuisf6940df2016-05-04 18:56:041464 if (StringEqualNoCase(encoding, "utf8")) {
Ryan Dahl07792af2009-09-21 10:27:221465 return UTF8;
Ben Noordhuisf6940df2016-05-04 18:56:041466 } else if (StringEqualNoCase(encoding, "utf-8")) {
Ryan Dahl2b994d92009-10-06 08:45:181467 return UTF8;
Ben Noordhuisf6940df2016-05-04 18:56:041468 } else if (StringEqualNoCase(encoding, "ascii")) {
Ryan Dahl07792af2009-09-21 10:27:221469 return ASCII;
Ben Noordhuisf6940df2016-05-04 18:56:041470 } else if (StringEqualNoCase(encoding, "base64")) {
Ben Noordhuis95638c92010-07-28 12:20:231471 return BASE64;
Ben Noordhuisf6940df2016-05-04 18:56:041472 } else if (StringEqualNoCase(encoding, "ucs2")) {
Konstantin Käfer9e101f22011-02-06 20:49:521473 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041474 } else if (StringEqualNoCase(encoding, "ucs-2")) {
Konstantin Käfer9e101f22011-02-06 20:49:521475 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041476 } else if (StringEqualNoCase(encoding, "utf16le")) {
koichikfbb0ee62012-10-02 14:57:381477 return UCS2;
Ben Noordhuisf6940df2016-05-04 18:56:041478 } else if (StringEqualNoCase(encoding, "utf-16le")) {
koichikfbb0ee62012-10-02 14:57:381479 return UCS2;
Trevor Norris54cc7212016-06-02 16:55:361480 } else if (StringEqualNoCase(encoding, "latin1")) {
1481 return LATIN1;
Ben Noordhuisf6940df2016-05-04 18:56:041482 } else if (StringEqualNoCase(encoding, "binary")) {
Ben Noordhuisa92089b2016-06-13 09:37:391483 return LATIN1; // BINARY is a deprecated alias of LATIN1.
Ben Noordhuisf6940df2016-05-04 18:56:041484 } else if (StringEqualNoCase(encoding, "buffer")) {
Fedor Indutny63ff4492012-09-12 20:35:591485 return BUFFER;
Ben Noordhuisf6940df2016-05-04 18:56:041486 } else if (StringEqualNoCase(encoding, "hex")) {
isaacs0aa1a8a2011-02-20 01:29:011487 return HEX;
Ryan Dahl07792af2009-09-21 10:27:221488 } else {
Fedor Indutnyc6367e72015-01-30 12:05:281489 return default_encoding;
Ryan Dahl07792af2009-09-21 10:27:221490 }
1491}
1492
Fedor Indutnyc6367e72015-01-30 12:05:281493
1494enum encoding ParseEncoding(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:161495 Local<Value> encoding_v,
Fedor Indutnyc6367e72015-01-30 12:05:281496 enum encoding default_encoding) {
Tobias Nießen88351a22017-04-02 13:00:321497 CHECK(!encoding_v.IsEmpty());
1498
Fedor Indutnyc6367e72015-01-30 12:05:281499 if (!encoding_v->IsString())
1500 return default_encoding;
1501
1502 node::Utf8Value encoding(isolate, encoding_v);
1503
1504 return ParseEncoding(*encoding, default_encoding);
1505}
1506
Fedor Indutny75adde02014-02-21 13:02:421507Local<Value> Encode(Isolate* isolate,
Ben Noordhuis56fde662014-12-10 16:33:561508 const char* buf,
Fedor Indutny75adde02014-02-21 13:02:421509 size_t len,
1510 enum encoding encoding) {
Ben Noordhuis56fde662014-12-10 16:33:561511 CHECK_NE(encoding, UCS2);
1512 return StringBytes::Encode(isolate, buf, len, encoding);
1513}
1514
1515Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1516 return StringBytes::Encode(isolate, buf, len);
Ryan21a1b042009-09-09 13:51:491517}
1518
Ryand6c9d312009-09-11 14:02:291519// Returns -1 if the handle was not valid for decoding
Fedor Indutny75adde02014-02-21 13:02:421520ssize_t DecodeBytes(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:161521 Local<Value> val,
Fedor Indutny75adde02014-02-21 13:02:421522 enum encoding encoding) {
1523 HandleScope scope(isolate);
Ryan21a1b042009-09-09 13:51:491524
Fedor Indutny75adde02014-02-21 13:02:421525 return StringBytes::Size(isolate, val, encoding);
Ryan21a1b042009-09-09 13:51:491526}
1527
Ryan21a1b042009-09-09 13:51:491528// Returns number of bytes written.
Fedor Indutny75adde02014-02-21 13:02:421529ssize_t DecodeWrite(Isolate* isolate,
1530 char* buf,
Ryan Dahl53530e92010-04-02 21:55:281531 size_t buflen,
Michaël Zasso4abc8962015-07-18 09:34:161532 Local<Value> val,
Ryand6c9d312009-09-11 14:02:291533 enum encoding encoding) {
Ben Noordhuis2d82cdf2014-10-22 01:29:321534 return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
Ryan21a1b042009-09-09 13:51:491535}
1536
Brian White18490d32015-12-15 08:55:351537bool IsExceptionDecorated(Environment* env, Local<Value> er) {
1538 if (!er.IsEmpty() && er->IsObject()) {
1539 Local<Object> err_obj = er.As<Object>();
Ben Noordhuis924cc6c2016-02-02 22:50:071540 auto maybe_value =
1541 err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1542 Local<Value> decorated;
1543 return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
Brian White18490d32015-12-15 08:55:351544 }
1545 return false;
1546}
1547
Fedor Indutnyf1de13b2014-02-05 16:38:331548void AppendExceptionLine(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161549 Local<Value> er,
Anna Henningsen3cac6162016-06-24 03:50:001550 Local<Message> message,
1551 enum ErrorHandlingMode mode) {
Fedor Indutnyf1de13b2014-02-05 16:38:331552 if (message.IsEmpty())
Fedor Indutny2bc30f22013-10-16 16:57:261553 return;
isaacsb3cf3f32012-07-28 21:00:271554
Fedor Indutnyf1de13b2014-02-05 16:38:331555 HandleScope scope(env->isolate());
1556 Local<Object> err_obj;
1557 if (!er.IsEmpty() && er->IsObject()) {
1558 err_obj = er.As<Object>();
Ryan Dahlcdf5d912011-10-11 20:41:331559
Ben Noordhuis924cc6c2016-02-02 22:50:071560 auto context = env->context();
1561 auto processed_private_symbol = env->processed_private_symbol();
Fedor Indutnyf1de13b2014-02-05 16:38:331562 // Do it only once per message
Ben Noordhuis924cc6c2016-02-02 22:50:071563 if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
Fedor Indutnyf1de13b2014-02-05 16:38:331564 return;
Ben Noordhuis924cc6c2016-02-02 22:50:071565 err_obj->SetPrivate(
1566 context,
1567 processed_private_symbol,
1568 True(env->isolate()));
Ryan Dahl8e6dd522010-01-15 18:45:041569 }
Fedor Indutnyf1de13b2014-02-05 16:38:331570
Fedor Indutnyf1de13b2014-02-05 16:38:331571 // Print (filename):(line number): (message).
Trevor Norriscbf76c12015-01-07 22:13:351572 node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
Fedor Indutnyf1de13b2014-02-05 16:38:331573 const char* filename_string = *filename;
1574 int linenum = message->GetLineNumber();
1575 // Print line of source code.
Trevor Norriscbf76c12015-01-07 22:13:351576 node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
Fedor Indutnyf1de13b2014-02-05 16:38:331577 const char* sourceline_string = *sourceline;
1578
1579 // Because of how node modules work, all scripts are wrapped with a
1580 // "function (module, exports, __filename, ...) {"
1581 // to provide script local variables.
1582 //
1583 // When reporting errors on the first line of a script, this wrapper
1584 // function is leaked to the user. There used to be a hack here to
1585 // truncate off the first 62 characters, but it caused numerous other
1586 // problems when vm.runIn*Context() methods were used for non-module
1587 // code.
1588 //
1589 // If we ever decide to re-instate such a hack, the following steps
1590 // must be taken:
1591 //
1592 // 1. Pass a flag around to say "this code was wrapped"
1593 // 2. Update the stack frame output so that it is also correct.
1594 //
1595 // It would probably be simpler to add a line rather than add some
1596 // number of characters to the first line, since V8 truncates the
1597 // sourceline to 78 characters, and we end up not providing very much
1598 // useful debugging info to the user if we remove 62 characters.
1599
Anna Henningsen4bd410b2016-05-20 20:55:371600 int start = message->GetStartColumn(env->context()).FromMaybe(0);
1601 int end = message->GetEndColumn(env->context()).FromMaybe(0);
Fedor Indutnyf1de13b2014-02-05 16:38:331602
Karl Skomski3bb92372015-09-03 08:10:291603 char arrow[1024];
1604 int max_off = sizeof(arrow) - 2;
1605
Fedor Indutnyf1de13b2014-02-05 16:38:331606 int off = snprintf(arrow,
1607 sizeof(arrow),
1608 "%s:%i\n%s\n",
1609 filename_string,
1610 linenum,
1611 sourceline_string);
Ben Noordhuis5fdff382014-10-11 14:52:071612 CHECK_GE(off, 0);
Karl Skomski3bb92372015-09-03 08:10:291613 if (off > max_off) {
1614 off = max_off;
1615 }
Fedor Indutnyf1de13b2014-02-05 16:38:331616
1617 // Print wavy underline (GetUnderline is deprecated).
1618 for (int i = 0; i < start; i++) {
Karl Skomski3bb92372015-09-03 08:10:291619 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:501620 break;
1621 }
Karl Skomski3bb92372015-09-03 08:10:291622 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:331623 arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1624 }
1625 for (int i = start; i < end; i++) {
Karl Skomski3bb92372015-09-03 08:10:291626 if (sourceline_string[i] == '\0' || off >= max_off) {
Yazhong Liu6b09f9c2014-06-25 13:18:501627 break;
1628 }
Karl Skomski3bb92372015-09-03 08:10:291629 CHECK_LT(off, max_off);
Fedor Indutnyf1de13b2014-02-05 16:38:331630 arrow[off++] = '^';
1631 }
Karl Skomski3bb92372015-09-03 08:10:291632 CHECK_LE(off, max_off);
1633 arrow[off] = '\n';
1634 arrow[off + 1] = '\0';
Fedor Indutnyf1de13b2014-02-05 16:38:331635
1636 Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
Fedor Indutnyf1de13b2014-02-05 16:38:331637
Anna Henningsen3cac6162016-06-24 03:50:001638 const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1639 // If allocating arrow_str failed, print it out. There's not much else to do.
1640 // If it's not an error, but something needs to be printed out because
1641 // it's a fatal exception, also print it out from here.
1642 // Otherwise, the arrow property will be attached to the object and handled
1643 // by the caller.
1644 if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1645 if (env->printed_error())
1646 return;
1647 env->set_printed_error(true);
1648
1649 uv_tty_reset_mode();
1650 PrintErrorString("\n%s", arrow);
Ben Noordhuis924cc6c2016-02-02 22:50:071651 return;
1652 }
Fedor Indutnyf1de13b2014-02-05 16:38:331653
Anna Henningsen3cac6162016-06-24 03:50:001654 CHECK(err_obj->SetPrivate(
1655 env->context(),
1656 env->arrow_message_private_symbol(),
1657 arrow_str).FromMaybe(false));
Ryan Dahlb57c1f52010-11-24 02:46:131658}
1659
1660
Fedor Indutnyf1de13b2014-02-05 16:38:331661static void ReportException(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161662 Local<Value> er,
1663 Local<Message> message) {
Fedor Indutnyf1de13b2014-02-05 16:38:331664 HandleScope scope(env->isolate());
Ryan Dahlb57c1f52010-11-24 02:46:131665
Anna Henningsen3cac6162016-06-24 03:50:001666 AppendExceptionLine(env, er, message, FATAL_ERROR);
Ryan Dahl53a841d2009-12-29 19:20:511667
Vladimir Kurchatkin259d4492013-12-06 11:56:371668 Local<Value> trace_value;
Fedor Indutnyef653212015-07-05 18:20:261669 Local<Value> arrow;
Brian White18490d32015-12-15 08:55:351670 const bool decorated = IsExceptionDecorated(env, er);
Vladimir Kurchatkin259d4492013-12-06 11:56:371671
Fedor Indutnyef653212015-07-05 18:20:261672 if (er->IsUndefined() || er->IsNull()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331673 trace_value = Undefined(env->isolate());
Fedor Indutnyef653212015-07-05 18:20:261674 } else {
1675 Local<Object> err_obj = er->ToObject(env->isolate());
1676
1677 trace_value = err_obj->Get(env->stack_string());
Ben Noordhuis924cc6c2016-02-02 22:50:071678 arrow =
1679 err_obj->GetPrivate(
1680 env->context(),
1681 env->arrow_message_private_symbol()).ToLocalChecked();
Fedor Indutnyef653212015-07-05 18:20:261682 }
Vladimir Kurchatkin259d4492013-12-06 11:56:371683
Trevor Norriscbf76c12015-01-07 22:13:351684 node::Utf8Value trace(env->isolate(), trace_value);
Ryan Dahlda932302010-05-14 18:48:141685
isaacs8df6f9e2011-04-25 19:22:181686 // range errors have a trace member set to undefined
Miroslav Bajtosc16963b2013-06-17 19:19:591687 if (trace.length() > 0 && !trace_value->IsUndefined()) {
Brian White18490d32015-12-15 08:55:351688 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:151689 PrintErrorString("%s\n", *trace);
Fedor Indutnyef653212015-07-05 18:20:261690 } else {
1691 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:151692 PrintErrorString("%s\n%s\n", *arrow_string, *trace);
Fedor Indutnyef653212015-07-05 18:20:261693 }
isaacse9b6b0b2010-10-02 06:22:341694 } else {
1695 // this really only happens for RangeErrors, since they're the only
isaacs8df6f9e2011-04-25 19:22:181696 // kind that won't have all this info in the trace, or when non-Error
1697 // objects are thrown manually.
Ben Noordhuisf674b092013-08-07 19:50:411698 Local<Value> message;
1699 Local<Value> name;
isaacs8df6f9e2011-04-25 19:22:181700
Ben Noordhuisf674b092013-08-07 19:50:411701 if (er->IsObject()) {
1702 Local<Object> err_obj = er.As<Object>();
Fedor Indutnyf1de13b2014-02-05 16:38:331703 message = err_obj->Get(env->message_string());
1704 name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
isaacs8df6f9e2011-04-25 19:22:181705 }
1706
Ben Noordhuisf674b092013-08-07 19:50:411707 if (message.IsEmpty() ||
1708 message->IsUndefined() ||
1709 name.IsEmpty() ||
1710 name->IsUndefined()) {
1711 // Not an error object. Just print as-is.
cjihrig1ec09b02015-12-02 01:34:451712 String::Utf8Value message(er);
1713
1714 PrintErrorString("%s\n", *message ? *message :
1715 "<toString() threw exception>");
Ben Noordhuisf674b092013-08-07 19:50:411716 } else {
Trevor Norriscbf76c12015-01-07 22:13:351717 node::Utf8Value name_string(env->isolate(), name);
1718 node::Utf8Value message_string(env->isolate(), message);
Fedor Indutnyef653212015-07-05 18:20:261719
Brian White18490d32015-12-15 08:55:351720 if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
Brian White2d356072015-10-13 21:18:151721 PrintErrorString("%s: %s\n", *name_string, *message_string);
Fedor Indutnyef653212015-07-05 18:20:261722 } else {
1723 node::Utf8Value arrow_string(env->isolate(), arrow);
Brian White2d356072015-10-13 21:18:151724 PrintErrorString("%s\n%s: %s\n",
1725 *arrow_string,
1726 *name_string,
1727 *message_string);
Fedor Indutnyef653212015-07-05 18:20:261728 }
Ben Noordhuisf674b092013-08-07 19:50:411729 }
Ryan5131e0a2009-03-09 00:23:411730 }
isaacse9b6b0b2010-10-02 06:22:341731
Ryand7e220c2009-09-09 20:35:401732 fflush(stderr);
Ryan5131e0a2009-03-09 00:23:411733}
1734
Miroslav Bajtosc16963b2013-06-17 19:19:591735
Fedor Indutnyf1de13b2014-02-05 16:38:331736static void ReportException(Environment* env, const TryCatch& try_catch) {
1737 ReportException(env, try_catch.Exception(), try_catch.Message());
Miroslav Bajtosc16963b2013-06-17 19:19:591738}
1739
1740
Ryand6c9d312009-09-11 14:02:291741// Executes a str within the current v8 context.
Fedor Indutnyf1de13b2014-02-05 16:38:331742static Local<Value> ExecuteString(Environment* env,
Michaël Zasso4abc8962015-07-18 09:34:161743 Local<String> source,
1744 Local<String> filename) {
Fedor Indutnyce04c722014-03-13 16:38:141745 EscapableHandleScope scope(env->isolate());
Michaël Zasso79d74752016-01-26 08:06:431746 TryCatch try_catch(env->isolate());
Ryan408526a2009-04-21 11:52:211747
Miroslav Bajtosc16963b2013-06-17 19:19:591748 // try_catch must be nonverbose to disable FatalException() handler,
1749 // we will handle exceptions ourself.
1750 try_catch.SetVerbose(false);
1751
Michaël Zasso023c3172016-02-08 21:34:051752 ScriptOrigin origin(filename);
1753 MaybeLocal<v8::Script> script =
1754 v8::Script::Compile(env->context(), source, &origin);
Ryan63a9cd32009-04-15 08:08:281755 if (script.IsEmpty()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331756 ReportException(env, try_catch);
isaacs95862b22013-02-27 19:23:201757 exit(3);
Ryan63a9cd32009-04-15 08:08:281758 }
1759
Michaël Zasso023c3172016-02-08 21:34:051760 Local<Value> result = script.ToLocalChecked()->Run();
Ryan63a9cd32009-04-15 08:08:281761 if (result.IsEmpty()) {
Fedor Indutnyf1de13b2014-02-05 16:38:331762 ReportException(env, try_catch);
isaacs95862b22013-02-27 19:23:201763 exit(4);
Ryan63a9cd32009-04-15 08:08:281764 }
1765
Fedor Indutnyce04c722014-03-13 16:38:141766 return scope.Escape(result);
Ryan63a9cd32009-04-15 08:08:281767}
1768
Felix Geisendörfer7371fcb2009-11-11 17:10:581769
Ben Noordhuis110a9cd2013-07-03 02:23:441770static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551771 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101772
Fedor Indutnyce04c722014-03-13 16:38:141773 Local<Array> ary = Array::New(args.GetIsolate());
Trevor Norris494227b2015-10-14 20:58:521774 Local<Context> ctx = env->context();
Trevor Norris83524b32015-11-10 09:58:511775 Local<Function> fn = env->push_values_to_array_function();
Trevor Norris946315f2015-11-11 00:04:561776 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1777 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101778
Trevor Norris494227b2015-10-14 20:58:521779 for (auto w : *env->req_wrap_queue()) {
Trevor Norris946315f2015-11-11 00:04:561780 if (w->persistent().IsEmpty())
1781 continue;
1782 argv[idx] = w->object();
Ben Noordhuisa7581d02016-03-31 10:47:061783 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561784 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1785 idx = 0;
Trevor Norris494227b2015-10-14 20:58:521786 }
1787 }
1788
Trevor Norris946315f2015-11-11 00:04:561789 if (idx > 0) {
1790 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Trevor Norris494227b2015-10-14 20:58:521791 }
Ben Noordhuis5f040652012-04-28 16:45:101792
Ben Noordhuis110a9cd2013-07-03 02:23:441793 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101794}
1795
1796
1797// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1798// implemented here for consistency with GetActiveRequests().
Ben Noordhuis110a9cd2013-07-03 02:23:441799void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551800 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis5f040652012-04-28 16:45:101801
Fedor Indutnyce04c722014-03-13 16:38:141802 Local<Array> ary = Array::New(env->isolate());
Trevor Norris946315f2015-11-11 00:04:561803 Local<Context> ctx = env->context();
1804 Local<Function> fn = env->push_values_to_array_function();
1805 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1806 size_t idx = 0;
Ben Noordhuis5f040652012-04-28 16:45:101807
Fedor Indutny75adde02014-02-21 13:02:421808 Local<String> owner_sym = env->owner_string();
Ben Noordhuise813e342012-05-15 15:24:061809
Ben Noordhuis38dc0cd2015-01-30 11:54:531810 for (auto w : *env->handle_wrap_queue()) {
Ben Noordhuiscad1a622016-04-26 10:01:461811 if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
Fedor Indutny2bc30f22013-10-16 16:57:261812 continue;
Ben Noordhuis110a9cd2013-07-03 02:23:441813 Local<Object> object = w->object();
1814 Local<Value> owner = object->Get(owner_sym);
Fedor Indutny2bc30f22013-10-16 16:57:261815 if (owner->IsUndefined())
1816 owner = object;
Trevor Norris946315f2015-11-11 00:04:561817 argv[idx] = owner;
Ben Noordhuisa7581d02016-03-31 10:47:061818 if (++idx >= arraysize(argv)) {
Trevor Norris946315f2015-11-11 00:04:561819 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1820 idx = 0;
1821 }
1822 }
1823 if (idx > 0) {
1824 fn->Call(ctx, ary, idx, argv).ToLocalChecked();
Ben Noordhuis5f040652012-04-28 16:45:101825 }
1826
Ben Noordhuis110a9cd2013-07-03 02:23:441827 args.GetReturnValue().Set(ary);
Ben Noordhuis5f040652012-04-28 16:45:101828}
1829
1830
Ben Noordhuisbe767cf2016-06-19 08:44:221831NO_RETURN void Abort() {
1832 DumpBacktrace(stderr);
1833 fflush(stderr);
1834 ABORT_NO_BACKTRACE();
1835}
1836
1837
Ben Noordhuis92dab4a2016-06-19 10:10:451838NO_RETURN void Assert(const char* const (*args)[4]) {
1839 auto filename = (*args)[0];
1840 auto linenum = (*args)[1];
1841 auto message = (*args)[2];
1842 auto function = (*args)[3];
1843
1844 char exepath[256];
1845 size_t exepath_size = sizeof(exepath);
1846 if (uv_exepath(exepath, &exepath_size))
1847 snprintf(exepath, sizeof(exepath), "node");
1848
1849 char pid[12] = {0};
1850#ifndef _WIN32
1851 snprintf(pid, sizeof(pid), "[%u]", getpid());
1852#endif
1853
1854 fprintf(stderr, "%s%s: %s:%s:%s%s Assertion `%s' failed.\n",
1855 exepath, pid, filename, linenum,
1856 function, *function ? ":" : "", message);
1857 fflush(stderr);
1858
1859 Abort();
1860}
1861
1862
Ben Noordhuis110a9cd2013-07-03 02:23:441863static void Abort(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisbe767cf2016-06-19 08:44:221864 Abort();
Robert Mustacchi22404862011-12-15 01:02:151865}
1866
1867
Ben Noordhuis110a9cd2013-07-03 02:23:441868static void Chdir(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551869 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb20c3432010-02-12 05:55:081870
Brandon Beacher47fcf782009-11-03 18:13:381871 if (args.Length() != 1 || !args[0]->IsString()) {
Caitlin Potterbe2404e2015-01-09 16:38:281872 return env->ThrowTypeError("Bad argument.");
Brandon Beacher47fcf782009-11-03 18:13:381873 }
Ryan Dahlb20c3432010-02-12 05:55:081874
Trevor Norriscbf76c12015-01-07 22:13:351875 node::Utf8Value path(args.GetIsolate(), args[0]);
Ben Noordhuisca9eb712013-07-18 21:18:501876 int err = uv_chdir(*path);
1877 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421878 return env->ThrowUVException(err, "uv_chdir");
Brandon Beacher47fcf782009-11-03 18:13:381879 }
Brandon Beacher47fcf782009-11-03 18:13:381880}
1881
Bert Beldercbcf4fe2011-11-24 01:19:541882
Ben Noordhuis110a9cd2013-07-03 02:23:441883static void Cwd(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551884 Environment* env = Environment::GetCurrent(args);
Bert Beldere84edd22011-12-01 23:24:441885#ifdef _WIN32
1886 /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261887 char buf[MAX_PATH * 4];
Bert Beldere84edd22011-12-01 23:24:441888#else
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261889 char buf[PATH_MAX];
Bert Beldere84edd22011-12-01 23:24:441890#endif
Michael Carter8ea6adc2009-09-01 09:39:301891
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261892 size_t cwd_len = sizeof(buf);
1893 int err = uv_cwd(buf, &cwd_len);
Ben Noordhuisca9eb712013-07-18 21:18:501894 if (err) {
Fedor Indutny75adde02014-02-21 13:02:421895 return env->ThrowUVException(err, "uv_cwd");
Michael Carter8ea6adc2009-09-01 09:39:301896 }
Peter Griess4e3c5d82010-07-12 15:47:451897
Saúl Ibarra Corretgéd2f2a322014-03-02 22:18:261898 Local<String> cwd = String::NewFromUtf8(env->isolate(),
1899 buf,
1900 String::kNormalString,
Saúl Ibarra Corretgée46cbaa2014-10-17 07:31:591901 cwd_len);
Ben Noordhuis110a9cd2013-07-03 02:23:441902 args.GetReturnValue().Set(cwd);
Michael Carter8ea6adc2009-09-01 09:39:301903}
1904
Bert Beldere84edd22011-12-01 23:24:441905
Ben Noordhuis110a9cd2013-07-03 02:23:441906static void Umask(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:551907 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis110a9cd2013-07-03 02:23:441908 uint32_t old;
isaacs5f2e9092011-01-25 18:40:121909
Ryan Dahlacc120a2011-08-09 20:53:561910 if (args.Length() < 1 || args[0]->IsUndefined()) {
Rasmus Andersson374300c2010-02-27 17:18:411911 old = umask(0);
Ben Noordhuis110a9cd2013-07-03 02:23:441912 umask(static_cast<mode_t>(old));
Fedor Indutny8e29ce92013-07-31 18:07:291913 } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:421914 return env->ThrowTypeError("argument must be an integer or octal string.");
isaacs5f2e9092011-01-25 18:40:121915 } else {
1916 int oct;
Fedor Indutny8e29ce92013-07-31 18:07:291917 if (args[0]->IsInt32()) {
isaacs5f2e9092011-01-25 18:40:121918 oct = args[0]->Uint32Value();
1919 } else {
1920 oct = 0;
Trevor Norriscbf76c12015-01-07 22:13:351921 node::Utf8Value str(env->isolate(), args[0]);
isaacs5f2e9092011-01-25 18:40:121922
1923 // Parse the octal string.
Timothy J Fontaine1a09da62014-06-10 23:36:041924 for (size_t i = 0; i < str.length(); i++) {
isaacs5f2e9092011-01-25 18:40:121925 char c = (*str)[i];
1926 if (c > '7' || c < '0') {
Fedor Indutny75adde02014-02-21 13:02:421927 return env->ThrowTypeError("invalid octal string");
isaacs5f2e9092011-01-25 18:40:121928 }
1929 oct *= 8;
1930 oct += c - '0';
1931 }
1932 }
1933 old = umask(static_cast<mode_t>(oct));
Friedemann Altrock0433d822009-11-22 18:52:521934 }
isaacs5f2e9092011-01-25 18:40:121935
Ben Noordhuis110a9cd2013-07-03 02:23:441936 args.GetReturnValue().Set(old);
Friedemann Altrock0433d822009-11-22 18:52:521937}
1938
Michael Cartera3860762010-02-08 06:13:101939
Linus MÃ¥rtensson5e4e8ec2013-05-08 12:10:071940#if defined(__POSIX__) && !defined(__ANDROID__)
Ryan Dahlacc120a2011-08-09 20:53:561941
Ben Noordhuis3ece1302012-12-04 05:36:231942static const uid_t uid_not_found = static_cast<uid_t>(-1);
1943static const gid_t gid_not_found = static_cast<gid_t>(-1);
1944
1945
1946static uid_t uid_by_name(const char* name) {
1947 struct passwd pwd;
1948 struct passwd* pp;
1949 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231950
1951 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321952 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231953
Ben Noordhuis2d82cdf2014-10-22 01:29:321954 if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231955 return pp->pw_uid;
1956 }
1957
1958 return uid_not_found;
1959}
1960
1961
1962static char* name_by_uid(uid_t uid) {
1963 struct passwd pwd;
1964 struct passwd* pp;
1965 char buf[8192];
1966 int rc;
1967
1968 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321969 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231970
Ben Noordhuis2d82cdf2014-10-22 01:29:321971 if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1972 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231973 return strdup(pp->pw_name);
1974 }
1975
1976 if (rc == 0) {
1977 errno = ENOENT;
1978 }
1979
Ben Noordhuis2d82cdf2014-10-22 01:29:321980 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231981}
1982
1983
1984static gid_t gid_by_name(const char* name) {
1985 struct group pwd;
1986 struct group* pp;
1987 char buf[8192];
Ben Noordhuis3ece1302012-12-04 05:36:231988
1989 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:321990 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:231991
Ben Noordhuis2d82cdf2014-10-22 01:29:321992 if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:231993 return pp->gr_gid;
1994 }
1995
1996 return gid_not_found;
1997}
1998
1999
2000#if 0 // For future use.
2001static const char* name_by_gid(gid_t gid) {
2002 struct group pwd;
2003 struct group* pp;
2004 char buf[8192];
2005 int rc;
2006
2007 errno = 0;
Ben Noordhuis2d82cdf2014-10-22 01:29:322008 pp = nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:232009
Ben Noordhuis2d82cdf2014-10-22 01:29:322010 if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
2011 pp != nullptr) {
Ben Noordhuis3ece1302012-12-04 05:36:232012 return strdup(pp->gr_name);
2013 }
2014
2015 if (rc == 0) {
2016 errno = ENOENT;
2017 }
2018
Ben Noordhuis2d82cdf2014-10-22 01:29:322019 return nullptr;
Ben Noordhuis3ece1302012-12-04 05:36:232020}
2021#endif
2022
2023
Michaël Zasso4abc8962015-07-18 09:34:162024static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:232025 if (value->IsUint32()) {
2026 return static_cast<uid_t>(value->Uint32Value());
2027 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142028 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:232029 return uid_by_name(*name);
2030 }
2031}
2032
2033
Michaël Zasso4abc8962015-07-18 09:34:162034static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
Ben Noordhuis3ece1302012-12-04 05:36:232035 if (value->IsUint32()) {
2036 return static_cast<gid_t>(value->Uint32Value());
2037 } else {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142038 node::Utf8Value name(isolate, value);
Ben Noordhuis3ece1302012-12-04 05:36:232039 return gid_by_name(*name);
2040 }
2041}
2042
Ben Noordhuis110a9cd2013-07-03 02:23:442043static void GetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:082044 // uid_t is an uint32_t on all supported platforms.
2045 args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
Michael Cartera3860762010-02-08 06:13:102046}
2047
Ryan Dahlacc120a2011-08-09 20:53:562048
Ben Noordhuis110a9cd2013-07-03 02:23:442049static void GetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis6df47412013-09-05 19:47:082050 // gid_t is an uint32_t on all supported platforms.
2051 args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
James Duncandf1c1e52010-02-23 22:45:022052}
2053
2054
Evan Lucas3c92ca22015-04-27 16:24:192055static void GetEUid(const FunctionCallbackInfo<Value>& args) {
2056 // uid_t is an uint32_t on all supported platforms.
2057 args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
2058}
2059
2060
2061static void GetEGid(const FunctionCallbackInfo<Value>& args) {
2062 // gid_t is an uint32_t on all supported platforms.
2063 args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
2064}
2065
2066
Ben Noordhuis110a9cd2013-07-03 02:23:442067static void SetGid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552068 Environment* env = Environment::GetCurrent(args);
Ryan Dahl39943402010-03-15 19:49:402069
Ben Noordhuis3ece1302012-12-04 05:36:232070 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:422071 return env->ThrowTypeError("setgid argument must be a number or a string");
James Duncandf1c1e52010-02-23 22:45:022072 }
2073
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142074 gid_t gid = gid_by_name(env->isolate(), args[0]);
Blake Mizerany8c853402010-06-30 06:12:462075
Ben Noordhuis3ece1302012-12-04 05:36:232076 if (gid == gid_not_found) {
Fedor Indutny75adde02014-02-21 13:02:422077 return env->ThrowError("setgid group id does not exist");
Peter Griess2420f072010-05-19 00:40:442078 }
2079
Ben Noordhuis3ece1302012-12-04 05:36:232080 if (setgid(gid)) {
Fedor Indutny75adde02014-02-21 13:02:422081 return env->ThrowErrnoException(errno, "setgid");
James Duncandf1c1e52010-02-23 22:45:022082 }
James Duncandf1c1e52010-02-23 22:45:022083}
Michael Cartera3860762010-02-08 06:13:102084
Ryan Dahlacc120a2011-08-09 20:53:562085
Evan Lucas3c92ca22015-04-27 16:24:192086static void SetEGid(const FunctionCallbackInfo<Value>& args) {
2087 Environment* env = Environment::GetCurrent(args);
2088
2089 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2090 return env->ThrowTypeError("setegid argument must be a number or string");
2091 }
2092
2093 gid_t gid = gid_by_name(env->isolate(), args[0]);
2094
2095 if (gid == gid_not_found) {
2096 return env->ThrowError("setegid group id does not exist");
2097 }
2098
2099 if (setegid(gid)) {
2100 return env->ThrowErrnoException(errno, "setegid");
2101 }
2102}
2103
2104
Ben Noordhuis110a9cd2013-07-03 02:23:442105static void SetUid(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552106 Environment* env = Environment::GetCurrent(args);
Michael Cartera3860762010-02-08 06:13:102107
Ben Noordhuis3ece1302012-12-04 05:36:232108 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:422109 return env->ThrowTypeError("setuid argument must be a number or a string");
Michael Cartera3860762010-02-08 06:13:102110 }
2111
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142112 uid_t uid = uid_by_name(env->isolate(), args[0]);
Peter Griess2420f072010-05-19 00:40:442113
Ben Noordhuis3ece1302012-12-04 05:36:232114 if (uid == uid_not_found) {
Fedor Indutny75adde02014-02-21 13:02:422115 return env->ThrowError("setuid user id does not exist");
Peter Griess2420f072010-05-19 00:40:442116 }
2117
Ben Noordhuis3ece1302012-12-04 05:36:232118 if (setuid(uid)) {
Fedor Indutny75adde02014-02-21 13:02:422119 return env->ThrowErrnoException(errno, "setuid");
Michael Cartera3860762010-02-08 06:13:102120 }
Michael Cartera3860762010-02-08 06:13:102121}
2122
Ryan Dahlacc120a2011-08-09 20:53:562123
Evan Lucas3c92ca22015-04-27 16:24:192124static void SetEUid(const FunctionCallbackInfo<Value>& args) {
2125 Environment* env = Environment::GetCurrent(args);
2126
2127 if (!args[0]->IsUint32() && !args[0]->IsString()) {
2128 return env->ThrowTypeError("seteuid argument must be a number or string");
2129 }
2130
2131 uid_t uid = uid_by_name(env->isolate(), args[0]);
2132
2133 if (uid == uid_not_found) {
2134 return env->ThrowError("seteuid user id does not exist");
2135 }
2136
2137 if (seteuid(uid)) {
2138 return env->ThrowErrnoException(errno, "seteuid");
2139 }
2140}
2141
2142
Ben Noordhuis110a9cd2013-07-03 02:23:442143static void GetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552144 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:232145
Ben Noordhuis2d82cdf2014-10-22 01:29:322146 int ngroups = getgroups(0, nullptr);
Ben Noordhuis3ece1302012-12-04 05:36:232147
2148 if (ngroups == -1) {
Fedor Indutny75adde02014-02-21 13:02:422149 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:232150 }
2151
2152 gid_t* groups = new gid_t[ngroups];
2153
2154 ngroups = getgroups(ngroups, groups);
2155
2156 if (ngroups == -1) {
2157 delete[] groups;
Fedor Indutny75adde02014-02-21 13:02:422158 return env->ThrowErrnoException(errno, "getgroups");
Ben Noordhuis3ece1302012-12-04 05:36:232159 }
2160
Fedor Indutnyce04c722014-03-13 16:38:142161 Local<Array> groups_list = Array::New(env->isolate(), ngroups);
Ben Noordhuis3ece1302012-12-04 05:36:232162 bool seen_egid = false;
2163 gid_t egid = getegid();
2164
2165 for (int i = 0; i < ngroups; i++) {
Fedor Indutnyce04c722014-03-13 16:38:142166 groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
Fedor Indutny2bc30f22013-10-16 16:57:262167 if (groups[i] == egid)
2168 seen_egid = true;
Ben Noordhuis3ece1302012-12-04 05:36:232169 }
2170
2171 delete[] groups;
2172
2173 if (seen_egid == false) {
Fedor Indutnyce04c722014-03-13 16:38:142174 groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
Ben Noordhuis3ece1302012-12-04 05:36:232175 }
2176
Ben Noordhuis110a9cd2013-07-03 02:23:442177 args.GetReturnValue().Set(groups_list);
Ben Noordhuis3ece1302012-12-04 05:36:232178}
2179
2180
Ben Noordhuis110a9cd2013-07-03 02:23:442181static void SetGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552182 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:232183
2184 if (!args[0]->IsArray()) {
Fedor Indutny75adde02014-02-21 13:02:422185 return env->ThrowTypeError("argument 1 must be an array");
Ben Noordhuis3ece1302012-12-04 05:36:232186 }
2187
2188 Local<Array> groups_list = args[0].As<Array>();
2189 size_t size = groups_list->Length();
2190 gid_t* groups = new gid_t[size];
2191
2192 for (size_t i = 0; i < size; i++) {
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142193 gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
Ben Noordhuis3ece1302012-12-04 05:36:232194
2195 if (gid == gid_not_found) {
2196 delete[] groups;
Fedor Indutny75adde02014-02-21 13:02:422197 return env->ThrowError("group name not found");
Ben Noordhuis3ece1302012-12-04 05:36:232198 }
2199
2200 groups[i] = gid;
2201 }
2202
2203 int rc = setgroups(size, groups);
2204 delete[] groups;
2205
2206 if (rc == -1) {
Fedor Indutny75adde02014-02-21 13:02:422207 return env->ThrowErrnoException(errno, "setgroups");
Ben Noordhuis3ece1302012-12-04 05:36:232208 }
Ben Noordhuis3ece1302012-12-04 05:36:232209}
2210
2211
Ben Noordhuis110a9cd2013-07-03 02:23:442212static void InitGroups(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552213 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis3ece1302012-12-04 05:36:232214
2215 if (!args[0]->IsUint32() && !args[0]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:422216 return env->ThrowTypeError("argument 1 must be a number or a string");
Ben Noordhuis3ece1302012-12-04 05:36:232217 }
2218
2219 if (!args[1]->IsUint32() && !args[1]->IsString()) {
Fedor Indutny75adde02014-02-21 13:02:422220 return env->ThrowTypeError("argument 2 must be a number or a string");
Ben Noordhuis3ece1302012-12-04 05:36:232221 }
2222
Trevor Norriscbf76c12015-01-07 22:13:352223 node::Utf8Value arg0(env->isolate(), args[0]);
Ben Noordhuis3ece1302012-12-04 05:36:232224 gid_t extra_group;
2225 bool must_free;
2226 char* user;
2227
2228 if (args[0]->IsUint32()) {
2229 user = name_by_uid(args[0]->Uint32Value());
2230 must_free = true;
2231 } else {
2232 user = *arg0;
2233 must_free = false;
2234 }
2235
Ben Noordhuis2d82cdf2014-10-22 01:29:322236 if (user == nullptr) {
Fedor Indutny75adde02014-02-21 13:02:422237 return env->ThrowError("initgroups user not found");
Ben Noordhuis3ece1302012-12-04 05:36:232238 }
2239
Vladimir Kurchatkin8aed9d62015-02-06 17:48:142240 extra_group = gid_by_name(env->isolate(), args[1]);
Ben Noordhuis3ece1302012-12-04 05:36:232241
2242 if (extra_group == gid_not_found) {
Fedor Indutny2bc30f22013-10-16 16:57:262243 if (must_free)
2244 free(user);
Fedor Indutny75adde02014-02-21 13:02:422245 return env->ThrowError("initgroups extra group not found");
Ben Noordhuis3ece1302012-12-04 05:36:232246 }
2247
2248 int rc = initgroups(user, extra_group);
2249
2250 if (must_free) {
2251 free(user);
2252 }
2253
2254 if (rc) {
Fedor Indutny75adde02014-02-21 13:02:422255 return env->ThrowErrnoException(errno, "initgroups");
Ben Noordhuis3ece1302012-12-04 05:36:232256 }
Ben Noordhuis3ece1302012-12-04 05:36:232257}
2258
Fedor Indutny8e29ce92013-07-31 18:07:292259#endif // __POSIX__ && !defined(__ANDROID__)
Bert Belder30bab522010-11-25 00:09:062260
Michael Cartera3860762010-02-08 06:13:102261
Eugene Ostroukhov66269192016-06-08 21:09:282262static void WaitForInspectorDisconnect(Environment* env) {
2263#if HAVE_INSPECTOR
2264 if (env->inspector_agent()->IsConnected()) {
2265 // Restore signal dispositions, the app is done and is no longer
2266 // capable of handling signals.
Stewart X Addison0f0f3d32016-12-30 12:44:462267#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
Eugene Ostroukhov66269192016-06-08 21:09:282268 struct sigaction act;
2269 memset(&act, 0, sizeof(act));
2270 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2271 if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2272 continue;
2273 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2274 CHECK_EQ(0, sigaction(nr, &act, nullptr));
2275 }
2276#endif
2277 env->inspector_agent()->WaitForDisconnect();
2278 }
2279#endif
2280}
2281
2282
Anna Henningsen9d522222017-04-12 17:17:242283static void Exit(const FunctionCallbackInfo<Value>& args) {
Eugene Ostroukhov66269192016-06-08 21:09:282284 WaitForInspectorDisconnect(Environment::GetCurrent(args));
Rasmus Christian Pedersen734fb492014-09-18 12:10:532285 exit(args[0]->Int32Value());
Ryan0f517032009-04-29 09:09:322286}
2287
Ryan Dahl3ac6dee2010-05-08 02:05:592288
Ben Noordhuis110a9cd2013-07-03 02:23:442289static void Uptime(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552290 Environment* env = Environment::GetCurrent(args);
Igor Zinkovsky500c8f42011-12-15 20:36:052291 double uptime;
Tom Hughescf78ce52011-03-04 23:57:542292
Fedor Indutny6a610a02014-10-04 14:44:392293 uv_update_time(env->event_loop());
2294 uptime = uv_now(env->event_loop()) - prog_start_time;
Tom Hughescf78ce52011-03-04 23:57:542295
Timothy J Fontaineb19b60a2014-05-01 20:54:232296 args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
Tom Hughescf78ce52011-03-04 23:57:542297}
Ryan Dahl3ac6dee2010-05-08 02:05:592298
Ryan Dahlc344fbc2011-10-06 21:59:382299
Anna Henningsen9d522222017-04-12 17:17:242300static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552301 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb3b3cfe2009-11-03 12:00:422302
Ryan Dahl5783a522011-10-18 21:30:312303 size_t rss;
Ben Noordhuisca9eb712013-07-18 21:18:502304 int err = uv_resident_set_memory(&rss);
2305 if (err) {
Fedor Indutny75adde02014-02-21 13:02:422306 return env->ThrowUVException(err, "uv_resident_set_memory");
Ryan Dahl3a701292009-11-03 00:30:012307 }
2308
Brian Whitef385f772017-02-22 07:03:492309 Isolate* isolate = env->isolate();
Ryan Dahl38e425d2009-11-28 15:31:292310 // V8 memory usage
2311 HeapStatistics v8_heap_stats;
Brian Whitef385f772017-02-22 07:03:492312 isolate->GetHeapStatistics(&v8_heap_stats);
Ben Noordhuis756b6222013-08-10 22:26:112313
Brian Whitef385f772017-02-22 07:03:492314 // Get the double array pointer from the Float64Array argument.
2315 CHECK(args[0]->IsFloat64Array());
2316 Local<Float64Array> array = args[0].As<Float64Array>();
2317 CHECK_EQ(array->Length(), 4);
2318 Local<ArrayBuffer> ab = array->Buffer();
2319 double* fields = static_cast<double*>(ab->GetContents().Data());
Ben Noordhuis756b6222013-08-10 22:26:112320
Brian Whitef385f772017-02-22 07:03:492321 fields[0] = rss;
2322 fields[1] = v8_heap_stats.total_heap_size();
2323 fields[2] = v8_heap_stats.used_heap_size();
2324 fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
Ryan Dahl3a701292009-11-03 00:30:012325}
Ryan Dahlb3b3cfe2009-11-03 12:00:422326
Bert Belder4a2cb072010-11-29 17:40:142327
Anna Henningsen9d522222017-04-12 17:17:242328static void Kill(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552329 Environment* env = Environment::GetCurrent(args);
Ryan Dahlb20c3432010-02-12 05:55:082330
Ryan Dahl4227e9d2010-12-21 23:40:102331 if (args.Length() != 2) {
Fedor Indutny75adde02014-02-21 13:02:422332 return env->ThrowError("Bad argument.");
Brandon Beacher334d56d2009-10-14 21:56:122333 }
Ryan Dahlb20c3432010-02-12 05:55:082334
Rasmus Christian Pedersen734fb492014-09-18 12:10:532335 int pid = args[0]->Int32Value();
Ryan Dahl6eca9482010-09-17 06:13:032336 int sig = args[1]->Int32Value();
Ben Noordhuisca9eb712013-07-18 21:18:502337 int err = uv_kill(pid, sig);
2338 args.GetReturnValue().Set(err);
Brandon Beacher334d56d2009-10-14 21:56:122339}
2340
Nathan Rajlich07c886f2012-03-05 16:51:582341// used in Hrtime() below
2342#define NANOS_PER_SEC 1000000000
2343
2344// Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2345// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
Joyee Cheunga647d822017-01-12 12:03:292346// so this function instead fills in an Uint32Array with 3 entries,
2347// to avoid any integer overflow possibility.
2348// The first two entries contain the second part of the value
2349// broken into the upper/lower 32 bits to be converted back in JS,
2350// because there is no Uint64Array in JS.
2351// The third entry contains the remaining nanosecond part of the value.
Anna Henningsen9d522222017-04-12 17:17:242352static void Hrtime(const FunctionCallbackInfo<Value>& args) {
Nathan Rajlich07c886f2012-03-05 16:51:582353 uint64_t t = uv_hrtime();
2354
Trevor Norris36e8a2c2015-11-11 07:15:152355 Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2356 uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
2357
Trevor Norris36e8a2c2015-11-11 07:15:152358 fields[0] = (t / NANOS_PER_SEC) >> 32;
2359 fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
2360 fields[2] = t % NANOS_PER_SEC;
Nathan Rajlich07c886f2012-03-05 16:51:582361}
2362
Patrick Mueller52cb4102016-04-05 13:17:482363// Microseconds in a second, as a float, used in CPUUsage() below
2364#define MICROS_PER_SEC 1e6
2365
2366// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
2367// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
2368// which are uv_timeval_t structs (long tv_sec, long tv_usec).
2369// Returns those values as Float64 microseconds in the elements of the array
2370// passed to the function.
Anna Henningsen9d522222017-04-12 17:17:242371static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
Patrick Mueller52cb4102016-04-05 13:17:482372 uv_rusage_t rusage;
2373
2374 // Call libuv to get the values we'll return.
2375 int err = uv_getrusage(&rusage);
2376 if (err) {
2377 // On error, return the strerror version of the error code.
2378 Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2379 args.GetReturnValue().Set(errmsg);
2380 return;
2381 }
2382
2383 // Get the double array pointer from the Float64Array argument.
2384 CHECK(args[0]->IsFloat64Array());
2385 Local<Float64Array> array = args[0].As<Float64Array>();
2386 CHECK_EQ(array->Length(), 2);
2387 Local<ArrayBuffer> ab = array->Buffer();
2388 double* fields = static_cast<double*>(ab->GetContents().Data());
2389
2390 // Set the Float64Array elements to be user / system values in microseconds.
2391 fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2392 fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2393}
2394
Keith M Wesolowski76b98462013-12-17 00:00:442395extern "C" void node_module_register(void* m) {
2396 struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2397
2398 if (mp->nm_flags & NM_F_BUILTIN) {
2399 mp->nm_link = modlist_builtin;
2400 modlist_builtin = mp;
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222401 } else if (!node_is_initialized) {
2402 // "Linked" modules are included as part of the node project.
2403 // Like builtins they are registered *before* node::Init runs.
2404 mp->nm_flags = NM_F_LINKED;
2405 mp->nm_link = modlist_linked;
2406 modlist_linked = mp;
Keith M Wesolowski76b98462013-12-17 00:00:442407 } else {
Keith M Wesolowski76b98462013-12-17 00:00:442408 modpending = mp;
2409 }
2410}
2411
2412struct node_module* get_builtin_module(const char* name) {
2413 struct node_module* mp;
2414
Ben Noordhuis2d82cdf2014-10-22 01:29:322415 for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) {
Keith M Wesolowski76b98462013-12-17 00:00:442416 if (strcmp(mp->nm_modname, name) == 0)
2417 break;
2418 }
2419
Ben Noordhuis2d82cdf2014-10-22 01:29:322420 CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0);
Keith M Wesolowski76b98462013-12-17 00:00:442421 return (mp);
2422}
Bert Belderdd93c532011-10-28 10:05:092423
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222424struct node_module* get_linked_module(const char* name) {
2425 struct node_module* mp;
2426
Bert Belder9483bfe2014-12-09 04:57:172427 for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222428 if (strcmp(mp->nm_modname, name) == 0)
2429 break;
2430 }
2431
Bert Belder9483bfe2014-12-09 04:57:172432 CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222433 return mp;
2434}
2435
isaacs15508582013-01-24 23:40:582436// DLOpen is process.dlopen(module, filename).
2437// Used to load 'module.node' dynamically shared objects.
Ben Noordhuis756b6222013-08-10 22:26:112438//
2439// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2440// when two contexts try to load the same shared object. Maybe have a shadow
2441// cache that's a plain C list or hash table that's shared across contexts?
Anna Henningsen9d522222017-04-12 17:17:242442static void DLOpen(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552443 Environment* env = Environment::GetCurrent(args);
Bert Belderdd93c532011-10-28 10:05:092444 uv_lib_t lib;
Ryan2b6d7242009-06-20 13:07:102445
Ben Noordhuisa60056d2014-12-11 14:29:522446 CHECK_EQ(modpending, nullptr);
2447
toastynerd9419e1f2015-01-19 18:17:452448 if (args.Length() != 2) {
Fedor Indutny75adde02014-02-21 13:02:422449 env->ThrowError("process.dlopen takes exactly 2 arguments.");
Keith M Wesolowski76b98462013-12-17 00:00:442450 return;
Bert Belderdd93c532011-10-28 10:05:092451 }
Ryana97dce72009-08-31 09:14:342452
Trevor Norrisd5533862015-01-07 21:29:582453 Local<Object> module = args[0]->ToObject(env->isolate()); // Cast
Trevor Norriscbf76c12015-01-07 22:13:352454 node::Utf8Value filename(env->isolate(), args[1]); // Cast
Ben Noordhuisa60056d2014-12-11 14:29:522455 const bool is_dlopen_error = uv_dlopen(*filename, &lib);
isaacs15508582013-01-24 23:40:582456
Ben Noordhuisa60056d2014-12-11 14:29:522457 // Objects containing v14 or later modules will have registered themselves
2458 // on the pending list. Activate all of them now. At present, only one
2459 // module per object is supported.
2460 node_module* const mp = modpending;
2461 modpending = nullptr;
Ryan2b6d7242009-06-20 13:07:102462
Ben Noordhuisa60056d2014-12-11 14:29:522463 if (is_dlopen_error) {
Ben Noordhuis756b6222013-08-10 22:26:112464 Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
Karl Skomskib48385a2015-08-14 08:12:162465 uv_dlclose(&lib);
Ben Noordhuis039fac62012-05-17 05:13:292466#ifdef _WIN32
2467 // Windows needs to add the filename into the error message
Trevor Norrisd5533862015-01-07 21:29:582468 errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
Fedor Indutny8e29ce92013-07-31 18:07:292469#endif // _WIN32
Fedor Indutny75adde02014-02-21 13:02:422470 env->isolate()->ThrowException(Exception::Error(errmsg));
Ben Noordhuis110a9cd2013-07-03 02:23:442471 return;
Ryan2b6d7242009-06-20 13:07:102472 }
2473
Ben Noordhuis2d82cdf2014-10-22 01:29:322474 if (mp == nullptr) {
Karl Skomskib48385a2015-08-14 08:12:162475 uv_dlclose(&lib);
Fedor Indutny75adde02014-02-21 13:02:422476 env->ThrowError("Module did not self-register.");
Keith M Wesolowski76b98462013-12-17 00:00:442477 return;
Paul Querna367b87d2010-07-13 08:33:512478 }
Keith M Wesolowski76b98462013-12-17 00:00:442479 if (mp->nm_version != NODE_MODULE_VERSION) {
Ben Noordhuisf6923472012-07-26 23:06:122480 char errmsg[1024];
Jason Ginchereau56e881d2017-03-20 21:55:262481 if (mp->nm_version == -1) {
2482 snprintf(errmsg,
2483 sizeof(errmsg),
2484 "The module '%s'"
2485 "\nwas compiled against the ABI-stable Node.js API (N-API)."
2486 "\nThis feature is experimental and must be enabled on the "
2487 "\ncommand-line by adding --napi-modules.",
2488 *filename);
2489 } else {
2490 snprintf(errmsg,
2491 sizeof(errmsg),
2492 "The module '%s'"
2493 "\nwas compiled against a different Node.js version using"
2494 "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
2495 "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
2496 "re-installing\nthe module (for instance, using `npm rebuild` "
2497 "or `npm install`).",
2498 *filename, mp->nm_version, NODE_MODULE_VERSION);
2499 }
Fedor Indutnya6d674d2015-09-10 11:01:202500
2501 // NOTE: `mp` is allocated inside of the shared library's memory, calling
2502 // `uv_dlclose` will deallocate it
2503 uv_dlclose(&lib);
Fedor Indutny75adde02014-02-21 13:02:422504 env->ThrowError(errmsg);
Keith M Wesolowski76b98462013-12-17 00:00:442505 return;
2506 }
2507 if (mp->nm_flags & NM_F_BUILTIN) {
Karl Skomskib48385a2015-08-14 08:12:162508 uv_dlclose(&lib);
Fedor Indutny75adde02014-02-21 13:02:422509 env->ThrowError("Built-in module self-registered.");
Keith M Wesolowski76b98462013-12-17 00:00:442510 return;
Ryan2b6d7242009-06-20 13:07:102511 }
Ryan2b6d7242009-06-20 13:07:102512
Keith M Wesolowski76b98462013-12-17 00:00:442513 mp->nm_dso_handle = lib.handle;
2514 mp->nm_link = modlist_addon;
2515 modlist_addon = mp;
2516
Ben Noordhuisa60056d2014-12-11 14:29:522517 Local<String> exports_string = env->exports_string();
Trevor Norrisd5533862015-01-07 21:29:582518 Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
Ben Noordhuisa60056d2014-12-11 14:29:522519
Ben Noordhuis2d82cdf2014-10-22 01:29:322520 if (mp->nm_context_register_func != nullptr) {
Keith M Wesolowski76b98462013-12-17 00:00:442521 mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
Ben Noordhuis2d82cdf2014-10-22 01:29:322522 } else if (mp->nm_register_func != nullptr) {
Keith M Wesolowski76b98462013-12-17 00:00:442523 mp->nm_register_func(exports, module, mp->nm_priv);
Ben Noordhuis756b6222013-08-10 22:26:112524 } else {
Karl Skomskib48385a2015-08-14 08:12:162525 uv_dlclose(&lib);
Fedor Indutny75adde02014-02-21 13:02:422526 env->ThrowError("Module has no declared entry point.");
Keith M Wesolowski76b98462013-12-17 00:00:442527 return;
Ben Noordhuis756b6222013-08-10 22:26:112528 }
Ryan2b6d7242009-06-20 13:07:102529
Peter Griess4e3c5d82010-07-12 15:47:452530 // Tell coverity that 'handle' should not be freed when we return.
2531 // coverity[leaked_storage]
Ryan2b6d7242009-06-20 13:07:102532}
2533
Tim-Smartae10a482010-03-12 08:36:002534
Ryand6c9d312009-09-11 14:02:292535static void OnFatalError(const char* location, const char* message) {
Ryan Dahl53a841d2009-12-29 19:20:512536 if (location) {
Brian White2d356072015-10-13 21:18:152537 PrintErrorString("FATAL ERROR: %s %s\n", location, message);
Ryan Dahl53a841d2009-12-29 19:20:512538 } else {
Brian White2d356072015-10-13 21:18:152539 PrintErrorString("FATAL ERROR: %s\n", message);
Ryan Dahl53a841d2009-12-29 19:20:512540 }
Ben Noordhuisc56a96c2013-06-29 05:30:112541 fflush(stderr);
Evan Lucas870229e2015-09-16 15:12:412542 ABORT();
Ryan63a9cd32009-04-15 08:08:282543}
2544
Miroslav Bajtosc16963b2013-06-17 19:19:592545
Trevor Norrisfa10b752013-06-20 23:44:022546NO_RETURN void FatalError(const char* location, const char* message) {
2547 OnFatalError(location, message);
James M Snell936c9ff2015-06-24 03:42:492548 // to suppress compiler warning
Evan Lucas870229e2015-09-16 15:12:412549 ABORT();
Trevor Norrisfa10b752013-06-20 23:44:022550}
2551
2552
Fedor Indutny75adde02014-02-21 13:02:422553void FatalException(Isolate* isolate,
Michaël Zasso4abc8962015-07-18 09:34:162554 Local<Value> error,
2555 Local<Message> message) {
Fedor Indutny75adde02014-02-21 13:02:422556 HandleScope scope(isolate);
Felix Geisendörfer2b252ac2009-11-14 22:07:542557
Fedor Indutny75adde02014-02-21 13:02:422558 Environment* env = Environment::GetCurrent(isolate);
Ben Noordhuis756b6222013-08-10 22:26:112559 Local<Object> process_object = env->process_object();
2560 Local<String> fatal_exception_string = env->fatal_exception_string();
2561 Local<Function> fatal_exception_function =
2562 process_object->Get(fatal_exception_string).As<Function>();
Ryan Dahl45a806a2009-12-09 08:02:212563
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472564 int exit_code = 0;
Ben Noordhuis756b6222013-08-10 22:26:112565 if (!fatal_exception_function->IsFunction()) {
isaacs4401bb42012-12-26 20:28:332566 // failed before the process._fatalException function was added!
2567 // this is probably pretty bad. Nothing to do but report and exit.
Fedor Indutnyf1de13b2014-02-05 16:38:332568 ReportException(env, error, message);
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472569 exit_code = 6;
Felix Geisendörfer2b252ac2009-11-14 22:07:542570 }
2571
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472572 if (exit_code == 0) {
2573 TryCatch fatal_try_catch(isolate);
isaacs07be9fc2012-05-09 22:12:132574
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472575 // Do not call FatalException when _fatalException handler throws
2576 fatal_try_catch.SetVerbose(false);
Miroslav Bajtosc16963b2013-06-17 19:19:592577
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472578 // this will return true if the JS layer handled it, false otherwise
2579 Local<Value> caught =
2580 fatal_exception_function->Call(process_object, 1, &error);
isaacs4401bb42012-12-26 20:28:332581
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472582 if (fatal_try_catch.HasCaught()) {
2583 // the fatal exception function threw, so we must exit
2584 ReportException(env, fatal_try_catch);
2585 exit_code = 7;
2586 }
2587
2588 if (exit_code == 0 && false == caught->BooleanValue()) {
2589 ReportException(env, error, message);
2590 exit_code = 1;
2591 }
isaacs4401bb42012-12-26 20:28:332592 }
2593
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472594 if (exit_code) {
2595#if HAVE_INSPECTOR
Eugene Ostroukhov7599b0e2016-12-13 01:08:312596 env->inspector_agent()->FatalException(error, message);
Aleksei Koziatinskii26cd48f2016-08-10 02:03:472597#endif
2598 exit(exit_code);
isaacs80a55e92012-04-07 02:23:162599 }
Ryane78917b2009-03-09 13:08:312600}
2601
Ryan0e9e9272009-04-04 14:53:432602
Fedor Indutny75adde02014-02-21 13:02:422603void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2604 HandleScope scope(isolate);
Fedor Indutny8e29ce92013-07-31 18:07:292605 // TODO(bajtos) do not call FatalException if try_catch is verbose
Miroslav Bajtosc16963b2013-06-17 19:19:592606 // (requires V8 API to expose getter for try_catch.is_verbose_)
Fedor Indutny75adde02014-02-21 13:02:422607 FatalException(isolate, try_catch.Exception(), try_catch.Message());
Miroslav Bajtosc16963b2013-06-17 19:19:592608}
2609
2610
Anna Henningsen9d522222017-04-12 17:17:242611static void OnMessage(Local<Message> message, Local<Value> error) {
Miroslav Bajtosc16963b2013-06-17 19:19:592612 // The current version of V8 sends messages for errors only
2613 // (thus `error` is always set).
Fedor Indutny75adde02014-02-21 13:02:422614 FatalException(Isolate::GetCurrent(), error, message);
Miroslav Bajtosc16963b2013-06-17 19:19:592615}
2616
2617
Trevor Norrisa17200b2016-03-14 18:35:222618void ClearFatalExceptionHandlers(Environment* env) {
2619 Local<Object> process = env->process_object();
2620 Local<Value> events =
2621 process->Get(env->context(), env->events_string()).ToLocalChecked();
2622
2623 if (events->IsObject()) {
2624 events.As<Object>()->Set(
2625 env->context(),
2626 OneByteString(env->isolate(), "uncaughtException"),
2627 Undefined(env->isolate())).FromJust();
2628 }
2629
2630 process->Set(
2631 env->context(),
2632 env->domain_string(),
2633 Undefined(env->isolate())).FromJust();
2634}
2635
Sam Roberts213134f2016-11-07 21:18:232636// Call process.emitWarning(str), fmt is a snprintf() format string
2637void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
2638 char warning[1024];
2639 va_list ap;
2640
2641 va_start(ap, fmt);
2642 vsnprintf(warning, sizeof(warning), fmt, ap);
2643 va_end(ap);
2644
2645 HandleScope handle_scope(env->isolate());
2646 Context::Scope context_scope(env->context());
2647
2648 Local<Object> process = env->process_object();
2649 MaybeLocal<Value> emit_warning = process->Get(env->context(),
2650 FIXED_ONE_BYTE_STRING(env->isolate(), "emitWarning"));
2651 Local<Value> arg = node::OneByteString(env->isolate(), warning);
2652
2653 Local<Value> f;
2654
2655 if (!emit_warning.ToLocal(&f)) return;
2656 if (!f->IsFunction()) return;
2657
2658 // MakeCallback() unneeded, because emitWarning is internal code, it calls
2659 // process.emit('warning', ..), but does so on the nextTick.
2660 f.As<v8::Function>()->Call(process, 1, &arg);
2661}
2662
Trevor Norrisa17200b2016-03-14 18:35:222663
Ben Noordhuis110a9cd2013-07-03 02:23:442664static void Binding(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:552665 Environment* env = Environment::GetCurrent(args);
Ryan Dahl627fb5a2010-03-15 20:48:032666
Trevor Norrisd5533862015-01-07 21:29:582667 Local<String> module = args[0]->ToString(env->isolate());
Trevor Norriscbf76c12015-01-07 22:13:352668 node::Utf8Value module_v(env->isolate(), module);
Ryan Dahl627fb5a2010-03-15 20:48:032669
Ben Noordhuis756b6222013-08-10 22:26:112670 Local<Object> cache = env->binding_cache_object();
Ryan Dahl627fb5a2010-03-15 20:48:032671 Local<Object> exports;
2672
Michaël Zassoa7292082016-02-08 21:54:002673 if (cache->Has(env->context(), module).FromJust()) {
Trevor Norrisd5533862015-01-07 21:29:582674 exports = cache->Get(module)->ToObject(env->isolate());
Ben Noordhuis110a9cd2013-07-03 02:23:442675 args.GetReturnValue().Set(exports);
2676 return;
Ryan Dahlea9ee1f2011-07-28 02:30:322677 }
Ryan Dahl6eca9482010-09-17 06:13:032678
Ryan Dahlea9ee1f2011-07-28 02:30:322679 // Append a string to process.moduleLoadList
2680 char buf[1024];
Fedor Indutny8e29ce92013-07-31 18:07:292681 snprintf(buf, sizeof(buf), "Binding %s", *module_v);
Ben Noordhuis110a9cd2013-07-03 02:23:442682
Ben Noordhuis756b6222013-08-10 22:26:112683 Local<Array> modules = env->module_load_list_array();
Ben Noordhuis110a9cd2013-07-03 02:23:442684 uint32_t l = modules->Length();
Fedor Indutny75adde02014-02-21 13:02:422685 modules->Set(l, OneByteString(env->isolate(), buf));
Ryan Dahlea9ee1f2011-07-28 02:30:322686
Keith M Wesolowski76b98462013-12-17 00:00:442687 node_module* mod = get_builtin_module(*module_v);
Ben Noordhuis2d82cdf2014-10-22 01:29:322688 if (mod != nullptr) {
Fedor Indutnyce04c722014-03-13 16:38:142689 exports = Object::New(env->isolate());
Ben Noordhuis756b6222013-08-10 22:26:112690 // Internal bindings don't have a "module" object, only exports.
Ben Noordhuis2d82cdf2014-10-22 01:29:322691 CHECK_EQ(mod->nm_register_func, nullptr);
2692 CHECK_NE(mod->nm_context_register_func, nullptr);
Ben Noordhuis756b6222013-08-10 22:26:112693 Local<Value> unused = Undefined(env->isolate());
Keith M Wesolowski76b98462013-12-17 00:00:442694 mod->nm_context_register_func(exports, unused,
2695 env->context(), mod->nm_priv);
Ben Noordhuis110a9cd2013-07-03 02:23:442696 cache->Set(module, exports);
Ryan Dahl6eca9482010-09-17 06:13:032697 } else if (!strcmp(*module_v, "constants")) {
Fedor Indutnyce04c722014-03-13 16:38:142698 exports = Object::New(env->isolate());
Sakthipriyan Vairamani (thefourtheye)caf9ae72016-12-26 11:12:092699 CHECK(exports->SetPrototype(env->context(),
2700 Null(env->isolate())).FromJust());
James M Snelldcccbfd2016-05-02 17:27:122701 DefineConstants(env->isolate(), exports);
Ben Noordhuis110a9cd2013-07-03 02:23:442702 cache->Set(module, exports);
Ryan Dahlc90546f2010-03-15 21:22:502703 } else if (!strcmp(*module_v, "natives")) {
Fedor Indutnyce04c722014-03-13 16:38:142704 exports = Object::New(env->isolate());
Fedor Indutny75adde02014-02-21 13:02:422705 DefineJavaScript(env, exports);
Ben Noordhuis110a9cd2013-07-03 02:23:442706 cache->Set(module, exports);
Ryan Dahl627fb5a2010-03-15 20:48:032707 } else {
Jackson Tian962e6512014-08-01 11:26:092708 char errmsg[1024];
2709 snprintf(errmsg,
2710 sizeof(errmsg),
2711 "No such module: %s",
2712 *module_v);
2713 return env->ThrowError(errmsg);
Ryan Dahl627fb5a2010-03-15 20:48:032714 }
2715
Ben Noordhuis110a9cd2013-07-03 02:23:442716 args.GetReturnValue().Set(exports);
Ryan Dahl627fb5a2010-03-15 20:48:032717}
2718
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222719static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2720 Environment* env = Environment::GetCurrent(args.GetIsolate());
2721
Phillip Kovalev71470a82016-01-19 21:52:162722 Local<String> module_name = args[0]->ToString(env->isolate());
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222723
2724 Local<Object> cache = env->binding_cache_object();
Phillip Kovalev71470a82016-01-19 21:52:162725 Local<Value> exports_v = cache->Get(module_name);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222726
2727 if (exports_v->IsObject())
2728 return args.GetReturnValue().Set(exports_v.As<Object>());
2729
Phillip Kovalev71470a82016-01-19 21:52:162730 node::Utf8Value module_name_v(env->isolate(), module_name);
2731 node_module* mod = get_linked_module(*module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222732
Bert Belder9483bfe2014-12-09 04:57:172733 if (mod == nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222734 char errmsg[1024];
2735 snprintf(errmsg,
2736 sizeof(errmsg),
2737 "No such module was linked: %s",
Phillip Kovalev71470a82016-01-19 21:52:162738 *module_name_v);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222739 return env->ThrowError(errmsg);
2740 }
2741
Phillip Kovalev71470a82016-01-19 21:52:162742 Local<Object> module = Object::New(env->isolate());
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222743 Local<Object> exports = Object::New(env->isolate());
Phillip Kovalev71470a82016-01-19 21:52:162744 Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
2745 module->Set(exports_prop, exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222746
Bert Belder9483bfe2014-12-09 04:57:172747 if (mod->nm_context_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222748 mod->nm_context_register_func(exports,
2749 module,
2750 env->context(),
2751 mod->nm_priv);
Bert Belder9483bfe2014-12-09 04:57:172752 } else if (mod->nm_register_func != nullptr) {
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222753 mod->nm_register_func(exports, module, mod->nm_priv);
2754 } else {
2755 return env->ThrowError("Linked module has no declared entry point.");
2756 }
2757
Phillip Kovalev5c14efb2016-02-20 08:30:432758 auto effective_exports = module->Get(exports_prop);
2759 cache->Set(module_name, effective_exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222760
Phillip Kovalev5c14efb2016-02-20 08:30:432761 args.GetReturnValue().Set(effective_exports);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:222762}
Ryan Dahle742d072009-10-09 11:25:042763
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262764static void ProcessTitleGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442765 const PropertyCallbackInfo<Value>& info) {
Igor Zinkovsky500c8f42011-12-15 20:36:052766 char buffer[512];
2767 uv_get_process_title(buffer, sizeof(buffer));
Ben Noordhuis2e5b87a2015-03-22 23:38:422768 info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
Ryan Dahl5185c152010-06-18 07:26:492769}
2770
2771
Ali Ijaz Sheikhc1649a72016-02-12 08:58:262772static void ProcessTitleSetter(Local<Name> property,
Ryan Dahl5185c152010-06-18 07:26:492773 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:442774 const PropertyCallbackInfo<void>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422775 node::Utf8Value title(info.GetIsolate(), value);
Fedor Indutny8e29ce92013-07-31 18:07:292776 // TODO(piscisaureus): protect with a lock
Igor Zinkovsky500c8f42011-12-15 20:36:052777 uv_set_process_title(*title);
Ryan Dahl5185c152010-06-18 07:26:492778}
2779
2780
AnnaMagab194122016-10-06 20:50:412781static void EnvGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442782 const PropertyCallbackInfo<Value>& info) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422783 Isolate* isolate = info.GetIsolate();
Anna Henningsen3295a7f2016-11-16 01:27:142784 if (property->IsSymbol()) {
2785 return info.GetReturnValue().SetUndefined();
2786 }
Bert Belder077f9d72012-02-15 22:34:182787#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422788 node::Utf8Value key(isolate, property);
Ben Noordhuisb4def482010-10-15 13:48:342789 const char* val = getenv(*key);
2790 if (val) {
Ben Noordhuis2e5b87a2015-03-22 23:38:422791 return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
Ben Noordhuisb4def482010-10-15 13:48:342792 }
Bert Belder077f9d72012-02-15 22:34:182793#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542794 node::TwoByteValue key(isolate, property);
Fedor Indutny8e29ce92013-07-31 18:07:292795 WCHAR buffer[32767]; // The maximum size allowed for environment variables.
Bert Belder077f9d72012-02-15 22:34:182796 DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2797 buffer,
Ben Noordhuisa7581d02016-03-31 10:47:062798 arraysize(buffer));
Bert Belder077f9d72012-02-15 22:34:182799 // If result >= sizeof buffer the buffer was too small. That should never
2800 // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2801 // not found.
2802 if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
Ben Noordhuisa7581d02016-03-31 10:47:062803 result < arraysize(buffer)) {
Ben Noordhuisf674b092013-08-07 19:50:412804 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
Ben Noordhuis2e5b87a2015-03-22 23:38:422805 Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
Ben Noordhuisf674b092013-08-07 19:50:412806 return info.GetReturnValue().Set(rc);
Bert Belder077f9d72012-02-15 22:34:182807 }
2808#endif
Ben Noordhuisb4def482010-10-15 13:48:342809}
2810
2811
AnnaMagab194122016-10-06 20:50:412812static void EnvSetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442813 Local<Value> value,
2814 const PropertyCallbackInfo<Value>& info) {
Bert Belder077f9d72012-02-15 22:34:182815#ifdef __POSIX__
Ben Noordhuis2e5b87a2015-03-22 23:38:422816 node::Utf8Value key(info.GetIsolate(), property);
2817 node::Utf8Value val(info.GetIsolate(), value);
Ben Noordhuisb4def482010-10-15 13:48:342818 setenv(*key, *val, 1);
Bert Belder077f9d72012-02-15 22:34:182819#else // _WIN32
cjihrig1aa595e2016-11-03 16:16:542820 node::TwoByteValue key(info.GetIsolate(), property);
2821 node::TwoByteValue val(info.GetIsolate(), value);
Bert Belder077f9d72012-02-15 22:34:182822 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2823 // Environment variables that start with '=' are read-only.
2824 if (key_ptr[0] != L'=') {
2825 SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
Ryan Dahle6b06bc2011-08-11 00:14:232826 }
Bert Belder30bab522010-11-25 00:09:062827#endif
Miguel Angel Asencio Hurtado88323e82016-10-11 08:19:162828 // Whether it worked or not, always return value.
Ben Noordhuis110a9cd2013-07-03 02:23:442829 info.GetReturnValue().Set(value);
Ben Noordhuisb4def482010-10-15 13:48:342830}
2831
2832
AnnaMagab194122016-10-06 20:50:412833static void EnvQuery(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442834 const PropertyCallbackInfo<Integer>& info) {
Ben Noordhuis110a9cd2013-07-03 02:23:442835 int32_t rc = -1; // Not found unless proven otherwise.
Timothy Gue2f151f2017-03-06 06:45:192836 if (property->IsString()) {
Bert Belder077f9d72012-02-15 22:34:182837#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192838 node::Utf8Value key(info.GetIsolate(), property);
2839 if (getenv(*key))
2840 rc = 0;
Bert Belder077f9d72012-02-15 22:34:182841#else // _WIN32
Timothy Gue2f151f2017-03-06 06:45:192842 node::TwoByteValue key(info.GetIsolate(), property);
2843 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2844 if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2845 GetLastError() == ERROR_SUCCESS) {
2846 rc = 0;
2847 if (key_ptr[0] == L'=') {
2848 // Environment variables that start with '=' are hidden and read-only.
2849 rc = static_cast<int32_t>(v8::ReadOnly) |
2850 static_cast<int32_t>(v8::DontDelete) |
2851 static_cast<int32_t>(v8::DontEnum);
2852 }
Bert Belder077f9d72012-02-15 22:34:182853 }
Bert Belder077f9d72012-02-15 22:34:182854#endif
Timothy Gue2f151f2017-03-06 06:45:192855 }
Fedor Indutny2bc30f22013-10-16 16:57:262856 if (rc != -1)
2857 info.GetReturnValue().Set(rc);
Ben Noordhuisb4def482010-10-15 13:48:342858}
2859
2860
AnnaMagab194122016-10-06 20:50:412861static void EnvDeleter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:442862 const PropertyCallbackInfo<Boolean>& info) {
Timothy Gue2f151f2017-03-06 06:45:192863 if (property->IsString()) {
Bert Belder30bab522010-11-25 00:09:062864#ifdef __POSIX__
Timothy Gue2f151f2017-03-06 06:45:192865 node::Utf8Value key(info.GetIsolate(), property);
2866 unsetenv(*key);
Bert Belder30bab522010-11-25 00:09:062867#else
Timothy Gue2f151f2017-03-06 06:45:192868 node::TwoByteValue key(info.GetIsolate(), property);
2869 WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2870 SetEnvironmentVariableW(key_ptr, nullptr);
Bert Belder077f9d72012-02-15 22:34:182871#endif
Timothy Gue2f151f2017-03-06 06:45:192872 }
Franziska Hinkelmannff7a8412016-08-04 07:36:502873
2874 // process.env never has non-configurable properties, so always
2875 // return true like the tc39 delete operator.
2876 info.GetReturnValue().Set(true);
Ben Noordhuisb4def482010-10-15 13:48:342877}
2878
2879
Ben Noordhuis110a9cd2013-07-03 02:23:442880static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
Trevor Norris56985ca2015-11-11 19:28:412881 Environment* env = Environment::GetCurrent(info);
2882 Isolate* isolate = env->isolate();
2883 Local<Context> ctx = env->context();
2884 Local<Function> fn = env->push_values_to_array_function();
2885 Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2886 size_t idx = 0;
2887
Bert Belder077f9d72012-02-15 22:34:182888#ifdef __POSIX__
Ben Noordhuisb4def482010-10-15 13:48:342889 int size = 0;
Fedor Indutny2bc30f22013-10-16 16:57:262890 while (environ[size])
2891 size++;
Ben Noordhuisb4def482010-10-15 13:48:342892
Trevor Norris56985ca2015-11-11 19:28:412893 Local<Array> envarr = Array::New(isolate);
Ben Noordhuisb4def482010-10-15 13:48:342894
2895 for (int i = 0; i < size; ++i) {
2896 const char* var = environ[i];
2897 const char* s = strchr(var, '=');
2898 const int length = s ? s - var : strlen(var);
Trevor Norris56985ca2015-11-11 19:28:412899 argv[idx] = String::NewFromUtf8(isolate,
2900 var,
2901 String::kNormalString,
2902 length);
Ben Noordhuisa7581d02016-03-31 10:47:062903 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412904 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2905 idx = 0;
2906 }
2907 }
2908 if (idx > 0) {
2909 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
Ben Noordhuisb4def482010-10-15 13:48:342910 }
Bert Belder077f9d72012-02-15 22:34:182911#else // _WIN32
2912 WCHAR* environment = GetEnvironmentStringsW();
Ben Noordhuis2d82cdf2014-10-22 01:29:322913 if (environment == nullptr)
Fedor Indutny2bc30f22013-10-16 16:57:262914 return; // This should not happen.
Ben Noordhuis2e5b87a2015-03-22 23:38:422915 Local<Array> envarr = Array::New(isolate);
Bert Belder077f9d72012-02-15 22:34:182916 WCHAR* p = environment;
Nikolai Vavilovb105f6f2014-10-24 22:36:592917 while (*p) {
Bert Belder077f9d72012-02-15 22:34:182918 WCHAR *s;
2919 if (*p == L'=') {
2920 // If the key starts with '=' it is a hidden environment variable.
2921 p += wcslen(p) + 1;
2922 continue;
2923 } else {
2924 s = wcschr(p, L'=');
2925 }
2926 if (!s) {
2927 s = p + wcslen(p);
2928 }
Ben Noordhuisf674b092013-08-07 19:50:412929 const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
Ben Noordhuis78f709d2013-08-09 15:43:102930 const size_t two_byte_buffer_len = s - p;
Trevor Norris56985ca2015-11-11 19:28:412931 argv[idx] = String::NewFromTwoByte(isolate,
2932 two_byte_buffer,
2933 String::kNormalString,
2934 two_byte_buffer_len);
Ben Noordhuisa7581d02016-03-31 10:47:062935 if (++idx >= arraysize(argv)) {
Trevor Norris56985ca2015-11-11 19:28:412936 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2937 idx = 0;
2938 }
Bert Belder077f9d72012-02-15 22:34:182939 p = s + wcslen(s) + 1;
2940 }
Trevor Norris56985ca2015-11-11 19:28:412941 if (idx > 0) {
2942 fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2943 }
Bert Belder077f9d72012-02-15 22:34:182944 FreeEnvironmentStringsW(environment);
2945#endif
Ben Noordhuis110a9cd2013-07-03 02:23:442946
Fedor Indutny75adde02014-02-21 13:02:422947 info.GetReturnValue().Set(envarr);
Ben Noordhuisb4def482010-10-15 13:48:342948}
2949
2950
Michaël Zasso4abc8962015-07-18 09:34:162951static Local<Object> GetFeatures(Environment* env) {
Fedor Indutnyce04c722014-03-13 16:38:142952 EscapableHandleScope scope(env->isolate());
Ben Noordhuisaa0308d2011-07-23 21:16:482953
Fedor Indutnyce04c722014-03-13 16:38:142954 Local<Object> obj = Object::New(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352955#if defined(DEBUG) && DEBUG
Fedor Indutny75adde02014-02-21 13:02:422956 Local<Value> debug = True(env->isolate());
Ryan Dahl52a40e02011-08-24 21:16:352957#else
Fedor Indutny75adde02014-02-21 13:02:422958 Local<Value> debug = False(env->isolate());
Fedor Indutny8e29ce92013-07-31 18:07:292959#endif // defined(DEBUG) && DEBUG
2960
Ben Noordhuisb4ea3a02016-08-21 10:31:202961 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
2962 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
Fedor Indutny8e29ce92013-07-31 18:07:292963 // TODO(bnoordhuis) ping libuv
Ben Noordhuisb4ea3a02016-08-21 10:31:202964 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
Ben Noordhuisf674b092013-08-07 19:50:412965
Shigeki Ohtsu02c98f42017-03-02 14:13:192966#ifndef OPENSSL_NO_NEXTPROTONEG
Fedor Indutny75adde02014-02-21 13:02:422967 Local<Boolean> tls_npn = True(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452968#else
Fedor Indutny75adde02014-02-21 13:02:422969 Local<Boolean> tls_npn = False(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452970#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202971 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
Ben Noordhuis8d567f42013-08-27 14:14:452972
Shigeki Ohtsu802a2e72015-04-23 06:25:152973#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2974 Local<Boolean> tls_alpn = True(env->isolate());
2975#else
2976 Local<Boolean> tls_alpn = False(env->isolate());
2977#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202978 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn);
Shigeki Ohtsu802a2e72015-04-23 06:25:152979
Ben Noordhuis8d567f42013-08-27 14:14:452980#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
Fedor Indutny75adde02014-02-21 13:02:422981 Local<Boolean> tls_sni = True(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452982#else
Fedor Indutny75adde02014-02-21 13:02:422983 Local<Boolean> tls_sni = False(env->isolate());
Ben Noordhuis8d567f42013-08-27 14:14:452984#endif
Ben Noordhuisb4ea3a02016-08-21 10:31:202985 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni);
Ben Noordhuis8d567f42013-08-27 14:14:452986
Fedor Indutnyb3ef2892014-04-14 17:15:572987#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2988 Local<Boolean> tls_ocsp = True(env->isolate());
2989#else
2990 Local<Boolean> tls_ocsp = False(env->isolate());
2991#endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
Ben Noordhuisb4ea3a02016-08-21 10:31:202992 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp);
Fedor Indutnyb3ef2892014-04-14 17:15:572993
Ben Noordhuisb4ea3a02016-08-21 10:31:202994 obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"),
Ben Noordhuis2d82cdf2014-10-22 01:29:322995 Boolean::New(env->isolate(),
2996 get_builtin_module("crypto") != nullptr));
Ben Noordhuisaa0308d2011-07-23 21:16:482997
Fedor Indutnyce04c722014-03-13 16:38:142998 return scope.Escape(obj);
Ben Noordhuisaa0308d2011-07-23 21:16:482999}
3000
3001
Ali Ijaz Sheikhc1649a72016-02-12 08:58:263002static void DebugPortGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:443003 const PropertyCallbackInfo<Value>& info) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223004 info.GetReturnValue().Set(debug_options.port());
Fedor Indutny3f43b1c2012-02-12 15:53:433005}
3006
3007
Ali Ijaz Sheikhc1649a72016-02-12 08:58:263008static void DebugPortSetter(Local<Name> property,
Fedor Indutny3f43b1c2012-02-12 15:53:433009 Local<Value> value,
Ben Noordhuis110a9cd2013-07-03 02:23:443010 const PropertyCallbackInfo<void>& info) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223011 debug_options.set_port(value->Int32Value());
Fedor Indutny3f43b1c2012-02-12 15:53:433012}
3013
3014
Ben Noordhuis110a9cd2013-07-03 02:23:443015static void DebugProcess(const FunctionCallbackInfo<Value>& args);
3016static void DebugPause(const FunctionCallbackInfo<Value>& args);
3017static void DebugEnd(const FunctionCallbackInfo<Value>& args);
Bert Belder829735e2011-11-04 15:23:023018
Anna Henningsen9d522222017-04-12 17:17:243019namespace {
Shigeki Ohtsucd372512013-02-06 02:13:023020
Ali Ijaz Sheikhc1649a72016-02-12 08:58:263021void NeedImmediateCallbackGetter(Local<Name> property,
Ben Noordhuis110a9cd2013-07-03 02:23:443022 const PropertyCallbackInfo<Value>& info) {
Ben Noordhuis7e88a932015-03-22 23:26:593023 Environment* env = Environment::GetCurrent(info);
Ben Noordhuis756b6222013-08-10 22:26:113024 const uv_check_t* immediate_check_handle = env->immediate_check_handle();
3025 bool active = uv_is_active(
3026 reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
3027 info.GetReturnValue().Set(active);
Shigeki Ohtsucd372512013-02-06 02:13:023028}
3029
3030
Anna Henningsen9d522222017-04-12 17:17:243031void NeedImmediateCallbackSetter(
Ali Ijaz Sheikhc1649a72016-02-12 08:58:263032 Local<Name> property,
Ben Noordhuis756b6222013-08-10 22:26:113033 Local<Value> value,
3034 const PropertyCallbackInfo<void>& info) {
Ben Noordhuis7e88a932015-03-22 23:26:593035 Environment* env = Environment::GetCurrent(info);
Shigeki Ohtsucd372512013-02-06 02:13:023036
Ben Noordhuis756b6222013-08-10 22:26:113037 uv_check_t* immediate_check_handle = env->immediate_check_handle();
3038 bool active = uv_is_active(
3039 reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
Shigeki Ohtsucd372512013-02-06 02:13:023040
Ben Noordhuis756b6222013-08-10 22:26:113041 if (active == value->BooleanValue())
3042 return;
Shigeki Ohtsucd372512013-02-06 02:13:023043
Ben Noordhuis756b6222013-08-10 22:26:113044 uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
Shigeki Ohtsucd372512013-02-06 02:13:023045
Ben Noordhuis756b6222013-08-10 22:26:113046 if (active) {
3047 uv_check_stop(immediate_check_handle);
3048 uv_idle_stop(immediate_idle_handle);
Shigeki Ohtsucd372512013-02-06 02:13:023049 } else {
Ben Noordhuis756b6222013-08-10 22:26:113050 uv_check_start(immediate_check_handle, CheckImmediate);
3051 // Idle handle is needed only to stop the event loop from blocking in poll.
3052 uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
Shigeki Ohtsucd372512013-02-06 02:13:023053 }
3054}
3055
3056
Ben Noordhuisf6496262013-10-03 09:03:463057void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553058 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:423059 env->StartProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:463060}
3061
3062
3063void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553064 Environment* env = Environment::GetCurrent(args);
Ben Noordhuis58cec4e2016-06-01 08:54:423065 env->StopProfilerIdleNotifier();
Ben Noordhuisf6496262013-10-03 09:03:463066}
3067
3068
Trevor Norrisc80f8fa2013-08-01 21:53:523069#define READONLY_PROPERTY(obj, str, var) \
3070 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:383071 obj->DefineOwnProperty(env->context(), \
3072 OneByteString(env->isolate(), str), \
3073 var, \
3074 v8::ReadOnly).FromJust(); \
Trevor Norrisc80f8fa2013-08-01 21:53:523075 } while (0)
3076
Petka Antonov872702d2015-02-22 12:44:123077#define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \
3078 do { \
Michaël Zasso67b5a8a2016-02-08 21:05:383079 obj->DefineOwnProperty(env->context(), \
3080 OneByteString(env->isolate(), str), \
3081 var, \
3082 static_cast<v8::PropertyAttribute>(v8::ReadOnly | \
3083 v8::DontEnum)) \
3084 .FromJust(); \
Petka Antonov872702d2015-02-22 12:44:123085 } while (0)
3086
Anna Henningsen9d522222017-04-12 17:17:243087} // anonymous namespace
Trevor Norrisc80f8fa2013-08-01 21:53:523088
Ben Noordhuis756b6222013-08-10 22:26:113089void SetupProcessObject(Environment* env,
3090 int argc,
3091 const char* const* argv,
3092 int exec_argc,
3093 const char* const* exec_argv) {
Fedor Indutny75adde02014-02-21 13:02:423094 HandleScope scope(env->isolate());
Ryan Dahlcd1ec272011-01-02 09:44:423095
Ben Noordhuis756b6222013-08-10 22:26:113096 Local<Object> process = env->process_object();
Ben Noordhuis74a82152012-02-03 15:32:003097
Ben Noordhuisb4ea3a02016-08-21 10:31:203098 auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
3099 CHECK(process->SetAccessor(env->context(),
3100 title_string,
3101 ProcessTitleGetter,
3102 ProcessTitleSetter,
3103 env->as_external()).FromJust());
Ryan Dahl5185c152010-06-18 07:26:493104
Ryan Dahlf4811832009-11-02 23:21:003105 // process.version
Ben Noordhuisf674b092013-08-07 19:50:413106 READONLY_PROPERTY(process,
3107 "version",
Fedor Indutny75adde02014-02-21 13:02:423108 FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
Ryan Dahl39b432e2010-08-17 18:24:103109
Ryan Dahlea9ee1f2011-07-28 02:30:323110 // process.moduleLoadList
Ben Noordhuis756b6222013-08-10 22:26:113111 READONLY_PROPERTY(process,
3112 "moduleLoadList",
3113 env->module_load_list_array());
Ryan Dahlea9ee1f2011-07-28 02:30:323114
Nathan Rajlich35043ad2012-03-13 23:04:173115 // process.versions
Fedor Indutnyce04c722014-03-13 16:38:143116 Local<Object> versions = Object::New(env->isolate());
Trevor Norrisc80f8fa2013-08-01 21:53:523117 READONLY_PROPERTY(process, "versions", versions);
Ben Noordhuisf674b092013-08-07 19:50:413118
3119 const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3120 "."
Johan Bergströmc0a9d1b2015-01-26 23:08:443121 NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
3122 "."
3123 NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
Ben Noordhuisf674b092013-08-07 19:50:413124 READONLY_PROPERTY(versions,
3125 "http_parser",
Fedor Indutny75adde02014-02-21 13:02:423126 FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
Ben Noordhuisf674b092013-08-07 19:50:413127
Ryan Dahl39b432e2010-08-17 18:24:103128 // +1 to get rid of the leading 'v'
Ben Noordhuisf674b092013-08-07 19:50:413129 READONLY_PROPERTY(versions,
3130 "node",
Fedor Indutny75adde02014-02-21 13:02:423131 OneByteString(env->isolate(), NODE_VERSION + 1));
Ben Noordhuisf674b092013-08-07 19:50:413132 READONLY_PROPERTY(versions,
3133 "v8",
Fedor Indutny75adde02014-02-21 13:02:423134 OneByteString(env->isolate(), V8::GetVersion()));
Ben Noordhuisf674b092013-08-07 19:50:413135 READONLY_PROPERTY(versions,
3136 "uv",
Fedor Indutny75adde02014-02-21 13:02:423137 OneByteString(env->isolate(), uv_version_string()));
Ben Noordhuisf674b092013-08-07 19:50:413138 READONLY_PROPERTY(versions,
3139 "zlib",
Fedor Indutny75adde02014-02-21 13:02:423140 FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
Johan Bergström01736dd2015-01-14 00:12:053141 READONLY_PROPERTY(versions,
3142 "ares",
3143 FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
Ben Noordhuisf674b092013-08-07 19:50:413144
Ben Noordhuisf674b092013-08-07 19:50:413145 const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
Fedor Indutny75adde02014-02-21 13:02:423146 READONLY_PROPERTY(
3147 versions,
3148 "modules",
3149 FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
Ben Noordhuisf674b092013-08-07 19:50:413150
Petka Antonov872702d2015-02-22 12:44:123151 // process._promiseRejectEvent
3152 Local<Object> promiseRejectEvent = Object::New(env->isolate());
3153 READONLY_DONT_ENUM_PROPERTY(process,
3154 "_promiseRejectEvent",
3155 promiseRejectEvent);
3156 READONLY_PROPERTY(promiseRejectEvent,
3157 "unhandled",
3158 Integer::New(env->isolate(),
3159 v8::kPromiseRejectWithNoHandler));
3160 READONLY_PROPERTY(promiseRejectEvent,
3161 "handled",
3162 Integer::New(env->isolate(),
3163 v8::kPromiseHandlerAddedAfterReject));
3164
Peter Bright13d6a1f2011-08-06 04:23:253165#if HAVE_OPENSSL
Ryan Dahlcd1ec272011-01-02 09:44:423166 // Stupid code to slice out the version string.
Ben Noordhuis7acdabb2013-11-04 21:42:483167 { // NOLINT(whitespace/braces)
Ben Noordhuis962686b2013-11-03 20:00:373168 size_t i, j, k;
3169 int c;
3170 for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3171 c = OPENSSL_VERSION_TEXT[i];
3172 if ('0' <= c && c <= '9') {
3173 for (j = i + 1; j < k; ++j) {
3174 c = OPENSSL_VERSION_TEXT[j];
3175 if (c == ' ')
3176 break;
3177 }
3178 break;
Ryan Dahlcd1ec272011-01-02 09:44:423179 }
Ryan Dahlcd1ec272011-01-02 09:44:423180 }
Ben Noordhuis962686b2013-11-03 20:00:373181 READONLY_PROPERTY(
3182 versions,
3183 "openssl",
Fedor Indutny75adde02014-02-21 13:02:423184 OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
Ryan Dahlcd1ec272011-01-02 09:44:423185 }
Ryan Dahlcd1ec272011-01-02 09:44:423186#endif
Ryan Dahl39b432e2010-08-17 18:24:103187
Nathan Rajlichb1be5402011-04-26 03:24:513188 // process.arch
Bert Beldere1fe2702015-01-08 12:05:513189 READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
Nathan Rajlichb1be5402011-04-26 03:24:513190
Ryan Dahlf4811832009-11-02 23:21:003191 // process.platform
Vladimir Kurchatkin9f457992015-01-09 12:38:093192 READONLY_PROPERTY(process,
3193 "platform",
3194 OneByteString(env->isolate(), NODE_PLATFORM));
Ryan Dahlf4811832009-11-02 23:21:003195
Rod Vagg04fd4fa2015-01-18 06:41:373196 // process.release
3197 Local<Object> release = Object::New(env->isolate());
3198 READONLY_PROPERTY(process, "release", release);
cjihrig4f50d3f2015-08-21 01:45:383199 READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node"));
Rod Vagg04fd4fa2015-01-18 06:41:373200
3201// if this is a release build and no explicit base has been set
3202// substitute the standard release download URL
3203#ifndef NODE_RELEASE_URLBASE
3204# if NODE_VERSION_IS_RELEASE
cjihriga69ab272015-08-13 16:14:343205# define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
Rod Vagg04fd4fa2015-01-18 06:41:373206# endif
3207#endif
3208
3209#if defined(NODE_RELEASE_URLBASE)
Rod Vagg278a9262015-09-05 04:41:343210# define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
3211# define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
Rod Vagg04fd4fa2015-01-18 06:41:373212
3213 READONLY_PROPERTY(release,
3214 "sourceUrl",
3215 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343216 NODE_RELEASE_URLFPFX ".tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:373217 READONLY_PROPERTY(release,
3218 "headersUrl",
3219 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343220 NODE_RELEASE_URLFPFX "-headers.tar.gz"));
Rod Vagg04fd4fa2015-01-18 06:41:373221# ifdef _WIN32
3222 READONLY_PROPERTY(release,
3223 "libUrl",
3224 OneByteString(env->isolate(),
Rod Vagg278a9262015-09-05 04:41:343225 strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
3226 NODE_ARCH "/node.lib"
3227 : NODE_RELEASE_URLPFX
3228 "win-x86/node.lib"));
Rod Vagg04fd4fa2015-01-18 06:41:373229# endif
3230#endif
3231
Ryan Dahlf3ad6352010-02-03 20:19:083232 // process.argv
Fedor Indutnyce04c722014-03-13 16:38:143233 Local<Array> arguments = Array::New(env->isolate(), argc);
Ben Noordhuis185c5152013-09-02 14:42:013234 for (int i = 0; i < argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:423235 arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
Ryan27b268b2009-06-17 13:05:443236 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203237 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
Ryan27b268b2009-06-17 13:05:443238
Micheil Smith19fd5302012-03-05 17:53:153239 // process.execArgv
Fedor Indutnyce04c722014-03-13 16:38:143240 Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
Ben Noordhuis185c5152013-09-02 14:42:013241 for (int i = 0; i < exec_argc; ++i) {
Fedor Indutny75adde02014-02-21 13:02:423242 exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
Micheil Smith19fd5302012-03-05 17:53:153243 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203244 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
3245 exec_arguments);
Micheil Smith19fd5302012-03-05 17:53:153246
Ryan Dahlf3ad6352010-02-03 20:19:083247 // create process.env
Fedor Indutnyce04c722014-03-13 16:38:143248 Local<ObjectTemplate> process_env_template =
3249 ObjectTemplate::New(env->isolate());
AnnaMagab194122016-10-06 20:50:413250 process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3251 EnvGetter,
3252 EnvSetter,
3253 EnvQuery,
3254 EnvDeleter,
3255 EnvEnumerator,
cjihrig1aa595e2016-11-03 16:16:543256 env->as_external()));
AnnaMagab194122016-10-06 20:50:413257
Michaël Zassoad0ce572016-01-26 08:41:293258 Local<Object> process_env =
3259 process_env_template->NewInstance(env->context()).ToLocalChecked();
Ben Noordhuis63c47e72016-10-20 20:36:173260 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
Ryan Dahlf3ad6352010-02-03 20:19:083261
Fedor Indutnyce04c722014-03-13 16:38:143262 READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
Fedor Indutny75adde02014-02-21 13:02:423263 READONLY_PROPERTY(process, "features", GetFeatures(env));
Ben Noordhuisb4ea3a02016-08-21 10:31:203264
3265 auto need_immediate_callback_string =
3266 FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback");
3267 CHECK(process->SetAccessor(env->context(), need_immediate_callback_string,
3268 NeedImmediateCallbackGetter,
3269 NeedImmediateCallbackSetter,
3270 env->as_external()).FromJust());
Ryandc39e822009-09-10 12:07:353271
TJ Holowaychuk9481bc12010-10-07 02:05:013272 // -e, --eval
Evan Lucas5b6f5752015-06-01 14:15:103273 if (eval_string) {
Ben Noordhuisf674b092013-08-07 19:50:413274 READONLY_PROPERTY(process,
3275 "_eval",
Evan Lucas5b6f5752015-06-01 14:15:103276 String::NewFromUtf8(env->isolate(), eval_string));
Nathan Rajlichef3a8742012-04-24 08:24:133277 }
3278
3279 // -p, --print
Evan Lucas5b6f5752015-06-01 14:15:103280 if (print_eval) {
Fedor Indutny75adde02014-02-21 13:02:423281 READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
TJ Holowaychuk9481bc12010-10-07 02:05:013282 }
3283
Dave Eddy2e6ece42015-08-17 21:33:133284 // -c, --check
3285 if (syntax_check_only) {
3286 READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
3287 }
3288
Nathan Rajlich6292df62012-04-24 08:32:333289 // -i, --interactive
Evan Lucas5b6f5752015-06-01 14:15:103290 if (force_repl) {
Fedor Indutny75adde02014-02-21 13:02:423291 READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
Nathan Rajlichfeaa8a42012-03-21 07:05:253292 }
3293
Sam Robertse505c072017-04-05 21:04:443294 // -r, --require
Sam Robertscecdf7c2017-04-05 18:45:523295 if (!preload_modules.empty()) {
Ali Ijaz Sheikh1514b822015-02-17 22:37:373296 Local<Array> array = Array::New(env->isolate());
Sam Robertscecdf7c2017-04-05 18:45:523297 for (unsigned int i = 0; i < preload_modules.size(); ++i) {
Evan Lucas5b6f5752015-06-01 14:15:103298 Local<String> module = String::NewFromUtf8(env->isolate(),
Sam Robertscecdf7c2017-04-05 18:45:523299 preload_modules[i].c_str());
Ali Ijaz Sheikh1514b822015-02-17 22:37:373300 array->Set(i, module);
3301 }
3302 READONLY_PROPERTY(process,
3303 "_preload_modules",
3304 array);
Ali Ijaz Sheikhf06b16f2015-03-25 19:19:463305
Sam Robertscecdf7c2017-04-05 18:45:523306 preload_modules.clear();
Ali Ijaz Sheikh1514b822015-02-17 22:37:373307 }
3308
isaacs5b399292012-06-21 18:42:333309 // --no-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103310 if (no_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423311 READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:333312 }
3313
Sam Robertse505c072017-04-05 21:04:443314 // --no-warnings
James M Snellc6656db2016-01-20 19:38:353315 if (no_process_warnings) {
3316 READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
3317 }
3318
Sam Robertse505c072017-04-05 21:04:443319 // --trace-warnings
James M Snellc6656db2016-01-20 19:38:353320 if (trace_warnings) {
3321 READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate()));
3322 }
3323
isaacs5038f402013-03-06 01:46:373324 // --throw-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103325 if (throw_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423326 READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
isaacs5038f402013-03-06 01:46:373327 }
3328
Fedor Indutny8363ede2016-03-23 01:05:543329#ifdef NODE_NO_BROWSER_GLOBALS
3330 // configure --no-browser-globals
3331 READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate()));
3332#endif // NODE_NO_BROWSER_GLOBALS
3333
Matt Loring49440b72015-11-25 14:08:583334 // --prof-process
3335 if (prof_process) {
3336 READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
3337 }
3338
isaacs5b399292012-06-21 18:42:333339 // --trace-deprecation
Evan Lucas5b6f5752015-06-01 14:15:103340 if (trace_deprecation) {
Fedor Indutny75adde02014-02-21 13:02:423341 READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
isaacs5b399292012-06-21 18:42:333342 }
3343
Ali Ijaz Sheikh4d4cfb22016-05-05 15:31:343344 // --debug-brk
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223345 if (debug_options.wait_for_connect()) {
Ali Ijaz Sheikh4d4cfb22016-05-05 15:31:343346 READONLY_PROPERTY(process, "_debugWaitConnect", True(env->isolate()));
3347 }
3348
James M Snelld3875912016-02-04 01:16:103349 // --security-revert flags
3350#define V(code, _, __) \
3351 do { \
3352 if (IsReverted(REVERT_ ## code)) { \
3353 READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate())); \
3354 } \
3355 } while (0);
3356 REVERSIONS(V)
3357#undef V
3358
Ben Noordhuisf674b092013-08-07 19:50:413359 size_t exec_path_len = 2 * PATH_MAX;
3360 char* exec_path = new char[exec_path_len];
3361 Local<String> exec_path_value;
3362 if (uv_exepath(exec_path, &exec_path_len) == 0) {
Fedor Indutny75adde02014-02-21 13:02:423363 exec_path_value = String::NewFromUtf8(env->isolate(),
Ben Noordhuisf674b092013-08-07 19:50:413364 exec_path,
3365 String::kNormalString,
3366 exec_path_len);
Marshall Culpepperca35ba62010-06-22 06:31:193367 } else {
Fedor Indutny75adde02014-02-21 13:02:423368 exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
Marshall Culpepperca35ba62010-06-22 06:31:193369 }
Ben Noordhuisb4ea3a02016-08-21 10:31:203370 process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"),
3371 exec_path_value);
Ben Noordhuisf674b092013-08-07 19:50:413372 delete[] exec_path;
Marshall Culpepperca35ba62010-06-22 06:31:193373
Ben Noordhuisb4ea3a02016-08-21 10:31:203374 auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort");
3375 CHECK(process->SetAccessor(env->context(),
3376 debug_port_string,
3377 DebugPortGetter,
3378 DebugPortSetter,
3379 env->as_external()).FromJust());
Fedor Indutny3f43b1c2012-02-12 15:53:433380
Ryan Dahl38814552009-10-09 15:15:473381 // define various internal methods
Ben Noordhuisd3c317e2014-10-13 13:19:553382 env->SetMethod(process,
3383 "_startProfilerIdleNotifier",
3384 StartProfilerIdleNotifier);
3385 env->SetMethod(process,
3386 "_stopProfilerIdleNotifier",
3387 StopProfilerIdleNotifier);
3388 env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
3389 env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
3390 env->SetMethod(process, "reallyExit", Exit);
3391 env->SetMethod(process, "abort", Abort);
3392 env->SetMethod(process, "chdir", Chdir);
3393 env->SetMethod(process, "cwd", Cwd);
Bert Belder30bab522010-11-25 00:09:063394
Ben Noordhuisd3c317e2014-10-13 13:19:553395 env->SetMethod(process, "umask", Umask);
Ryan Dahlacc120a2011-08-09 20:53:563396
Linus MÃ¥rtensson5e4e8ec2013-05-08 12:10:073397#if defined(__POSIX__) && !defined(__ANDROID__)
Ben Noordhuisd3c317e2014-10-13 13:19:553398 env->SetMethod(process, "getuid", GetUid);
Evan Lucas3c92ca22015-04-27 16:24:193399 env->SetMethod(process, "geteuid", GetEUid);
Ben Noordhuisd3c317e2014-10-13 13:19:553400 env->SetMethod(process, "setuid", SetUid);
Evan Lucas3c92ca22015-04-27 16:24:193401 env->SetMethod(process, "seteuid", SetEUid);
James Duncandf1c1e52010-02-23 22:45:023402
Ben Noordhuisd3c317e2014-10-13 13:19:553403 env->SetMethod(process, "setgid", SetGid);
Evan Lucas3c92ca22015-04-27 16:24:193404 env->SetMethod(process, "setegid", SetEGid);
Ben Noordhuisd3c317e2014-10-13 13:19:553405 env->SetMethod(process, "getgid", GetGid);
Evan Lucas3c92ca22015-04-27 16:24:193406 env->SetMethod(process, "getegid", GetEGid);
Ben Noordhuis3ece1302012-12-04 05:36:233407
Ben Noordhuisd3c317e2014-10-13 13:19:553408 env->SetMethod(process, "getgroups", GetGroups);
3409 env->SetMethod(process, "setgroups", SetGroups);
3410 env->SetMethod(process, "initgroups", InitGroups);
Fedor Indutny8e29ce92013-07-31 18:07:293411#endif // __POSIX__ && !defined(__ANDROID__)
James Duncandf1c1e52010-02-23 22:45:023412
Ben Noordhuisd3c317e2014-10-13 13:19:553413 env->SetMethod(process, "_kill", Kill);
Bert Belder30bab522010-11-25 00:09:063414
Ben Noordhuisd3c317e2014-10-13 13:19:553415 env->SetMethod(process, "_debugProcess", DebugProcess);
3416 env->SetMethod(process, "_debugPause", DebugPause);
3417 env->SetMethod(process, "_debugEnd", DebugEnd);
Bert Belder829735e2011-11-04 15:23:023418
Ben Noordhuisd3c317e2014-10-13 13:19:553419 env->SetMethod(process, "hrtime", Hrtime);
Nathan Rajlich07c886f2012-03-05 16:51:583420
Patrick Mueller52cb4102016-04-05 13:17:483421 env->SetMethod(process, "cpuUsage", CPUUsage);
3422
Ben Noordhuisd3c317e2014-10-13 13:19:553423 env->SetMethod(process, "dlopen", DLOpen);
Bert Belderdd93c532011-10-28 10:05:093424
Ben Noordhuisd3c317e2014-10-13 13:19:553425 env->SetMethod(process, "uptime", Uptime);
3426 env->SetMethod(process, "memoryUsage", MemoryUsage);
Ryan27b268b2009-06-17 13:05:443427
Ben Noordhuisd3c317e2014-10-13 13:19:553428 env->SetMethod(process, "binding", Binding);
Thorsten Lorenz0fe7a0d2014-09-15 17:00:223429 env->SetMethod(process, "_linkedBinding", LinkedBinding);
Ryan Dahl627fb5a2010-03-15 20:48:033430
Trevor Norris494227b2015-10-14 20:58:523431 env->SetMethod(process, "_setupProcessObject", SetupProcessObject);
Ben Noordhuisd3c317e2014-10-13 13:19:553432 env->SetMethod(process, "_setupNextTick", SetupNextTick);
Petka Antonov872702d2015-02-22 12:44:123433 env->SetMethod(process, "_setupPromises", SetupPromises);
Ben Noordhuisd3c317e2014-10-13 13:19:553434 env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
Trevor Norrisf0b68892013-03-26 05:32:413435
Trevor Norris4f7f8bb2013-02-26 17:47:363436 // pre-set _events object for faster emit checks
Brian Whitee38bade2016-04-07 00:33:283437 Local<Object> events_obj = Object::New(env->isolate());
Ben Noordhuisb4ea3a02016-08-21 10:31:203438 CHECK(events_obj->SetPrototype(env->context(),
3439 Null(env->isolate())).FromJust());
Brian Whitee38bade2016-04-07 00:33:283440 process->Set(env->events_string(), events_obj);
Dean McNameef67e8f22011-03-15 22:39:163441}
3442
3443
Trevor Norrisc80f8fa2013-08-01 21:53:523444#undef READONLY_PROPERTY
3445
3446
Anna Henningsen0815b942016-05-08 01:28:473447void SignalExit(int signo) {
Ryan Dahl4e43afd2011-09-30 20:11:473448 uv_tty_reset_mode();
misterpoeba4847e2016-08-05 21:04:253449 if (trace_enabled) {
Myk Melez046f66a2017-01-31 17:56:093450 v8_platform.StopTracingAgent();
misterpoeba4847e2016-08-05 21:04:253451 }
Fedor Indutnyb64983d2015-03-20 05:03:343452#ifdef __FreeBSD__
3453 // FreeBSD has a nasty bug, see RegisterSignalHandler for details
3454 struct sigaction sa;
3455 memset(&sa, 0, sizeof(sa));
3456 sa.sa_handler = SIG_DFL;
3457 CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
3458#endif
Geir Haugec61b0e92014-03-31 07:52:033459 raise(signo);
Dean McNameef67e8f22011-03-15 22:39:163460}
3461
3462
isaacs906a1752013-08-21 22:36:503463// Most of the time, it's best to use `console.error` to write
3464// to the process.stderr stream. However, in some cases, such as
3465// when debugging the stream.Writable class or the process.nextTick
3466// function, it is useful to bypass JavaScript entirely.
3467static void RawDebug(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuis5fdff382014-10-11 14:52:073468 CHECK(args.Length() == 1 && args[0]->IsString() &&
3469 "must be called with a single string");
Trevor Norriscbf76c12015-01-07 22:13:353470 node::Utf8Value message(args.GetIsolate(), args[0]);
Brian White2d356072015-10-13 21:18:153471 PrintErrorString("%s\n", *message);
isaacs906a1752013-08-21 22:36:503472 fflush(stderr);
3473}
3474
3475
Fedor Indutny6a610a02014-10-04 14:44:393476void LoadEnvironment(Environment* env) {
Fedor Indutny75adde02014-02-21 13:02:423477 HandleScope handle_scope(env->isolate());
Ben Noordhuis34b0a362013-07-29 03:07:073478
Michaël Zasso79d74752016-01-26 08:06:433479 TryCatch try_catch(env->isolate());
Ryan Dahl9f5643f2010-01-31 07:22:343480
Miroslav Bajtosc16963b2013-06-17 19:19:593481 // Disable verbose mode to stop FatalException() handler from trying
3482 // to handle the exception. Errors this early in the start-up phase
3483 // are not safe to ignore.
3484 try_catch.SetVerbose(false);
3485
Daniel Bevenius81b68822016-06-12 11:14:343486 // Execute the lib/internal/bootstrap_node.js file which was included as a
3487 // static C string in node_natives.h by node_js2c.
3488 // 'internal_bootstrap_node_native' is the string containing that source code.
3489 Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),
3490 "bootstrap_node.js");
Fedor Indutny75adde02014-02-21 13:02:423491 Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
Ryan Dahl9f5643f2010-01-31 07:22:343492 if (try_catch.HasCaught()) {
Fedor Indutnyf1de13b2014-02-05 16:38:333493 ReportException(env, try_catch);
Ryan Dahl9f5643f2010-01-31 07:22:343494 exit(10);
3495 }
Daniel Bevenius0441f2a2016-08-03 08:08:473496 // The bootstrap_node.js file returns a function 'f'
Ben Noordhuis5fdff382014-10-11 14:52:073497 CHECK(f_value->IsFunction());
Ryan Dahl9f5643f2010-01-31 07:22:343498 Local<Function> f = Local<Function>::Cast(f_value);
3499
Ryan Dahlf8ce8482010-09-17 07:01:073500 // Add a reference to the global object
Ben Noordhuis756b6222013-08-10 22:26:113501 Local<Object> global = env->context()->Global();
Zoran Tomicicd98ea702010-02-22 05:15:443502
Ben Noordhuisc4def502013-10-28 19:18:593503#if defined HAVE_DTRACE || defined HAVE_ETW
Fedor Indutny75adde02014-02-21 13:02:423504 InitDTrace(env, global);
Ryan Dahle9257b82011-02-10 02:50:263505#endif
Ryan Dahl068b7332011-01-25 01:50:103506
Glen Keane5e825d12015-01-22 12:35:163507#if defined HAVE_LTTNG
3508 InitLTTNG(env, global);
3509#endif
3510
Scott Blomquistf657ce62012-11-20 23:27:223511#if defined HAVE_PERFCTR
Fedor Indutny75adde02014-02-21 13:02:423512 InitPerfCounters(env, global);
Scott Blomquistf657ce62012-11-20 23:27:223513#endif
3514
Miroslav Bajtosc16963b2013-06-17 19:19:593515 // Enable handling of uncaught exceptions
3516 // (FatalException(), break on uncaught exception in debugger)
3517 //
3518 // This is not strictly necessary since it's almost impossible
Benjamin Fleischer4897ae22017-02-06 01:18:463519 // to attach the debugger fast enough to break on exception
Miroslav Bajtosc16963b2013-06-17 19:19:593520 // thrown during process startup.
3521 try_catch.SetVerbose(true);
Ryan Dahl9f5643f2010-01-31 07:22:343522
Ben Noordhuisd3c317e2014-10-13 13:19:553523 env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
isaacs906a1752013-08-21 22:36:503524
Jeremiah Senkpiel21d66d62016-03-23 22:09:103525 // Expose the global object as a property on itself
3526 // (Allows you to set stuff on `global` from anywhere in JavaScript.)
3527 global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
3528
Daniel Beveniusa01e8bc2016-09-04 18:49:093529 // Now we call 'f' with the 'process' variable that we've built up with
Daniel Bevenius8afde122016-09-06 07:31:023530 // all our bindings. Inside bootstrap_node.js and internal/process we'll
3531 // take care of assigning things to their places.
Daniel Beveniusa01e8bc2016-09-04 18:49:093532
3533 // We start the process this way in order to be more modular. Developers
Daniel Bevenius8afde122016-09-06 07:31:023534 // who do not like how bootstrap_node.js sets up the module system but do
Daniel Beveniusa01e8bc2016-09-04 18:49:093535 // like Node's I/O bindings may want to replace 'f' with their own function.
Ben Noordhuis756b6222013-08-10 22:26:113536 Local<Value> arg = env->process_object();
Ben Noordhuis00c876d2016-03-31 10:39:373537 f->Call(Null(env->isolate()), 1, &arg);
Ryan27b268b2009-06-17 13:05:443538}
3539
Evan Lucas5b6f5752015-06-01 14:15:103540static void PrintHelp() {
Jeremiah Senkpiel91cf55b2016-03-18 17:26:413541 // XXX: If you add an option here, please also add it to doc/node.1 and
Robert Jefe Lindstaedt0800c0a2016-04-20 22:12:403542 // doc/api/cli.md
Aashil Patel5d27cc12017-01-21 22:44:293543 printf("Usage: node [options] [ -e script | script.js ] [arguments]\n"
Ali Ijaz Sheikha235ccd2017-03-14 21:20:383544 " node inspect script.js [arguments]\n"
Evan Lucas5b6f5752015-06-01 14:15:103545 "\n"
3546 "Options:\n"
Aashil Patel5d27cc12017-01-21 22:44:293547 " -v, --version print Node.js version\n"
3548 " -e, --eval script evaluate script\n"
3549 " -p, --print evaluate script and print result\n"
3550 " -c, --check syntax check script without executing\n"
3551 " -i, --interactive always enter the REPL even if stdin\n"
3552 " does not appear to be a terminal\n"
3553 " -r, --require module to preload (option can be "
misterpoeba4847e2016-08-05 21:04:253554 "repeated)\n"
Josh Gavant6ff3b032016-12-15 04:18:153555#if HAVE_INSPECTOR
Gibson Fahnestock2d2970e2017-03-28 15:54:303556 " --inspect[=[host:]port] activate inspector on host:port\n"
Aashil Patel5d27cc12017-01-21 22:44:293557 " (default: 127.0.0.1:9229)\n"
Gibson Fahnestock2d2970e2017-03-28 15:54:303558 " --inspect-brk[=[host:]port]\n"
3559 " activate inspector on host:port\n"
Josh Gavant6ff3b032016-12-15 04:18:153560 " and break at start of user script\n"
3561#endif
Aashil Patel5d27cc12017-01-21 22:44:293562 " --no-deprecation silence deprecation warnings\n"
3563 " --trace-deprecation show stack traces on deprecations\n"
3564 " --throw-deprecation throw an exception on deprecations\n"
3565 " --no-warnings silence all process warnings\n"
Jason Ginchereau56e881d2017-03-20 21:55:263566 " --napi-modules load N-API modules\n"
Aashil Patel5d27cc12017-01-21 22:44:293567 " --trace-warnings show stack traces on process warnings\n"
James M Snell03e89b32016-12-04 18:38:353568 " --redirect-warnings=path\n"
3569 " write warnings to path instead of\n"
3570 " stderr\n"
Aashil Patel5d27cc12017-01-21 22:44:293571 " --trace-sync-io show stack trace when use of sync IO\n"
3572 " is detected after the first tick\n"
3573 " --trace-events-enabled track trace events\n"
3574 " --trace-event-categories comma separated list of trace event\n"
3575 " categories to record\n"
3576 " --track-heap-objects track heap object allocations for heap "
Bradley Meckcf14a242015-07-09 16:15:263577 "snapshots\n"
Aashil Patel5d27cc12017-01-21 22:44:293578 " --prof-process process v8 profiler output generated\n"
3579 " using --prof\n"
3580 " --zero-fill-buffers automatically zero-fill all newly "
misterpoeba4847e2016-08-05 21:04:253581 "allocated\n"
Aashil Patel5d27cc12017-01-21 22:44:293582 " Buffer and SlowBuffer instances\n"
3583 " --v8-options print v8 command line options\n"
3584 " --v8-pool-size=num set v8's thread pool size\n"
James M Snell5ba868f2015-08-17 22:51:513585#if HAVE_OPENSSL
Aashil Patel5d27cc12017-01-21 22:44:293586 " --tls-cipher-list=val use an alternative default TLS cipher "
misterpoeba4847e2016-08-05 21:04:253587 "list\n"
Aashil Patel5d27cc12017-01-21 22:44:293588 " --use-bundled-ca use bundled CA store"
Adam Majer33012e92016-12-21 10:16:393589#if !defined(NODE_OPENSSL_CERT_STORE)
3590 " (default)"
3591#endif
3592 "\n"
Aashil Patel5d27cc12017-01-21 22:44:293593 " --use-openssl-ca use OpenSSL's default CA store"
Adam Majer33012e92016-12-21 10:16:393594#if defined(NODE_OPENSSL_CERT_STORE)
3595 " (default)"
3596#endif
3597 "\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093598#if NODE_FIPS_MODE
Aashil Patel5d27cc12017-01-21 22:44:293599 " --enable-fips enable FIPS crypto at startup\n"
3600 " --force-fips force FIPS crypto (cannot be disabled)\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093601#endif /* NODE_FIPS_MODE */
Sam Roberts59afa272017-01-25 22:13:343602 " --openssl-config=file load OpenSSL configuration from the\n"
3603 " specified file (overrides\n"
3604 " OPENSSL_CONF)\n"
Stefan Budeanu7c48cb52016-01-22 23:10:093605#endif /* HAVE_OPENSSL */
Evan Lucas5b6f5752015-06-01 14:15:103606#if defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293607 " --icu-data-dir=dir set ICU data load path to dir\n"
3608 " (overrides NODE_ICU_DATA)\n"
Evan Lucas5b6f5752015-06-01 14:15:103609#if !defined(NODE_HAVE_SMALL_ICU)
Aashil Patel5d27cc12017-01-21 22:44:293610 " note: linked-in ICU data is present\n"
Evan Lucas5b6f5752015-06-01 14:15:103611#endif
Aashil Patel5d27cc12017-01-21 22:44:293612 " --preserve-symlinks preserve symbolic links when resolving\n"
3613 " and caching modules\n"
Evan Lucas5b6f5752015-06-01 14:15:103614#endif
3615 "\n"
3616 "Environment variables:\n"
Aashil Patel5d27cc12017-01-21 22:44:293617 "NODE_DEBUG ','-separated list of core modules\n"
3618 " that should print debug information\n"
3619 "NODE_DISABLE_COLORS set to 1 to disable colors in the REPL\n"
3620 "NODE_EXTRA_CA_CERTS path to additional CA certificates\n"
3621 " file\n"
Evan Lucas5b6f5752015-06-01 14:15:103622#if defined(NODE_HAVE_I18N_SUPPORT)
Aashil Patel5d27cc12017-01-21 22:44:293623 "NODE_ICU_DATA data path for ICU (Intl object) data\n"
Evan Lucas5b6f5752015-06-01 14:15:103624#if !defined(NODE_HAVE_SMALL_ICU)
Aashil Patel5d27cc12017-01-21 22:44:293625 " (will extend linked-in data)\n"
Evan Lucas5b6f5752015-06-01 14:15:103626#endif
3627#endif
Aashil Patel5d27cc12017-01-21 22:44:293628 "NODE_NO_WARNINGS set to 1 to silence process warnings\n"
Roman Reiss2d235622016-12-22 06:10:223629#ifdef _WIN32
Aashil Patel5d27cc12017-01-21 22:44:293630 "NODE_PATH ';'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223631#else
Aashil Patel5d27cc12017-01-21 22:44:293632 "NODE_PATH ':'-separated list of directories\n"
Roman Reiss2d235622016-12-22 06:10:223633#endif
Aashil Patel5d27cc12017-01-21 22:44:293634 " prefixed to the module search path\n"
3635 "NODE_REPL_HISTORY path to the persistent REPL history\n"
3636 " file\n"
James M Snell03e89b32016-12-04 18:38:353637 "NODE_REDIRECT_WARNINGS write warnings to path instead of\n"
3638 " stderr\n"
Sam Roberts59afa272017-01-25 22:13:343639 "OPENSSL_CONF load OpenSSL configuration from file\n"
3640 "\n"
cjihriga69ab272015-08-13 16:14:343641 "Documentation can be found at https://nodejs.org/\n");
Evan Lucas5b6f5752015-06-01 14:15:103642}
3643
3644
3645// Parse command line arguments.
3646//
3647// argv is modified in place. exec_argv and v8_argv are out arguments that
3648// ParseArgs() allocates memory for and stores a pointer to the output
3649// vector in. The caller should free them with delete[].
3650//
3651// On exit:
3652//
3653// * argv contains the arguments with node and V8 options filtered out.
3654// * exec_argv contains both node and V8 options and nothing else.
3655// * v8_argv contains argv[0] plus any V8 options
3656static void ParseArgs(int* argc,
3657 const char** argv,
3658 int* exec_argc,
3659 const char*** exec_argv,
3660 int* v8_argc,
3661 const char*** v8_argv) {
3662 const unsigned int nargs = static_cast<unsigned int>(*argc);
3663 const char** new_exec_argv = new const char*[nargs];
3664 const char** new_v8_argv = new const char*[nargs];
3665 const char** new_argv = new const char*[nargs];
Daniel Beveniusde168b42017-04-10 13:13:243666#if HAVE_OPENSSL
Daniel Bevenius8a7db9d2017-03-28 06:56:393667 bool use_bundled_ca = false;
3668 bool use_openssl_ca = false;
Daniel Beveniusde168b42017-04-10 13:13:243669#endif // HAVE_INSPECTOR
Evan Lucas5b6f5752015-06-01 14:15:103670
3671 for (unsigned int i = 0; i < nargs; ++i) {
3672 new_exec_argv[i] = nullptr;
3673 new_v8_argv[i] = nullptr;
3674 new_argv[i] = nullptr;
Evan Lucas5b6f5752015-06-01 14:15:103675 }
3676
3677 // exec_argv starts with the first option, the other two start with argv[0].
3678 unsigned int new_exec_argc = 0;
3679 unsigned int new_v8_argc = 1;
3680 unsigned int new_argc = 1;
3681 new_v8_argv[0] = argv[0];
3682 new_argv[0] = argv[0];
3683
3684 unsigned int index = 1;
Matt Loring49440b72015-11-25 14:08:583685 bool short_circuit = false;
3686 while (index < nargs && argv[index][0] == '-' && !short_circuit) {
Evan Lucas5b6f5752015-06-01 14:15:103687 const char* const arg = argv[index];
3688 unsigned int args_consumed = 1;
3689
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223690 if (debug_options.ParseOption(arg)) {
3691 // Done, consumed by DebugOptions::ParseOption().
Evan Lucas5b6f5752015-06-01 14:15:103692 } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3693 printf("%s\n", NODE_VERSION);
3694 exit(0);
3695 } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3696 PrintHelp();
3697 exit(0);
3698 } else if (strcmp(arg, "--eval") == 0 ||
3699 strcmp(arg, "-e") == 0 ||
3700 strcmp(arg, "--print") == 0 ||
3701 strcmp(arg, "-pe") == 0 ||
3702 strcmp(arg, "-p") == 0) {
3703 bool is_eval = strchr(arg, 'e') != nullptr;
3704 bool is_print = strchr(arg, 'p') != nullptr;
3705 print_eval = print_eval || is_print;
3706 // --eval, -e and -pe always require an argument.
3707 if (is_eval == true) {
3708 args_consumed += 1;
3709 eval_string = argv[index + 1];
3710 if (eval_string == nullptr) {
3711 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3712 exit(9);
3713 }
3714 } else if ((index + 1 < nargs) &&
3715 argv[index + 1] != nullptr &&
3716 argv[index + 1][0] != '-') {
3717 args_consumed += 1;
3718 eval_string = argv[index + 1];
3719 if (strncmp(eval_string, "\\-", 2) == 0) {
3720 // Starts with "\\-": escaped expression, drop the backslash.
3721 eval_string += 1;
3722 }
3723 }
3724 } else if (strcmp(arg, "--require") == 0 ||
3725 strcmp(arg, "-r") == 0) {
3726 const char* module = argv[index + 1];
3727 if (module == nullptr) {
3728 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3729 exit(9);
3730 }
3731 args_consumed += 1;
Sam Robertscecdf7c2017-04-05 18:45:523732 preload_modules.push_back(module);
Dave Eddy2e6ece42015-08-17 21:33:133733 } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3734 syntax_check_only = true;
Evan Lucas5b6f5752015-06-01 14:15:103735 } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3736 force_repl = true;
3737 } else if (strcmp(arg, "--no-deprecation") == 0) {
3738 no_deprecation = true;
Jason Ginchereau56e881d2017-03-20 21:55:263739 } else if (strcmp(arg, "--napi-modules") == 0) {
3740 load_napi_modules = true;
James M Snellc6656db2016-01-20 19:38:353741 } else if (strcmp(arg, "--no-warnings") == 0) {
3742 no_process_warnings = true;
3743 } else if (strcmp(arg, "--trace-warnings") == 0) {
3744 trace_warnings = true;
James M Snell03e89b32016-12-04 18:38:353745 } else if (strncmp(arg, "--redirect-warnings=", 20) == 0) {
3746 config_warning_file = arg + 20;
Evan Lucas5b6f5752015-06-01 14:15:103747 } else if (strcmp(arg, "--trace-deprecation") == 0) {
3748 trace_deprecation = true;
3749 } else if (strcmp(arg, "--trace-sync-io") == 0) {
3750 trace_sync_io = true;
misterpoeba4847e2016-08-05 21:04:253751 } else if (strcmp(arg, "--trace-events-enabled") == 0) {
3752 trace_enabled = true;
3753 } else if (strcmp(arg, "--trace-event-categories") == 0) {
3754 const char* categories = argv[index + 1];
3755 if (categories == nullptr) {
3756 fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3757 exit(9);
3758 }
3759 args_consumed += 1;
3760 trace_enabled_categories = categories;
Bradley Meckcf14a242015-07-09 16:15:263761 } else if (strcmp(arg, "--track-heap-objects") == 0) {
3762 track_heap_objects = true;
Evan Lucas5b6f5752015-06-01 14:15:103763 } else if (strcmp(arg, "--throw-deprecation") == 0) {
3764 throw_deprecation = true;
James M Snelld3875912016-02-04 01:16:103765 } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3766 const char* cve = arg + 18;
3767 Revert(cve);
James M Snell5d38d542016-05-02 23:31:203768 } else if (strcmp(arg, "--preserve-symlinks") == 0) {
3769 config_preserve_symlinks = true;
Matt Loring49440b72015-11-25 14:08:583770 } else if (strcmp(arg, "--prof-process") == 0) {
3771 prof_process = true;
3772 short_circuit = true;
James M Snell85ab4a52016-01-25 23:00:063773 } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
3774 zero_fill_all_buffers = true;
James M Snella16b5702017-03-11 20:18:533775 } else if (strcmp(arg, "--pending-deprecation") == 0) {
3776 config_pending_deprecation = true;
Evan Lucas5b6f5752015-06-01 14:15:103777 } else if (strcmp(arg, "--v8-options") == 0) {
3778 new_v8_argv[new_v8_argc] = "--help";
3779 new_v8_argc += 1;
Tom Gallacher03e07d32015-12-18 12:24:563780 } else if (strncmp(arg, "--v8-pool-size=", 15) == 0) {
3781 v8_thread_pool_size = atoi(arg + 15);
James M Snell5ba868f2015-08-17 22:51:513782#if HAVE_OPENSSL
3783 } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) {
3784 default_cipher_list = arg + 18;
Adam Majer33012e92016-12-21 10:16:393785 } else if (strncmp(arg, "--use-openssl-ca", 16) == 0) {
3786 ssl_openssl_cert_store = true;
Daniel Bevenius8a7db9d2017-03-28 06:56:393787 use_openssl_ca = true;
Adam Majer33012e92016-12-21 10:16:393788 } else if (strncmp(arg, "--use-bundled-ca", 16) == 0) {
Daniel Bevenius8a7db9d2017-03-28 06:56:393789 use_bundled_ca = true;
Adam Majer33012e92016-12-21 10:16:393790 ssl_openssl_cert_store = false;
Stefan Budeanu7c48cb52016-01-22 23:10:093791#if NODE_FIPS_MODE
3792 } else if (strcmp(arg, "--enable-fips") == 0) {
3793 enable_fips_crypto = true;
3794 } else if (strcmp(arg, "--force-fips") == 0) {
3795 force_fips_crypto = true;
3796#endif /* NODE_FIPS_MODE */
Fedor Indutnydb411cf2016-09-29 08:53:303797 } else if (strncmp(arg, "--openssl-config=", 17) == 0) {
Sam Roberts59afa272017-01-25 22:13:343798 openssl_config.assign(arg + 17);
Stefan Budeanu7c48cb52016-01-22 23:10:093799#endif /* HAVE_OPENSSL */
Evan Lucas5b6f5752015-06-01 14:15:103800#if defined(NODE_HAVE_I18N_SUPPORT)
3801 } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
Ben Noordhuis291b5992017-02-11 13:04:583802 icu_data_dir.assign(arg + 15);
Evan Lucas5b6f5752015-06-01 14:15:103803#endif
3804 } else if (strcmp(arg, "--expose-internals") == 0 ||
3805 strcmp(arg, "--expose_internals") == 0) {
Sam Roberts8086cb62017-04-05 21:06:523806 config_expose_internals = true;
John Barboza0a9f3602016-12-30 05:28:383807 } else if (strcmp(arg, "--") == 0) {
3808 index += 1;
3809 break;
Evan Lucas5b6f5752015-06-01 14:15:103810 } else {
3811 // V8 option. Pass through as-is.
3812 new_v8_argv[new_v8_argc] = arg;
3813 new_v8_argc += 1;
3814 }
3815
3816 memcpy(new_exec_argv + new_exec_argc,
3817 argv + index,
3818 args_consumed * sizeof(*argv));
3819
3820 new_exec_argc += args_consumed;
3821 index += args_consumed;
3822 }
3823
Daniel Bevenius8a7db9d2017-03-28 06:56:393824#if HAVE_OPENSSL
3825 if (use_openssl_ca && use_bundled_ca) {
3826 fprintf(stderr,
3827 "%s: either --use-openssl-ca or --use-bundled-ca can be used, "
3828 "not both\n",
3829 argv[0]);
3830 exit(9);
3831 }
3832#endif
3833
Teddy Katza5f91ab2017-03-30 06:35:033834 if (eval_string != nullptr && syntax_check_only) {
3835 fprintf(stderr,
3836 "%s: either --check or --eval can be used, not both\n", argv[0]);
3837 exit(9);
3838 }
3839
Evan Lucas5b6f5752015-06-01 14:15:103840 // Copy remaining arguments.
3841 const unsigned int args_left = nargs - index;
3842 memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3843 new_argc += args_left;
3844
3845 *exec_argc = new_exec_argc;
3846 *exec_argv = new_exec_argv;
3847 *v8_argc = new_v8_argc;
3848 *v8_argv = new_v8_argv;
3849
3850 // Copy new_argv over argv and update argc.
3851 memcpy(argv, new_argv, new_argc * sizeof(*argv));
3852 delete[] new_argv;
3853 *argc = static_cast<int>(new_argc);
Evan Lucas5b6f5752015-06-01 14:15:103854}
3855
Bert Belder829735e2011-11-04 15:23:023856
Peter Rybin688859a2012-07-03 19:21:373857// Called from V8 Debug Agent TCP thread.
Fedor Indutny6a610a02014-10-04 14:44:393858static void DispatchMessagesDebugAgentCallback(Environment* env) {
3859 // TODO(indutny): move async handle to environment
Peter Rybin688859a2012-07-03 19:21:373860 uv_async_send(&dispatch_debug_messages_async);
3861}
3862
3863
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223864static void StartDebug(Environment* env, const char* path,
3865 DebugOptions debug_options) {
Fedor Indutny6a610a02014-10-04 14:44:393866 CHECK(!debugger_running);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223867 if (debug_options.debugger_enabled()) {
Pavel Feldman84ad31f2016-02-07 16:47:143868 env->debugger_agent()->set_dispatch_handler(
3869 DispatchMessagesDebugAgentCallback);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223870 debugger_running = env->debugger_agent()->Start(debug_options);
Ali Ijaz Sheikha766ebf2016-06-08 01:02:033871 if (debugger_running == false) {
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223872 fprintf(stderr, "Starting debugger on %s:%d failed\n",
3873 debug_options.host_name().c_str(), debug_options.port());
Ali Ijaz Sheikha766ebf2016-06-08 01:02:033874 fflush(stderr);
Ali Ijaz Sheikha766ebf2016-06-08 01:02:033875 }
Eugene Ostroukhov7599b0e2016-12-13 01:08:313876#if HAVE_INSPECTOR
3877 } else {
3878 debugger_running = v8_platform.StartInspector(env, path, debug_options);
3879#endif // HAVE_INSPECTOR
Pavel Feldman84ad31f2016-02-07 16:47:143880 }
Fedor Indutny6a610a02014-10-04 14:44:393881}
Ben Noordhuisca363cf2013-10-15 21:32:183882
Ben Noordhuisca363cf2013-10-15 21:32:183883
Fedor Indutny6a610a02014-10-04 14:44:393884// Called from the main thread.
3885static void EnableDebug(Environment* env) {
3886 CHECK(debugger_running);
Ben Noordhuisc5c28c32015-10-10 13:01:493887
Fedor Indutny6a610a02014-10-04 14:44:393888 // Send message to enable debug in workers
3889 HandleScope handle_scope(env->isolate());
3890
Fedor Indutnyce04c722014-03-13 16:38:143891 Local<Object> message = Object::New(env->isolate());
Ben Noordhuisca363cf2013-10-15 21:32:183892 message->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "cmd"),
3893 FIXED_ONE_BYTE_STRING(env->isolate(), "NODE_DEBUG_ENABLED"));
3894 Local<Value> argv[] = {
3895 FIXED_ONE_BYTE_STRING(env->isolate(), "internalMessage"),
Ben Noordhuis756b6222013-08-10 22:26:113896 message
Ben Noordhuisf674b092013-08-07 19:50:413897 };
Ben Noordhuisa7581d02016-03-31 10:47:063898 MakeCallback(env, env->process_object(), "emit", arraysize(argv), argv);
Fedor Indutny6a610a02014-10-04 14:44:393899
3900 // Enabled debugger, possibly making it wait on a semaphore
3901 env->debugger_agent()->Enable();
Miroslav Bajtoš43ec1b12013-05-02 06:34:223902}
3903
3904
Ben Noordhuisca363cf2013-10-15 21:32:183905// Called from the main thread.
Saúl Ibarra Corretgé42b93432014-03-12 23:08:293906static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
Ben Noordhuisd7087df2016-06-17 23:39:053907 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuis844f0a92016-03-25 16:59:073908 if (auto isolate = node_isolate) {
3909 if (debugger_running == false) {
3910 fprintf(stderr, "Starting debugger agent.\n");
Ben Noordhuis53e64bb2015-10-26 13:11:033911
Ben Noordhuis844f0a92016-03-25 16:59:073912 HandleScope scope(isolate);
3913 Environment* env = Environment::GetCurrent(isolate);
3914 Context::Scope context_scope(env->context());
Eugene Ostroukhovf9aadfb2016-11-18 21:52:223915 debug_options.EnableDebugAgent(DebugAgentType::kDebugger);
3916 StartDebug(env, nullptr, debug_options);
Ben Noordhuis844f0a92016-03-25 16:59:073917 EnableDebug(env);
3918 }
Fedor Indutny6a610a02014-10-04 14:44:393919
Ben Noordhuis844f0a92016-03-25 16:59:073920 Isolate::Scope isolate_scope(isolate);
3921 v8::Debug::ProcessDebugMessages(isolate);
Ben Noordhuis756b6222013-08-10 22:26:113922 }
Ryan Dahl2a7e7b12010-12-18 19:17:293923}
3924
3925
Fedor Indutny82d0ac72011-09-24 13:51:593926#ifdef __POSIX__
Anna Henningsen0815b942016-05-08 01:28:473927void RegisterSignalHandler(int signal,
3928 void (*handler)(int signal),
3929 bool reset_handler) {
Tom Hughesf61b1102010-10-12 21:01:583930 struct sigaction sa;
Tom Hughesf61b1102010-10-12 21:01:583931 memset(&sa, 0, sizeof(sa));
3932 sa.sa_handler = handler;
Fedor Indutnyb64983d2015-03-20 05:03:343933#ifndef __FreeBSD__
3934 // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
3935 // in turn set for a libthr wrapper. This leads to a crash.
3936 // Work around the issue by manually setting SIG_DFL in the signal handler
Geir Haugec61b0e92014-03-31 07:52:033937 sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
Fedor Indutnyb64983d2015-03-20 05:03:343938#endif
Tom Hughesf61b1102010-10-12 21:01:583939 sigfillset(&sa.sa_mask);
Ben Noordhuis2d82cdf2014-10-22 01:29:323940 CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
Bert Belder829735e2011-11-04 15:23:023941}
3942
3943
Ben Noordhuis110a9cd2013-07-03 02:23:443944void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553945 Environment* env = Environment::GetCurrent(args);
Bert Belder829735e2011-11-04 15:23:023946
3947 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423948 return env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023949 }
3950
3951 pid_t pid;
3952 int r;
3953
3954 pid = args[0]->IntegerValue();
3955 r = kill(pid, SIGUSR1);
3956 if (r != 0) {
Fedor Indutny75adde02014-02-21 13:02:423957 return env->ThrowErrnoException(errno, "kill");
Bert Belder829735e2011-11-04 15:23:023958 }
Tom Hughesf61b1102010-10-12 21:01:583959}
Fedor Indutny8e29ce92013-07-31 18:07:293960#endif // __POSIX__
Tom Hughesf61b1102010-10-12 21:01:583961
3962
Bert Belder829735e2011-11-04 15:23:023963#ifdef _WIN32
Bert Belder8f2694b2012-02-16 21:19:483964static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
3965 size_t buf_len) {
3966 return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
Bert Belder829735e2011-11-04 15:23:023967}
3968
3969
Ben Noordhuis110a9cd2013-07-03 02:23:443970static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
Ben Noordhuisd3c317e2014-10-13 13:19:553971 Environment* env = Environment::GetCurrent(args);
Alexis Campailla440b9e22014-02-24 18:55:273972 Isolate* isolate = args.GetIsolate();
Bert Belder829735e2011-11-04 15:23:023973 DWORD pid;
Ben Noordhuis2d82cdf2014-10-22 01:29:323974 HANDLE process = nullptr;
3975 HANDLE thread = nullptr;
3976 HANDLE mapping = nullptr;
Bert Belder8f2694b2012-02-16 21:19:483977 wchar_t mapping_name[32];
Ben Noordhuis2d82cdf2014-10-22 01:29:323978 LPTHREAD_START_ROUTINE* handler = nullptr;
Bert Belder829735e2011-11-04 15:23:023979
3980 if (args.Length() != 1) {
Fedor Indutny75adde02014-02-21 13:02:423981 env->ThrowError("Invalid number of arguments.");
Bert Belder829735e2011-11-04 15:23:023982 goto out;
3983 }
3984
3985 pid = (DWORD) args[0]->IntegerValue();
3986
Bert Belder68db2062012-02-03 14:37:463987 process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
Bert Belder829735e2011-11-04 15:23:023988 PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
3989 PROCESS_VM_READ,
3990 FALSE,
3991 pid);
Ben Noordhuis2d82cdf2014-10-22 01:29:323992 if (process == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:273993 isolate->ThrowException(
3994 WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
Bert Belder829735e2011-11-04 15:23:023995 goto out;
3996 }
3997
3998 if (GetDebugSignalHandlerMappingName(pid,
3999 mapping_name,
Ben Noordhuisa7581d02016-03-31 10:47:064000 arraysize(mapping_name)) < 0) {
Fedor Indutny75adde02014-02-21 13:02:424001 env->ThrowErrnoException(errno, "sprintf");
Bert Belder829735e2011-11-04 15:23:024002 goto out;
4003 }
4004
Bert Belder8f2694b2012-02-16 21:19:484005 mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
Ben Noordhuis2d82cdf2014-10-22 01:29:324006 if (mapping == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274007 isolate->ThrowException(WinapiErrnoException(isolate,
Fedor Indutny75adde02014-02-21 13:02:424008 GetLastError(),
4009 "OpenFileMappingW"));
Bert Belder829735e2011-11-04 15:23:024010 goto out;
4011 }
4012
Bert Belder8f2694b2012-02-16 21:19:484013 handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
4014 MapViewOfFile(mapping,
4015 FILE_MAP_READ,
4016 0,
4017 0,
4018 sizeof *handler));
Ben Noordhuis2d82cdf2014-10-22 01:29:324019 if (handler == nullptr || *handler == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274020 isolate->ThrowException(
4021 WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
Bert Belder829735e2011-11-04 15:23:024022 goto out;
4023 }
4024
Bert Belder68db2062012-02-03 14:37:464025 thread = CreateRemoteThread(process,
Ben Noordhuis2d82cdf2014-10-22 01:29:324026 nullptr,
Bert Belder829735e2011-11-04 15:23:024027 0,
4028 *handler,
Ben Noordhuis2d82cdf2014-10-22 01:29:324029 nullptr,
Bert Belder829735e2011-11-04 15:23:024030 0,
Ben Noordhuis2d82cdf2014-10-22 01:29:324031 nullptr);
4032 if (thread == nullptr) {
Alexis Campailla440b9e22014-02-24 18:55:274033 isolate->ThrowException(WinapiErrnoException(isolate,
4034 GetLastError(),
4035 "CreateRemoteThread"));
Bert Belder829735e2011-11-04 15:23:024036 goto out;
4037 }
4038
4039 // Wait for the thread to terminate
4040 if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
Alexis Campailla440b9e22014-02-24 18:55:274041 isolate->ThrowException(WinapiErrnoException(isolate,
4042 GetLastError(),
4043 "WaitForSingleObject"));
Bert Belder829735e2011-11-04 15:23:024044 goto out;
4045 }
4046
4047 out:
Ben Noordhuis2d82cdf2014-10-22 01:29:324048 if (process != nullptr)
Fedor Indutny8e29ce92013-07-31 18:07:294049 CloseHandle(process);
Ben Noordhuis2d82cdf2014-10-22 01:29:324050 if (thread != nullptr)
Bert Belder829735e2011-11-04 15:23:024051 CloseHandle(thread);
Ben Noordhuis2d82cdf2014-10-22 01:29:324052 if (handler != nullptr)
Bert Belder829735e2011-11-04 15:23:024053 UnmapViewOfFile(handler);
Ben Noordhuis2d82cdf2014-10-22 01:29:324054 if (mapping != nullptr)
Bert Belder829735e2011-11-04 15:23:024055 CloseHandle(mapping);
Bert Belder829735e2011-11-04 15:23:024056}
Fedor Indutny8e29ce92013-07-31 18:07:294057#endif // _WIN32
Bert Belder829735e2011-11-04 15:23:024058
4059
Ben Noordhuis110a9cd2013-07-03 02:23:444060static void DebugPause(const FunctionCallbackInfo<Value>& args) {
Fedor Indutny75adde02014-02-21 13:02:424061 v8::Debug::DebugBreak(args.GetIsolate());
Fedor Indutnyb0388cc2011-12-10 16:52:074062}
4063
4064
Ben Noordhuis110a9cd2013-07-03 02:23:444065static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
Fedor Indutny3f43b1c2012-02-12 15:53:434066 if (debugger_running) {
Ben Noordhuisd3c317e2014-10-13 13:19:554067 Environment* env = Environment::GetCurrent(args);
Pavel Feldman84ad31f2016-02-07 16:47:144068#if HAVE_INSPECTOR
Eugene Ostroukhov7599b0e2016-12-13 01:08:314069 if (!debug_options.debugger_enabled()) {
Pavel Feldman84ad31f2016-02-07 16:47:144070 env->inspector_agent()->Stop();
4071 } else {
4072#endif
4073 env->debugger_agent()->Stop();
4074#if HAVE_INSPECTOR
4075 }
4076#endif
Fedor Indutny3f43b1c2012-02-12 15:53:434077 debugger_running = false;
4078 }
Fedor Indutny3f43b1c2012-02-12 15:53:434079}
4080
4081
Ben Noordhuis5756f922015-01-26 22:15:204082inline void PlatformInit() {
4083#ifdef __POSIX__
Daniel Bevenius65a6e052017-04-07 06:48:324084#if HAVE_INSPECTOR
Ben Noordhuis63ae1d22015-01-26 22:26:334085 sigset_t sigmask;
4086 sigemptyset(&sigmask);
4087 sigaddset(&sigmask, SIGUSR1);
Ben Noordhuisb5f25a92015-02-18 02:43:294088 const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
Daniel Bevenius65a6e052017-04-07 06:48:324089#endif // HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:294090
4091 // Make sure file descriptors 0-2 are valid before we start logging anything.
4092 for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
4093 struct stat ignored;
4094 if (fstat(fd, &ignored) == 0)
4095 continue;
4096 // Anything but EBADF means something is seriously wrong. We don't
4097 // have to special-case EINTR, fstat() is not interruptible.
4098 if (errno != EBADF)
Evan Lucas870229e2015-09-16 15:12:414099 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:294100 if (fd != open("/dev/null", O_RDWR))
Evan Lucas870229e2015-09-16 15:12:414101 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:294102 }
4103
Daniel Bevenius65a6e052017-04-07 06:48:324104#if HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:294105 CHECK_EQ(err, 0);
Daniel Bevenius65a6e052017-04-07 06:48:324106#endif // HAVE_INSPECTOR
Ben Noordhuisdd47a8c2015-01-26 23:07:344107
Stewart X Addison0f0f3d32016-12-30 12:44:464108#ifndef NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:344109 // Restore signal dispositions, the parent process may have changed them.
4110 struct sigaction act;
4111 memset(&act, 0, sizeof(act));
4112
4113 // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
4114 // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
4115 // Counting up to SIGRTMIN doesn't work for the same reason.
Eugene Ostroukhov66269192016-06-08 21:09:284116 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
Ben Noordhuisdd47a8c2015-01-26 23:07:344117 if (nr == SIGKILL || nr == SIGSTOP)
4118 continue;
4119 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
4120 CHECK_EQ(0, sigaction(nr, &act, nullptr));
4121 }
Stewart X Addison0f0f3d32016-12-30 12:44:464122#endif // !NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:344123
Ben Noordhuis63ae1d22015-01-26 22:26:334124 RegisterSignalHandler(SIGINT, SignalExit, true);
4125 RegisterSignalHandler(SIGTERM, SignalExit, true);
Ben Noordhuisdd47a8c2015-01-26 23:07:344126
Ben Noordhuis5756f922015-01-26 22:15:204127 // Raise the open file descriptor limit.
4128 struct rlimit lim;
4129 if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
4130 // Do a binary search for the limit.
4131 rlim_t min = lim.rlim_cur;
4132 rlim_t max = 1 << 20;
4133 // But if there's a defined upper bound, don't search, just set it.
4134 if (lim.rlim_max != RLIM_INFINITY) {
4135 min = lim.rlim_max;
4136 max = lim.rlim_max;
4137 }
4138 do {
4139 lim.rlim_cur = min + (max - min) / 2;
4140 if (setrlimit(RLIMIT_NOFILE, &lim)) {
4141 max = lim.rlim_cur;
4142 } else {
4143 min = lim.rlim_cur;
4144 }
4145 } while (min + 1 < max);
4146 }
Ben Noordhuis5756f922015-01-26 22:15:204147#endif // __POSIX__
Bartosz Sosnowskibd496e02017-03-14 17:22:534148#ifdef _WIN32
4149 for (int fd = 0; fd <= 2; ++fd) {
4150 auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
4151 if (handle == INVALID_HANDLE_VALUE ||
4152 GetFileType(handle) == FILE_TYPE_UNKNOWN) {
4153 // Ignore _close result. If it fails or not depends on used Windows
4154 // version. We will just check _open result.
4155 _close(fd);
4156 if (fd != _open("nul", _O_RDWR))
4157 ABORT();
4158 }
4159 }
4160#endif // _WIN32
Ben Noordhuis5756f922015-01-26 22:15:204161}
4162
4163
Ben Noordhuis185c5152013-09-02 14:42:014164void Init(int* argc,
4165 const char** argv,
4166 int* exec_argc,
4167 const char*** exec_argv) {
Ben Noordhuis74a82152012-02-03 15:32:004168 // Initialize prog_start_time to get relative uptime.
Rasmus Christian Pedersen734fb492014-09-18 12:10:534169 prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
Ben Noordhuis74a82152012-02-03 15:32:004170
Bert Belder09be3602012-06-13 23:28:514171 // Make inherited handles noninheritable.
4172 uv_disable_stdio_inheritance();
4173
Miroslav Bajtošfbf46412013-05-02 14:42:494174 // init async debug messages dispatching
Petka Antonov4ae64b22015-03-03 20:25:474175 // Main thread uses uv_default_loop
Ben Noordhuis5e60ded2016-06-22 11:03:464176 CHECK_EQ(0, uv_async_init(uv_default_loop(),
4177 &dispatch_debug_messages_async,
4178 DispatchDebugMessagesAsyncCallback));
Ben Noordhuis9b024422015-10-29 12:33:034179 uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
Miroslav Bajtošfbf46412013-05-02 14:42:494180
Steven R. Loomis1a55e9a2016-11-03 21:36:194181#if defined(NODE_HAVE_I18N_SUPPORT)
4182 // Set the ICU casing flag early
4183 // so the user can disable a flag --foo at run-time by passing
4184 // --no_foo from the command line.
4185 const char icu_case_mapping[] = "--icu_case_mapping";
4186 V8::SetFlagsFromString(icu_case_mapping, sizeof(icu_case_mapping) - 1);
4187#endif
4188
Ben Noordhuis490d5ab2014-03-31 12:22:494189#if defined(NODE_V8_OPTIONS)
4190 // Should come before the call to V8::SetFlagsFromCommandLine()
4191 // so the user can disable a flag --foo at run-time by passing
4192 // --no_foo from the command line.
4193 V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
4194#endif
Fedor Indutnyb55c9d62014-03-26 20:30:494195
James M Snella16b5702017-03-11 20:18:534196 {
4197 std::string text;
4198 config_pending_deprecation =
4199 SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1';
4200 }
4201
Marc Udoffd3b1a2b2016-09-20 22:21:444202 // Allow for environment set preserving symlinks.
Ben Noordhuisa8734af2017-01-28 12:27:024203 {
4204 std::string text;
4205 config_preserve_symlinks =
4206 SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
Marc Udoffd3b1a2b2016-09-20 22:21:444207 }
4208
Ben Noordhuisa8734af2017-01-28 12:27:024209 if (config_warning_file.empty())
4210 SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file);
James M Snell03e89b32016-12-04 18:38:354211
Daniel Beveniuse1d88992017-02-28 19:04:124212#if HAVE_OPENSSL
Sam Roberts59afa272017-01-25 22:13:344213 if (openssl_config.empty())
4214 SafeGetenv("OPENSSL_CONF", &openssl_config);
Daniel Beveniuse1d88992017-02-28 19:04:124215#endif
Sam Roberts59afa272017-01-25 22:13:344216
Ryan Dahl38814552009-10-09 15:15:474217 // Parse a few arguments which are specific to Node.
Ben Noordhuis185c5152013-09-02 14:42:014218 int v8_argc;
4219 const char** v8_argv;
Evan Lucas5b6f5752015-06-01 14:15:104220 ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv);
4221
Ben Noordhuis9566fe82013-10-03 08:45:324222 // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
4223 // manually? That would give us a little more control over its runtime
4224 // behavior but it could also interfere with the user's intentions in ways
4225 // we fail to anticipate. Dillema.
4226 for (int i = 1; i < v8_argc; ++i) {
4227 if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
4228 v8_is_profiling = true;
4229 break;
4230 }
4231 }
4232
Oleksandr Chekhovskyi8e141352015-08-07 13:03:044233#ifdef __POSIX__
4234 // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the
4235 // performance penalty of frequent EINTR wakeups when the profiler is running.
4236 // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
4237 if (v8_is_profiling) {
4238 uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
4239 }
4240#endif
4241
Steven R. Loomisac2857b2014-09-05 05:03:244242#if defined(NODE_HAVE_I18N_SUPPORT)
Ben Noordhuisa8734af2017-01-28 12:27:024243 // If the parameter isn't given, use the env variable.
4244 if (icu_data_dir.empty())
4245 SafeGetenv("NODE_ICU_DATA", &icu_data_dir);
Steven R. Loomisac2857b2014-09-05 05:03:244246 // Initialize ICU.
Ben Noordhuisa8734af2017-01-28 12:27:024247 // If icu_data_dir is empty here, it will load the 'minimal' data.
Steven R. Loomisac2857b2014-09-05 05:03:244248 if (!i18n::InitializeICUDirectory(icu_data_dir)) {
Ben Noordhuis2d82cdf2014-10-22 01:29:324249 FatalError(nullptr, "Could not initialize ICU "
Steven R. Loomisac2857b2014-09-05 05:03:244250 "(check NODE_ICU_DATA or --icu-data-dir parameters)");
4251 }
4252#endif
Ben Noordhuis185c5152013-09-02 14:42:014253 // The const_cast doesn't violate conceptual const-ness. V8 doesn't modify
4254 // the argv array or the elements it points to.
Evan Lucas45fb3402015-09-02 07:59:214255 if (v8_argc > 1)
Evan Lucas1c20b872015-08-21 09:15:554256 V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
Ben Noordhuis185c5152013-09-02 14:42:014257
4258 // Anything that's still in v8_argv is not a V8 or a node option.
4259 for (int i = 1; i < v8_argc; i++) {
4260 fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
4261 }
4262 delete[] v8_argv;
Ben Noordhuis2d82cdf2014-10-22 01:29:324263 v8_argv = nullptr;
Ben Noordhuis185c5152013-09-02 14:42:014264
4265 if (v8_argc > 1) {
isaacsb30a03e2013-09-07 00:47:564266 exit(9);
Ryan Dahladec5442010-08-04 17:38:194267 }
Tom Hughes78da9cb2010-10-18 22:50:564268
Trevor Norris16f86d62015-09-16 04:14:184269 // Unconditionally force typed arrays to allocate outside the v8 heap. This
4270 // is to prevent memory pointers from being moved around that are returned by
4271 // Buffer::Data().
4272 const char no_typed_array_heap[] = "--typed_array_max_size_in_heap=0";
4273 V8::SetFlagsFromString(no_typed_array_heap, sizeof(no_typed_array_heap) - 1);
4274
Cheng Zhao22e1aea2015-01-12 21:31:254275 // We should set node_is_initialized here instead of in node::Start,
4276 // otherwise embedders using node::Init to initialize everything will not be
4277 // able to set it and native modules will not load for them.
4278 node_is_initialized = true;
Ben Noordhuis5866f1a2011-12-09 18:02:334279}
Ben Noordhuis356992f2011-11-22 16:10:094280
Ben Noordhuis5866f1a2011-12-09 18:02:334281
Ben Noordhuis756b6222013-08-10 22:26:114282void RunAtExit(Environment* env) {
Daniel Beveniusec539212017-03-21 07:06:434283 env->RunAtExitCallbacks();
Ben Noordhuise4a8d262012-04-21 05:13:254284}
4285
4286
Daniel Beveniusec539212017-03-21 07:06:434287static uv_key_t thread_local_env;
4288
4289
Ben Noordhuise4a8d262012-04-21 05:13:254290void AtExit(void (*cb)(void* arg), void* arg) {
Daniel Beveniusec539212017-03-21 07:06:434291 auto env = static_cast<Environment*>(uv_key_get(&thread_local_env));
4292 AtExit(env, cb, arg);
4293}
4294
4295
4296void AtExit(Environment* env, void (*cb)(void* arg), void* arg) {
4297 CHECK_NE(env, nullptr);
4298 env->AtExit(cb, arg);
Ben Noordhuise4a8d262012-04-21 05:13:254299}
4300
4301
Ben Noordhuisa2eeb432013-10-07 13:39:394302void EmitBeforeExit(Environment* env) {
Ben Noordhuisa2eeb432013-10-07 13:39:394303 HandleScope handle_scope(env->isolate());
Fedor Indutnye2c90402015-03-12 21:19:164304 Context::Scope context_scope(env->context());
Ben Noordhuisa2eeb432013-10-07 13:39:394305 Local<Object> process_object = env->process_object();
4306 Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(), "exitCode");
4307 Local<Value> args[] = {
4308 FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
Trevor Norrisd5533862015-01-07 21:29:584309 process_object->Get(exit_code)->ToInteger(env->isolate())
Ben Noordhuisa2eeb432013-10-07 13:39:394310 };
Ben Noordhuisa7581d02016-03-31 10:47:064311 MakeCallback(env, process_object, "emit", arraysize(args), args);
Ben Noordhuisa2eeb432013-10-07 13:39:394312}
4313
4314
Fedor Indutnye57ab7b2014-01-18 22:49:334315int EmitExit(Environment* env) {
Ben Noordhuis5866f1a2011-12-09 18:02:334316 // process.emit('exit')
Ben Noordhuis756b6222013-08-10 22:26:114317 HandleScope handle_scope(env->isolate());
Ben Noordhuis27f115d2013-11-11 09:53:004318 Context::Scope context_scope(env->context());
Ben Noordhuis756b6222013-08-10 22:26:114319 Local<Object> process_object = env->process_object();
Fedor Indutny75adde02014-02-21 13:02:424320 process_object->Set(env->exiting_string(), True(env->isolate()));
isaacsa5dba822013-09-06 23:46:354321
Michaël Zasso4abc8962015-07-18 09:34:164322 Local<String> exitCode = env->exit_code_string();
Rasmus Christian Pedersen734fb492014-09-18 12:10:534323 int code = process_object->Get(exitCode)->Int32Value();
isaacsa5dba822013-09-06 23:46:354324
Ben Noordhuisf674b092013-08-07 19:50:414325 Local<Value> args[] = {
Fedor Indutny75adde02014-02-21 13:02:424326 env->exit_string(),
Fedor Indutnyce04c722014-03-13 16:38:144327 Integer::New(env->isolate(), code)
Ben Noordhuisf674b092013-08-07 19:50:414328 };
isaacsa5dba822013-09-06 23:46:354329
Ben Noordhuisa7581d02016-03-31 10:47:064330 MakeCallback(env, process_object, "emit", arraysize(args), args);
Fedor Indutnyc0d81f92014-02-09 10:40:574331
4332 // Reload exit code, it may be changed by `emit('exit')`
Rasmus Christian Pedersen734fb492014-09-18 12:10:534333 return process_object->Get(exitCode)->Int32Value();
Ben Noordhuis756b6222013-08-10 22:26:114334}
4335
4336
Ben Noordhuisc3cd4532016-05-31 14:42:524337IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) {
4338 return new IsolateData(isolate, loop);
4339}
4340
4341
4342void FreeIsolateData(IsolateData* isolate_data) {
4343 delete isolate_data;
4344}
4345
4346
4347Environment* CreateEnvironment(IsolateData* isolate_data,
Michaël Zasso4abc8962015-07-18 09:34:164348 Local<Context> context,
Fedor Indutny6a610a02014-10-04 14:44:394349 int argc,
4350 const char* const* argv,
4351 int exec_argc,
4352 const char* const* exec_argv) {
Ben Noordhuisc3cd4532016-05-31 14:42:524353 Isolate* isolate = context->GetIsolate();
Ben Noordhuis756b6222013-08-10 22:26:114354 HandleScope handle_scope(isolate);
Ben Noordhuis756b6222013-08-10 22:26:114355 Context::Scope context_scope(context);
Ben Noordhuisaac79df2016-06-01 09:18:024356 auto env = new Environment(isolate_data, context);
Ben Noordhuis58cec4e2016-06-01 08:54:424357 env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
Ben Noordhuis756b6222013-08-10 22:26:114358 return env;
Ben Noordhuis5866f1a2011-12-09 18:02:334359}
4360
Micheil Smith19fd5302012-03-05 17:53:154361
Ben Noordhuisaac79df2016-06-01 09:18:024362void FreeEnvironment(Environment* env) {
4363 delete env;
4364}
4365
4366
Ben Noordhuisceb60232016-10-21 12:24:484367inline int Start(Isolate* isolate, IsolateData* isolate_data,
4368 int argc, const char* const* argv,
4369 int exec_argc, const char* const* exec_argv) {
4370 HandleScope handle_scope(isolate);
4371 Local<Context> context = Context::New(isolate);
4372 Context::Scope context_scope(context);
4373 Environment env(isolate_data, context);
Daniel Beveniusec539212017-03-21 07:06:434374 CHECK_EQ(0, uv_key_create(&thread_local_env));
4375 uv_key_set(&thread_local_env, &env);
Ben Noordhuisceb60232016-10-21 12:24:484376 env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4377
Eugene Ostroukhov7599b0e2016-12-13 01:08:314378 const char* path = argc > 1 ? argv[1] : nullptr;
4379 StartDebug(&env, path, debug_options);
Eugene Ostroukhovf9aadfb2016-11-18 21:52:224380
Eugene Ostroukhov7599b0e2016-12-13 01:08:314381 bool debugger_enabled =
4382 debug_options.debugger_enabled() || debug_options.inspector_enabled();
4383 if (debugger_enabled && !debugger_running)
4384 return 12; // Signal internal error.
Ben Noordhuisceb60232016-10-21 12:24:484385
4386 {
4387 Environment::AsyncCallbackScope callback_scope(&env);
4388 LoadEnvironment(&env);
4389 }
4390
4391 env.set_trace_sync_io(trace_sync_io);
4392
4393 // Enable debugger
Eugene Ostroukhov7599b0e2016-12-13 01:08:314394 if (debug_options.debugger_enabled())
Ben Noordhuisceb60232016-10-21 12:24:484395 EnableDebug(&env);
4396
Jason Ginchereau56e881d2017-03-20 21:55:264397 if (load_napi_modules) {
4398 ProcessEmitWarning(&env, "N-API is an experimental feature "
4399 "and could change at any time.");
4400 }
4401
Ben Noordhuisceb60232016-10-21 12:24:484402 {
4403 SealHandleScope seal(isolate);
4404 bool more;
4405 do {
4406 v8_platform.PumpMessageLoop(isolate);
4407 more = uv_run(env.event_loop(), UV_RUN_ONCE);
4408
4409 if (more == false) {
4410 v8_platform.PumpMessageLoop(isolate);
4411 EmitBeforeExit(&env);
4412
4413 // Emit `beforeExit` if the loop became alive either after emitting
4414 // event, or after running some callbacks.
4415 more = uv_loop_alive(env.event_loop());
4416 if (uv_run(env.event_loop(), UV_RUN_NOWAIT) != 0)
4417 more = true;
4418 }
4419 } while (more == true);
4420 }
4421
4422 env.set_trace_sync_io(false);
4423
4424 const int exit_code = EmitExit(&env);
4425 RunAtExit(&env);
Daniel Beveniusec539212017-03-21 07:06:434426 uv_key_delete(&thread_local_env);
Ben Noordhuisceb60232016-10-21 12:24:484427
4428 WaitForInspectorDisconnect(&env);
4429#if defined(LEAK_SANITIZER)
4430 __lsan_do_leak_check();
4431#endif
4432
4433 return exit_code;
4434}
4435
Ben Noordhuisd77e8182016-10-21 11:47:494436inline int Start(uv_loop_t* event_loop,
4437 int argc, const char* const* argv,
4438 int exec_argc, const char* const* exec_argv) {
Ben Noordhuis9a03ae62015-07-01 21:47:374439 Isolate::CreateParams params;
Ben Noordhuisceb60232016-10-21 12:24:484440 ArrayBufferAllocator allocator;
4441 params.array_buffer_allocator = &allocator;
Chunyang Daia881b532015-10-21 16:24:124442#ifdef NODE_ENABLE_VTUNE_PROFILING
4443 params.code_event_handler = vTune::GetVtuneCodeEventHandler();
4444#endif
Ben Noordhuisceb60232016-10-21 12:24:484445
4446 Isolate* const isolate = Isolate::New(params);
4447 if (isolate == nullptr)
4448 return 12; // Signal internal error.
4449
4450 isolate->AddMessageListener(OnMessage);
4451 isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
4452 isolate->SetAutorunMicrotasks(false);
4453 isolate->SetFatalErrorHandler(OnFatalError);
4454
4455 if (track_heap_objects) {
4456 isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
4457 }
Ben Noordhuis844f0a92016-03-25 16:59:074458
Ben Noordhuisd7087df2016-06-17 23:39:054459 {
4460 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuisd77e8182016-10-21 11:47:494461 CHECK_EQ(node_isolate, nullptr);
4462 node_isolate = isolate;
Ben Noordhuis844f0a92016-03-25 16:59:074463 }
Ben Noordhuis844f0a92016-03-25 16:59:074464
Ben Noordhuisd77e8182016-10-21 11:47:494465 int exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474466 {
4467 Locker locker(isolate);
4468 Isolate::Scope isolate_scope(isolate);
4469 HandleScope handle_scope(isolate);
Ben Noordhuisceb60232016-10-21 12:24:484470 IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field());
4471 exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
Petka Antonov4ae64b22015-03-03 20:25:474472 }
4473
Ben Noordhuisd7087df2016-06-17 23:39:054474 {
4475 Mutex::ScopedLock scoped_lock(node_isolate_mutex);
Ben Noordhuisceb60232016-10-21 12:24:484476 CHECK_EQ(node_isolate, isolate);
4477 node_isolate = nullptr;
Ben Noordhuisd7087df2016-06-17 23:39:054478 }
Ben Noordhuis53e64bb2015-10-26 13:11:034479
Petka Antonov4ae64b22015-03-03 20:25:474480 isolate->Dispose();
Ben Noordhuisd77e8182016-10-21 11:47:494481
4482 return exit_code;
Petka Antonov4ae64b22015-03-03 20:25:474483}
4484
Ben Noordhuis185c5152013-09-02 14:42:014485int Start(int argc, char** argv) {
Ben Noordhuisceb60232016-10-21 12:24:484486 atexit([] () { uv_tty_reset_mode(); });
Ben Noordhuis5756f922015-01-26 22:15:204487 PlatformInit();
4488
Ben Noordhuis5fdff382014-10-11 14:52:074489 CHECK_GT(argc, 0);
Micheil Smith19fd5302012-03-05 17:53:154490
Ben Noordhuis185c5152013-09-02 14:42:014491 // Hack around with the argv pointer. Used for process.title = "blah".
Ben Noordhuis1a979982012-03-15 22:10:324492 argv = uv_setup_args(argc, argv);
4493
Ben Noordhuis185c5152013-09-02 14:42:014494 // This needs to run *before* V8::Initialize(). The const_cast is not
4495 // optional, in case you're wondering.
4496 int exec_argc;
4497 const char** exec_argv;
4498 Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
Ben Noordhuis5866f1a2011-12-09 18:02:334499
Ben Noordhuis7ac23912013-09-20 20:01:494500#if HAVE_OPENSSL
Ben Noordhuisa8734af2017-01-28 12:27:024501 {
4502 std::string extra_ca_certs;
4503 if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
4504 crypto::UseExtraCaCerts(extra_ca_certs);
4505 }
Stefan Budeanu7c48cb52016-01-22 23:10:094506#ifdef NODE_FIPS_MODE
4507 // In the case of FIPS builds we should make sure
4508 // the random source is properly initialized first.
4509 OPENSSL_init();
4510#endif // NODE_FIPS_MODE
Ben Noordhuis7ac23912013-09-20 20:01:494511 // V8 on Windows doesn't have a good source of entropy. Seed it from
4512 // OpenSSL's pool.
4513 V8::SetEntropySource(crypto::EntropySource);
Ben Noordhuisa8734af2017-01-28 12:27:024514#endif // HAVE_OPENSSL
Ben Noordhuis7ac23912013-09-20 20:01:494515
Stefan Budeanu410296c2016-03-27 00:17:554516 v8_platform.Initialize(v8_thread_pool_size);
misterpoeba4847e2016-08-05 21:04:254517 // Enable tracing when argv has --trace-events-enabled.
4518 if (trace_enabled) {
4519 fprintf(stderr, "Warning: Trace event is an experimental feature "
4520 "and could change at any time.\n");
Myk Melez046f66a2017-01-31 17:56:094521 v8_platform.StartTracingAgent();
misterpoeba4847e2016-08-05 21:04:254522 }
Ben Noordhuis75ea5662013-09-23 12:27:264523 V8::Initialize();
Anna Henningsen72c60e82016-09-10 16:21:204524 v8_initialized = true;
Ben Noordhuisd77e8182016-10-21 11:47:494525 const int exit_code =
4526 Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
misterpoeba4847e2016-08-05 21:04:254527 if (trace_enabled) {
Myk Melez046f66a2017-01-31 17:56:094528 v8_platform.StopTracingAgent();
misterpoeba4847e2016-08-05 21:04:254529 }
Anna Henningsen72c60e82016-09-10 16:21:204530 v8_initialized = false;
Ryan27b268b2009-06-17 13:05:444531 V8::Dispose();
Igor Zinkovskya58b6432011-07-07 20:54:304532
Stefan Budeanu410296c2016-03-27 00:17:554533 v8_platform.Dispose();
Ben Noordhuis4a801c22015-04-02 21:51:014534
Ben Noordhuis185c5152013-09-02 14:42:014535 delete[] exec_argv;
Ben Noordhuis2d82cdf2014-10-22 01:29:324536 exec_argv = nullptr;
Micheil Smith19fd5302012-03-05 17:53:154537
Petka Antonov4ae64b22015-03-03 20:25:474538 return exit_code;
Ryan19478ed2009-03-03 00:56:154539}
Ryan Dahl124fbed2010-09-19 20:13:574540
4541
4542} // namespace node