James M Snell | 98e54b0 | 2017-01-03 21:16:48 | [diff] [blame] | 1 | // 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 Noordhuis | ff4a9d3 | 2012-03-09 23:11:11 | [diff] [blame] | 22 | #include "node.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 23 | #include "node_buffer.h" |
| 24 | #include "node_constants.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 25 | #include "node_javascript.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 26 | #include "node_version.h" |
Trevor Norris | 63da0df | 2015-05-26 18:42:14 | [diff] [blame] | 27 | #include "node_internals.h" |
James M Snell | d387591 | 2016-02-04 01:16:10 | [diff] [blame] | 28 | #include "node_revert.h" |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 29 | #include "node_debug_options.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 30 | |
| 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. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 39 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 40 | #include "node_i18n.h" |
| 41 | #endif |
| 42 | |
Ben Noordhuis | c4def50 | 2013-10-28 19:18:59 | [diff] [blame] | 43 | #if defined HAVE_DTRACE || defined HAVE_ETW |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 44 | #include "node_dtrace.h" |
| 45 | #endif |
| 46 | |
Glen Keane | 5e825d1 | 2015-01-22 12:35:16 | [diff] [blame] | 47 | #if defined HAVE_LTTNG |
| 48 | #include "node_lttng.h" |
| 49 | #endif |
| 50 | |
Bert Belder | 22d03c9 | 2012-08-06 23:48:15 | [diff] [blame] | 51 | #include "ares.h" |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 52 | #include "async-wrap.h" |
| 53 | #include "async-wrap-inl.h" |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 54 | #include "env.h" |
| 55 | #include "env-inl.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 56 | #include "handle_wrap.h" |
Ben Noordhuis | 38dc0cd | 2015-01-30 11:54:53 | [diff] [blame] | 57 | #include "req-wrap.h" |
| 58 | #include "req-wrap-inl.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 59 | #include "string_bytes.h" |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 60 | #include "tracing/agent.h" |
Timothy J Fontaine | 1a09da6 | 2014-06-10 23:36:04 | [diff] [blame] | 61 | #include "util.h" |
Ben Noordhuis | ff4a9d3 | 2012-03-09 23:11:11 | [diff] [blame] | 62 | #include "uv.h" |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 63 | #if NODE_USE_V8_PLATFORM |
Ben Noordhuis | 4a801c2 | 2015-04-02 21:51:01 | [diff] [blame] | 64 | #include "libplatform/libplatform.h" |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 65 | #endif // NODE_USE_V8_PLATFORM |
Ben Noordhuis | ff4a9d3 | 2012-03-09 23:11:11 | [diff] [blame] | 66 | #include "v8-debug.h" |
Ben Noordhuis | 57231d5 | 2013-10-02 04:37:44 | [diff] [blame] | 67 | #include "v8-profiler.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 68 | #include "zlib.h" |
Ryan Dahl | 4635ed7 | 2010-03-11 20:40:19 | [diff] [blame] | 69 | |
Chunyang Dai | a881b53 | 2015-10-21 16:24:12 | [diff] [blame] | 70 | #ifdef NODE_ENABLE_VTUNE_PROFILING |
| 71 | #include "../deps/v8/src/third_party/vtune/v8-vtune.h" |
| 72 | #endif |
| 73 | |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 74 | #include <errno.h> |
| 75 | #include <limits.h> // PATH_MAX |
Bert Belder | e0f47be | 2011-01-17 23:22:36 | [diff] [blame] | 76 | #include <locale.h> |
Bert Belder | 9cec08e | 2011-05-23 23:42:22 | [diff] [blame] | 77 | #include <signal.h> |
Ryan | 19478ed | 2009-03-03 00:56:15 | [diff] [blame] | 78 | #include <stdio.h> |
Ryan | 34a6f10 | 2009-05-28 12:47:16 | [diff] [blame] | 79 | #include <stdlib.h> |
Ryan Dahl | c90e44e | 2010-05-10 23:38:47 | [diff] [blame] | 80 | #include <string.h> |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 81 | #include <sys/types.h> |
Ben Noordhuis | c5c28c3 | 2015-10-10 13:01:49 | [diff] [blame] | 82 | |
| 83 | #include <string> |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 84 | #include <vector> |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 85 | |
Evan Lucas | 30b8bb0 | 2015-09-27 15:59:02 | [diff] [blame] | 86 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 87 | #include <unicode/uvernum.h> |
| 88 | #endif |
| 89 | |
Karl Skomski | 6ed0603 | 2015-08-14 08:07:18 | [diff] [blame] | 90 | #if defined(LEAK_SANITIZER) |
| 91 | #include <sanitizer/lsan_interface.h> |
| 92 | #endif |
| 93 | |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 94 | #if defined(_MSC_VER) |
Peter Bright | 13d6a1f | 2011-08-06 04:23:25 | [diff] [blame] | 95 | #include <direct.h> |
Peter Bright | b9d7777 | 2011-08-11 01:45:56 | [diff] [blame] | 96 | #include <io.h> |
Ben Noordhuis | e6e7891 | 2015-12-04 23:31:49 | [diff] [blame] | 97 | #define getpid GetCurrentProcessId |
Peter Bright | b9d7777 | 2011-08-11 01:45:56 | [diff] [blame] | 98 | #define umask _umask |
| 99 | typedef int mode_t; |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 100 | #else |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 101 | #include <pthread.h> |
Ben Noordhuis | 6820054 | 2013-10-02 10:17:57 | [diff] [blame] | 102 | #include <sys/resource.h> // getrlimit, setrlimit |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 103 | #include <unistd.h> // setuid, getuid |
Peter Bright | 13d6a1f | 2011-08-06 04:23:25 | [diff] [blame] | 104 | #endif |
Ryan | e02b71e | 2009-03-03 23:31:37 | [diff] [blame] | 105 | |
Linus MÃ¥rtensson | 5e4e8ec | 2013-05-08 12:10:07 | [diff] [blame] | 106 | #if defined(__POSIX__) && !defined(__ANDROID__) |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 107 | #include <pwd.h> // getpwnam() |
| 108 | #include <grp.h> // getgrnam() |
Bert Belder | a177d60 | 2010-11-25 00:02:55 | [diff] [blame] | 109 | #endif |
| 110 | |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 111 | #ifdef __APPLE__ |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 112 | #include <crt_externs.h> |
| 113 | #define environ (*_NSGetEnviron()) |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 114 | #elif !defined(_MSC_VER) |
Ryan | 3e4fc9f | 2009-09-10 14:48:38 | [diff] [blame] | 115 | extern char **environ; |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 116 | #endif |
Ryan | 3e4fc9f | 2009-09-10 14:48:38 | [diff] [blame] | 117 | |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 118 | namespace node { |
| 119 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 120 | using v8::Array; |
Ben Noordhuis | 0693d22 | 2013-06-29 06:16:25 | [diff] [blame] | 121 | using v8::ArrayBuffer; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 122 | using v8::Boolean; |
| 123 | using v8::Context; |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 124 | using v8::EscapableHandleScope; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 125 | using v8::Exception; |
Patrick Mueller | 52cb410 | 2016-04-05 13:17:48 | [diff] [blame] | 126 | using v8::Float64Array; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 127 | using v8::Function; |
| 128 | using v8::FunctionCallbackInfo; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 129 | using v8::HandleScope; |
| 130 | using v8::HeapStatistics; |
| 131 | using v8::Integer; |
| 132 | using v8::Isolate; |
Ben Noordhuis | 511af4d | 2013-07-30 19:28:43 | [diff] [blame] | 133 | using v8::Local; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 134 | using v8::Locker; |
Michaël Zasso | 023c317 | 2016-02-08 21:34:05 | [diff] [blame] | 135 | using v8::MaybeLocal; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 136 | using v8::Message; |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 137 | using v8::Name; |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 138 | using v8::NamedPropertyHandlerConfiguration; |
Jeremiah Senkpiel | 21d66d6 | 2016-03-23 22:09:10 | [diff] [blame] | 139 | using v8::Null; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 140 | using v8::Number; |
| 141 | using v8::Object; |
| 142 | using v8::ObjectTemplate; |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 143 | using v8::Promise; |
| 144 | using v8::PromiseRejectMessage; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 145 | using v8::PropertyCallbackInfo; |
Michaël Zasso | 023c317 | 2016-02-08 21:34:05 | [diff] [blame] | 146 | using v8::ScriptOrigin; |
Fedor Indutny | a07c691 | 2015-04-11 14:02:33 | [diff] [blame] | 147 | using v8::SealHandleScope; |
Ben Noordhuis | 511af4d | 2013-07-30 19:28:43 | [diff] [blame] | 148 | using v8::String; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 149 | using v8::TryCatch; |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 150 | using v8::Uint32Array; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 151 | using v8::V8; |
| 152 | using v8::Value; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 153 | |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 154 | static bool print_eval = false; |
| 155 | static bool force_repl = false; |
Dave Eddy | 2e6ece4 | 2015-08-17 21:33:13 | [diff] [blame] | 156 | static bool syntax_check_only = false; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 157 | static bool trace_deprecation = false; |
| 158 | static bool throw_deprecation = false; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 159 | static bool trace_sync_io = false; |
Bradley Meck | cf14a24 | 2015-07-09 16:15:26 | [diff] [blame] | 160 | static bool track_heap_objects = false; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 161 | static const char* eval_string = nullptr; |
Sam Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 162 | static std::vector<std::string> preload_modules; |
Tom Gallacher | 03e07d3 | 2015-12-18 12:24:56 | [diff] [blame] | 163 | static const int v8_default_thread_pool_size = 4; |
| 164 | static int v8_thread_pool_size = v8_default_thread_pool_size; |
Matt Loring | 49440b7 | 2015-11-25 14:08:58 | [diff] [blame] | 165 | static bool prof_process = false; |
Ben Noordhuis | 9566fe8 | 2013-10-03 08:45:32 | [diff] [blame] | 166 | static bool v8_is_profiling = false; |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 167 | static bool node_is_initialized = false; |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 168 | static node_module* modpending; |
| 169 | static node_module* modlist_builtin; |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 170 | static node_module* modlist_linked; |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 171 | static node_module* modlist_addon; |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 172 | static bool trace_enabled = false; |
Sam Roberts | 809ca2f | 2017-04-05 19:09:32 | [diff] [blame] | 173 | static std::string trace_enabled_categories; // NOLINT(runtime/string) |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 174 | |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 175 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 176 | // Path to ICU data (for i18n / Intl) |
Ben Noordhuis | 46345b9 | 2017-02-11 13:00:22 | [diff] [blame] | 177 | std::string icu_data_dir; // NOLINT(runtime/string) |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 178 | #endif |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 179 | |
Jason Ginchereau | 56e881d | 2017-03-20 21:55:26 | [diff] [blame] | 180 | // N-API is in experimental state, disabled by default. |
| 181 | bool load_napi_modules = false; |
| 182 | |
isaacs | 48c3d20 | 2012-06-21 19:20:23 | [diff] [blame] | 183 | // used by C++ modules as well |
| 184 | bool no_deprecation = false; |
| 185 | |
Fedor Indutny | db411cf | 2016-09-29 08:53:30 | [diff] [blame] | 186 | #if HAVE_OPENSSL |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 187 | // use OpenSSL's cert store instead of bundled certs |
| 188 | bool ssl_openssl_cert_store = |
| 189 | #if defined(NODE_OPENSSL_CERT_STORE) |
| 190 | true; |
| 191 | #else |
| 192 | false; |
| 193 | #endif |
| 194 | |
Fedor Indutny | db411cf | 2016-09-29 08:53:30 | [diff] [blame] | 195 | # if NODE_FIPS_MODE |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 196 | // used by crypto module |
| 197 | bool enable_fips_crypto = false; |
| 198 | bool force_fips_crypto = false; |
Fedor Indutny | db411cf | 2016-09-29 08:53:30 | [diff] [blame] | 199 | # endif // NODE_FIPS_MODE |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 200 | std::string openssl_config; // NOLINT(runtime/string) |
Fedor Indutny | db411cf | 2016-09-29 08:53:30 | [diff] [blame] | 201 | #endif // HAVE_OPENSSL |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 202 | |
James M Snell | c6656db | 2016-01-20 19:38:35 | [diff] [blame] | 203 | // true if process warnings should be suppressed |
| 204 | bool no_process_warnings = false; |
| 205 | bool trace_warnings = false; |
| 206 | |
James M Snell | 5d38d54 | 2016-05-02 23:31:20 | [diff] [blame] | 207 | // 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 |
| 210 | bool config_preserve_symlinks = false; |
| 211 | |
James M Snell | a16b570 | 2017-03-11 20:18:53 | [diff] [blame^] | 212 | // Set by ParseArgs when --pending-deprecation or NODE_PENDING_DEPRECATION |
| 213 | // is used. |
| 214 | bool config_pending_deprecation = false; |
| 215 | |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 216 | // Set in node.cc by ParseArgs when --redirect-warnings= is used. |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 217 | std::string config_warning_file; // NOLINT(runtime/string) |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 218 | |
Sam Roberts | 8086cb6 | 2017-04-05 21:06:52 | [diff] [blame] | 219 | // 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 |
| 223 | bool config_expose_internals = false; |
| 224 | |
Anna Henningsen | 72c60e8 | 2016-09-10 16:21:20 | [diff] [blame] | 225 | bool v8_initialized = false; |
| 226 | |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 227 | // process-relative uptime base, initialized at start-up |
| 228 | static double prog_start_time; |
Ben Noordhuis | ca363cf | 2013-10-15 21:32:18 | [diff] [blame] | 229 | static bool debugger_running; |
Ben Noordhuis | 5d0816b | 2013-01-06 22:06:48 | [diff] [blame] | 230 | static uv_async_t dispatch_debug_messages_async; |
| 231 | |
Ben Noordhuis | d7087df | 2016-06-17 23:39:05 | [diff] [blame] | 232 | static Mutex node_isolate_mutex; |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 233 | static v8::Isolate* node_isolate; |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 234 | |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 235 | static node::DebugOptions debug_options; |
| 236 | |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 237 | static 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_); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 242 | tracing::TraceEventHelper::SetCurrentPlatform(platform_); |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 243 | } |
| 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 Noordhuis | c5c28c3 | 2015-10-10 13:01:49 | [diff] [blame] | 254 | #if HAVE_INSPECTOR |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 255 | bool StartInspector(Environment *env, const char* script_path, |
| 256 | const node::DebugOptions& options) { |
| 257 | return env->inspector_agent()->Start(platform_, script_path, options); |
Ben Noordhuis | c5c28c3 | 2015-10-10 13:01:49 | [diff] [blame] | 258 | } |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 259 | #endif // HAVE_INSPECTOR |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 260 | |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 261 | 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 Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 271 | v8::Platform* platform_; |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 272 | tracing::Agent* tracing_agent_; |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 273 | #else // !NODE_USE_V8_PLATFORM |
| 274 | void Initialize(int thread_pool_size) {} |
| 275 | void PumpMessageLoop(Isolate* isolate) {} |
| 276 | void Dispose() {} |
Eugene Ostroukhov | 609a265 | 2016-06-10 01:00:08 | [diff] [blame] | 277 | bool StartInspector(Environment *env, const char* script_path, |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 278 | const node::DebugOptions& options) { |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 279 | env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0"); |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 280 | return true; |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 281 | } |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 282 | |
| 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 Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 288 | #endif // !NODE_USE_V8_PLATFORM |
| 289 | } v8_platform; |
Ben Noordhuis | 5d0816b | 2013-01-06 22:06:48 | [diff] [blame] | 290 | |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 291 | #ifdef __POSIX__ |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 292 | static const unsigned kMaxSignal = 32; |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 293 | #endif |
| 294 | |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 295 | static 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 Usta | 44a298b | 2015-10-28 12:49:51 | [diff] [blame] | 306 | va_end(ap); |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 307 | 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 Vavilov | 09f861f | 2016-07-16 17:06:47 | [diff] [blame] | 320 | |
| 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 White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 324 | #else |
| 325 | vfprintf(stderr, format, ap); |
| 326 | #endif |
| 327 | va_end(ap); |
| 328 | } |
| 329 | |
| 330 | |
Saúl Ibarra Corretgé | 42b9343 | 2014-03-12 23:08:29 | [diff] [blame] | 331 | static void CheckImmediate(uv_check_t* handle) { |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 332 | Environment* env = Environment::from_immediate_check_handle(handle); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 333 | HandleScope scope(env->isolate()); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 334 | Context::Scope context_scope(env->context()); |
| 335 | MakeCallback(env, env->process_object(), env->immediate_callback_string()); |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | |
Saúl Ibarra Corretgé | 42b9343 | 2014-03-12 23:08:29 | [diff] [blame] | 339 | static void IdleImmediateDummy(uv_idle_t* handle) { |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 340 | // Do nothing. Only for maintaining event loop. |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 341 | // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks. |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 342 | } |
| 343 | |
| 344 | |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 345 | static inline const char *errno_string(int errorno) { |
| 346 | #define ERRNO_CASE(e) case e: return #e; |
| 347 | switch (errorno) { |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 348 | #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 Dahl | 9b2aac6 | 2010-04-28 19:58:00 | [diff] [blame] | 366 | #endif |
| 367 | |
| 368 | #ifdef EWOULDBLOCK |
| 369 | # if EAGAIN != EWOULDBLOCK |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 370 | 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 Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 534 | #ifdef ENOLINK |
| 535 | ERRNO_CASE(ENOLINK); |
| 536 | #endif |
| 537 | |
Ryan Dahl | 3bb21b5 | 2010-04-28 22:07:15 | [diff] [blame] | 538 | #ifdef ENOLCK |
| 539 | # if ENOLINK != ENOLCK |
| 540 | ERRNO_CASE(ENOLCK); |
| 541 | # endif |
| 542 | #endif |
| 543 | |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 544 | #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 Dawson | 2a17c7f | 2015-08-12 15:53:33 | [diff] [blame] | 581 | # if ENOTEMPTY != EEXIST |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 582 | ERRNO_CASE(ENOTEMPTY); |
Michael Dawson | 2a17c7f | 2015-08-12 15:53:33 | [diff] [blame] | 583 | # endif |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 584 | #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örfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 671 | const char *signo_string(int signo) { |
| 672 | #define SIGNO_CASE(e) case e: return #e; |
| 673 | switch (signo) { |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 674 | #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 Belder | dcc3508 | 2010-11-25 00:04:31 | [diff] [blame] | 737 | |
| 738 | #ifdef SIGCHLD |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 739 | SIGNO_CASE(SIGCHLD); |
Bert Belder | dcc3508 | 2010-11-25 00:04:31 | [diff] [blame] | 740 | #endif |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 741 | |
| 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 Belder | 600a646 | 2012-08-20 21:59:21 | [diff] [blame] | 759 | #ifdef SIGBREAK |
| 760 | SIGNO_CASE(SIGBREAK); |
| 761 | #endif |
| 762 | |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 763 | #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 Dahl | 3bb21b5 | 2010-04-28 22:07:15 | [diff] [blame] | 800 | # if SIGPOLL != SIGIO |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 801 | SIGNO_CASE(SIGPOLL); |
Ryan Dahl | 3bb21b5 | 2010-04-28 22:07:15 | [diff] [blame] | 802 | # endif |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 803 | #endif |
| 804 | |
| 805 | #ifdef SIGLOST |
Michael Dawson | 2a17c7f | 2015-08-12 15:53:33 | [diff] [blame] | 806 | # if SIGLOST != SIGABRT |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 807 | SIGNO_CASE(SIGLOST); |
Michael Dawson | 2a17c7f | 2015-08-12 15:53:33 | [diff] [blame] | 808 | # endif |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 809 | #endif |
| 810 | |
| 811 | #ifdef SIGPWR |
Raffaele Sena | b3b81d6 | 2010-06-09 04:08:05 | [diff] [blame] | 812 | # if SIGPWR != SIGLOST |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 813 | SIGNO_CASE(SIGPWR); |
Raffaele Sena | b3b81d6 | 2010-06-09 04:08:05 | [diff] [blame] | 814 | # endif |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 815 | #endif |
| 816 | |
James Reggio | fb5f66a | 2016-04-07 01:00:04 | [diff] [blame] | 817 | #ifdef SIGINFO |
| 818 | # if !defined(SIGPWR) || SIGINFO != SIGPWR |
| 819 | SIGNO_CASE(SIGINFO); |
| 820 | # endif |
| 821 | #endif |
| 822 | |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 823 | #ifdef SIGSYS |
| 824 | SIGNO_CASE(SIGSYS); |
| 825 | #endif |
| 826 | |
Felix Geisendörfer | f8a3cf9 | 2010-04-28 13:04:08 | [diff] [blame] | 827 | default: return ""; |
| 828 | } |
| 829 | } |
| 830 | |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 831 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 832 | Local<Value> ErrnoException(Isolate* isolate, |
| 833 | int errorno, |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 834 | const char *syscall, |
visionmedia | 45948e0 | 2010-05-14 14:52:49 | [diff] [blame] | 835 | const char *msg, |
| 836 | const char *path) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 837 | Environment* env = Environment::GetCurrent(isolate); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 838 | |
visionmedia | 45948e0 | 2010-05-14 14:52:49 | [diff] [blame] | 839 | Local<Value> e; |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 840 | Local<String> estring = OneByteString(env->isolate(), errno_string(errorno)); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 841 | if (msg == nullptr || msg[0] == '\0') { |
Bert Belder | 2ce0961 | 2011-01-17 21:47:59 | [diff] [blame] | 842 | msg = strerror(errorno); |
Bert Belder | 2ce0961 | 2011-01-17 21:47:59 | [diff] [blame] | 843 | } |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 844 | Local<String> message = OneByteString(env->isolate(), msg); |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 845 | |
Ben Noordhuis | 4f39499 | 2015-03-13 18:15:18 | [diff] [blame] | 846 | Local<String> cons = |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 847 | String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", ")); |
Ben Noordhuis | 4f39499 | 2015-03-13 18:15:18 | [diff] [blame] | 848 | cons = String::Concat(cons, message); |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 849 | |
Ben Noordhuis | 4f39499 | 2015-03-13 18:15:18 | [diff] [blame] | 850 | 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); |
visionmedia | 45948e0 | 2010-05-14 14:52:49 | [diff] [blame] | 854 | } |
| 855 | |
Ben Noordhuis | 4f39499 | 2015-03-13 18:15:18 | [diff] [blame] | 856 | 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 Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 863 | Local<Object> obj = e->ToObject(env->isolate()); |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 864 | obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno)); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 865 | obj->Set(env->code_string(), estring); |
visionmedia | 45948e0 | 2010-05-14 14:52:49 | [diff] [blame] | 866 | |
Ben Noordhuis | 4f39499 | 2015-03-13 18:15:18 | [diff] [blame] | 867 | if (path_string.IsEmpty() == false) { |
| 868 | obj->Set(env->path_string(), path_string); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 869 | } |
| 870 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 871 | if (syscall != nullptr) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 872 | obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall)); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 873 | } |
| 874 | |
Ryan Dahl | c9e27b1 | 2010-04-23 00:53:45 | [diff] [blame] | 875 | return e; |
| 876 | } |
| 877 | |
| 878 | |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 879 | static 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 Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 893 | Local<Value> UVException(Isolate* isolate, |
| 894 | int errorno, |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 895 | const char* syscall, |
| 896 | const char* msg, |
| 897 | const char* path) { |
| 898 | return UVException(isolate, errorno, syscall, msg, path, nullptr); |
| 899 | } |
| 900 | |
| 901 | |
| 902 | Local<Value> UVException(Isolate* isolate, |
| 903 | int errorno, |
| 904 | const char* syscall, |
| 905 | const char* msg, |
| 906 | const char* path, |
| 907 | const char* dest) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 908 | Environment* env = Environment::GetCurrent(isolate); |
Bert Belder | 823a443 | 2011-12-01 23:02:51 | [diff] [blame] | 909 | |
| 910 | if (!msg || !msg[0]) |
Ben Noordhuis | ca9eb71 | 2013-07-18 21:18:50 | [diff] [blame] | 911 | msg = uv_strerror(errorno); |
Bert Belder | 823a443 | 2011-12-01 23:02:51 | [diff] [blame] | 912 | |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 913 | 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 Belder | 823a443 | 2011-12-01 23:02:51 | [diff] [blame] | 917 | |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 918 | 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 923 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 924 | if (path != nullptr) { |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 925 | 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 930 | } |
| 931 | |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 932 | 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 938 | } |
| 939 | |
Bert Belder | bc2c85c | 2015-01-31 10:48:34 | [diff] [blame] | 940 | 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 Belder | 823a443 | 2011-12-01 23:02:51 | [diff] [blame] | 952 | return e; |
| 953 | } |
| 954 | |
| 955 | |
Ben Noordhuis | 8f6c587 | 2014-10-11 19:48:25 | [diff] [blame] | 956 | // Look up environment variable unless running as setuid root. |
Sam Roberts | 901e926 | 2017-01-27 19:49:14 | [diff] [blame] | 957 | bool SafeGetenv(const char* key, std::string* text) { |
Ben Noordhuis | 8f6c587 | 2014-10-11 19:48:25 | [diff] [blame] | 958 | #ifndef _WIN32 |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 959 | // 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 Noordhuis | 8f6c587 | 2014-10-11 19:48:25 | [diff] [blame] | 965 | #endif |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 966 | if (const char* value = getenv(key)) { |
| 967 | *text = value; |
| 968 | return true; |
| 969 | } |
| 970 | text->clear(); |
| 971 | return false; |
Ben Noordhuis | 8f6c587 | 2014-10-11 19:48:25 | [diff] [blame] | 972 | } |
| 973 | |
| 974 | |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 975 | #ifdef _WIN32 |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 976 | // Does about the same as strerror(), |
| 977 | // but supports all windows error messages |
Alexis Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 978 | static const char *winapi_strerror(const int errorno, bool* must_free) { |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 979 | char *errmsg = nullptr; |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 980 | |
| 981 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 982 | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno, |
| 983 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr); |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 984 | |
| 985 | if (errmsg) { |
Alexis Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 986 | *must_free = true; |
| 987 | |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 988 | // 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 Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 997 | *must_free = false; |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 998 | return "Unknown error"; |
| 999 | } |
| 1000 | } |
| 1001 | |
| 1002 | |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1003 | Local<Value> WinapiErrnoException(Isolate* isolate, |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1004 | int errorno, |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 1005 | const char* syscall, |
| 1006 | const char* msg, |
| 1007 | const char* path) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1008 | Environment* env = Environment::GetCurrent(isolate); |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1009 | Local<Value> e; |
Alexis Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 1010 | bool must_free = false; |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 1011 | if (!msg || !msg[0]) { |
Alexis Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 1012 | msg = winapi_strerror(errorno, &must_free); |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1013 | } |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1014 | Local<String> message = OneByteString(env->isolate(), msg); |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1015 | |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1016 | if (path) { |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1017 | Local<String> cons1 = |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1018 | String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '")); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1019 | Local<String> cons2 = |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1020 | String::Concat(cons1, String::NewFromUtf8(isolate, path)); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1021 | Local<String> cons3 = |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1022 | String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'")); |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1023 | e = Exception::Error(cons3); |
| 1024 | } else { |
| 1025 | e = Exception::Error(message); |
| 1026 | } |
| 1027 | |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 1028 | Local<Object> obj = e->ToObject(env->isolate()); |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1029 | obj->Set(env->errno_string(), Integer::New(isolate, errorno)); |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1030 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1031 | if (path != nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1032 | obj->Set(env->path_string(), String::NewFromUtf8(isolate, path)); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1033 | } |
| 1034 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1035 | if (syscall != nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 1036 | obj->Set(env->syscall_string(), OneByteString(isolate, syscall)); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1037 | } |
| 1038 | |
Alexis Campailla | 93f3b64 | 2014-08-05 13:33:16 | [diff] [blame] | 1039 | if (must_free) |
| 1040 | LocalFree((HLOCAL)msg); |
| 1041 | |
Bert Belder | 6ee73a2 | 2011-11-04 15:10:48 | [diff] [blame] | 1042 | return e; |
| 1043 | } |
| 1044 | #endif |
| 1045 | |
| 1046 | |
Trevor Norris | 74178a5 | 2015-09-14 22:31:10 | [diff] [blame] | 1047 | void* ArrayBufferAllocator::Allocate(size_t size) { |
Ben Noordhuis | 27e84dd | 2016-05-31 18:58:31 | [diff] [blame] | 1048 | if (zero_fill_field_ || zero_fill_all_buffers) |
Anna Henningsen | ea94086 | 2016-09-10 16:19:24 | [diff] [blame] | 1049 | return node::UncheckedCalloc(size); |
Ben Noordhuis | 3a39963 | 2016-06-01 13:53:01 | [diff] [blame] | 1050 | else |
Anna Henningsen | ea94086 | 2016-09-10 16:19:24 | [diff] [blame] | 1051 | return node::UncheckedMalloc(size); |
Trevor Norris | 74178a5 | 2015-09-14 22:31:10 | [diff] [blame] | 1052 | } |
| 1053 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 1054 | namespace { |
| 1055 | |
| 1056 | bool DomainHasErrorHandler(const Environment* env, |
| 1057 | const Local<Object>& domain) { |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1058 | HandleScope scope(env->isolate()); |
Trevor Norris | 74178a5 | 2015-09-14 22:31:10 | [diff] [blame] | 1059 | |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1060 | 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 Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 1078 | bool DomainsStackHasErrorHandler(const Environment* env) { |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1079 | HandleScope scope(env->isolate()); |
| 1080 | |
Jeremy Whitlock | 77a10ed | 2015-10-05 20:08:53 | [diff] [blame] | 1081 | if (!env->using_domains()) |
| 1082 | return false; |
| 1083 | |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1084 | Local<Array> domains_stack_array = env->domains_stack_array().As<Array>(); |
| 1085 | if (domains_stack_array->Length() == 0) |
Jeremy Whitlock | 77a10ed | 2015-10-05 20:08:53 | [diff] [blame] | 1086 | return false; |
| 1087 | |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1088 | 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 Whitlock | 77a10ed | 2015-10-05 20:08:53 | [diff] [blame] | 1100 | } |
| 1101 | |
| 1102 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 1103 | bool ShouldAbortOnUncaughtException(Isolate* isolate) { |
Jeremy Whitlock | 77a10ed | 2015-10-05 20:08:53 | [diff] [blame] | 1104 | 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 Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1113 | return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env); |
Jeremy Whitlock | 77a10ed | 2015-10-05 20:08:53 | [diff] [blame] | 1114 | } |
| 1115 | |
| 1116 | |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1117 | void SetupDomainUse(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1118 | Environment* env = Environment::GetCurrent(args); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1119 | |
| 1120 | if (env->using_domains()) |
| 1121 | return; |
| 1122 | env->set_using_domains(true); |
| 1123 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1124 | HandleScope scope(env->isolate()); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1125 | Local<Object> process_object = env->process_object(); |
| 1126 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1127 | Local<String> tick_callback_function_key = env->tick_domain_cb_string(); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1128 | 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 Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 1133 | ABORT(); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1134 | } |
| 1135 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1136 | process_object->Set(env->tick_callback_string(), tick_callback_function); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1137 | env->set_tick_callback_function(tick_callback_function); |
| 1138 | |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 1139 | CHECK(args[0]->IsArray()); |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1140 | env->set_domain_array(args[0].As<Array>()); |
| 1141 | |
Julien Gilli | 425a354 | 2015-11-03 01:56:24 | [diff] [blame] | 1142 | CHECK(args[1]->IsArray()); |
| 1143 | env->set_domains_stack_array(args[1].As<Array>()); |
| 1144 | |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1145 | // Do a little housekeeping. |
| 1146 | env->process_object()->Delete( |
Michaël Zasso | d45045f | 2016-02-08 21:42:04 | [diff] [blame] | 1147 | env->context(), |
| 1148 | FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust(); |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 1149 | |
| 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 Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1157 | } |
| 1158 | |
Vladimir Kurchatkin | 30bd7b6 | 2014-09-04 16:02:04 | [diff] [blame] | 1159 | void RunMicrotasks(const FunctionCallbackInfo<Value>& args) { |
| 1160 | args.GetIsolate()->RunMicrotasks(); |
| 1161 | } |
| 1162 | |
Trevor Norris | 828f145 | 2014-01-09 19:11:40 | [diff] [blame] | 1163 | |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1164 | void SetupProcessObject(const FunctionCallbackInfo<Value>& args) { |
| 1165 | Environment* env = Environment::GetCurrent(args); |
| 1166 | |
| 1167 | CHECK(args[0]->IsFunction()); |
| 1168 | |
Trevor Norris | 83524b3 | 2015-11-10 09:58:51 | [diff] [blame] | 1169 | env->set_push_values_to_array_function(args[0].As<Function>()); |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1170 | env->process_object()->Delete( |
Michaël Zasso | d45045f | 2016-02-08 21:42:04 | [diff] [blame] | 1171 | env->context(), |
| 1172 | FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust(); |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1173 | } |
| 1174 | |
| 1175 | |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1176 | void SetupNextTick(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1177 | Environment* env = Environment::GetCurrent(args); |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1178 | |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 1179 | CHECK(args[0]->IsFunction()); |
| 1180 | CHECK(args[1]->IsObject()); |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1181 | |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 1182 | env->set_tick_callback_function(args[0].As<Function>()); |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1183 | |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 1184 | env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks); |
Vladimir Kurchatkin | 30bd7b6 | 2014-09-04 16:02:04 | [diff] [blame] | 1185 | |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1186 | // Do a little housekeeping. |
| 1187 | env->process_object()->Delete( |
Michaël Zasso | d45045f | 2016-02-08 21:42:04 | [diff] [blame] | 1188 | env->context(), |
| 1189 | FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick")).FromJust(); |
Ben Noordhuis | 70d1f32 | 2015-06-19 11:23:56 | [diff] [blame] | 1190 | |
| 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 Norris | 3f5d584 | 2013-08-07 00:01:44 | [diff] [blame] | 1199 | } |
| 1200 | |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 1201 | void 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 Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 1216 | callback->Call(process, arraysize(args), args); |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 1217 | } |
| 1218 | |
| 1219 | void 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 Zasso | d45045f | 2016-02-08 21:42:04 | [diff] [blame] | 1229 | env->context(), |
| 1230 | FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises")).FromJust(); |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 1231 | } |
| 1232 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 1233 | } // anonymous namespace |
| 1234 | |
Trevor Norris | 3f5d584 | 2013-08-07 00:01:44 | [diff] [blame] | 1235 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1236 | Local<Value> MakeCallback(Environment* env, |
Trevor Norris | f86a3a2 | 2016-02-11 20:10:47 | [diff] [blame] | 1237 | Local<Value> recv, |
| 1238 | const Local<Function> callback, |
| 1239 | int argc, |
| 1240 | Local<Value> argv[]) { |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1241 | // If you hit this assertion, you forgot to enter the v8::Context first. |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 1242 | CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); |
Trevor Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1243 | |
Trevor Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1244 | Local<Function> pre_fn = env->async_hooks_pre_function(); |
| 1245 | Local<Function> post_fn = env->async_hooks_post_function(); |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1246 | Local<Object> object, domain; |
Trevor Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1247 | bool ran_init_callback = false; |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1248 | bool has_domain = false; |
| 1249 | |
Trevor Norris | e919224 | 2016-01-05 22:33:21 | [diff] [blame] | 1250 | Environment::AsyncCallbackScope callback_scope(env); |
| 1251 | |
Trevor Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1252 | // 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 Norris | b9e6032 | 2014-12-09 04:10:44 | [diff] [blame] | 1254 | 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 Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1258 | ran_init_callback = true; |
Trevor Norris | b9e6032 | 2014-12-09 04:10:44 | [diff] [blame] | 1259 | } |
| 1260 | |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1261 | if (env->using_domains()) { |
| 1262 | CHECK(recv->IsObject()); |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1263 | 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 Norris | efa62fd | 2013-09-24 21:12:11 | [diff] [blame] | 1271 | |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1272 | if (has_domain) { |
| 1273 | Local<Value> enter_v = domain->Get(env->enter_string()); |
| 1274 | if (enter_v->IsFunction()) { |
Trevor Norris | 95afe28 | 2016-02-11 20:57:26 | [diff] [blame] | 1275 | if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) { |
| 1276 | FatalError("node::MakeCallback", |
| 1277 | "domain enter callback threw, please report this"); |
| 1278 | } |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1279 | } |
| 1280 | } |
| 1281 | |
Trevor Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1282 | if (ran_init_callback && !pre_fn.IsEmpty()) { |
Trevor Norris | a17200b | 2016-03-14 18:35:22 | [diff] [blame] | 1283 | 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 Norris | b9e6032 | 2014-12-09 04:10:44 | [diff] [blame] | 1290 | } |
| 1291 | |
Ben Noordhuis | 1f2f3fa | 2014-01-27 02:58:16 | [diff] [blame] | 1292 | Local<Value> ret = callback->Call(recv, argc, argv); |
isaacs | 10ce3d1 | 2012-04-13 23:27:23 | [diff] [blame] | 1293 | |
Trevor Norris | aeee956 | 2015-10-02 00:57:36 | [diff] [blame] | 1294 | if (ran_init_callback && !post_fn.IsEmpty()) { |
Trevor Norris | 20337ad | 2016-02-23 05:50:56 | [diff] [blame] | 1295 | 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 Norris | a17200b | 2016-03-14 18:35:22 | [diff] [blame] | 1300 | TryCatch try_catch(env->isolate()); |
| 1301 | MaybeLocal<Value> ar = |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 1302 | post_fn->Call(env->context(), object, arraysize(vals), vals); |
Trevor Norris | a17200b | 2016-03-14 18:35:22 | [diff] [blame] | 1303 | if (ar.IsEmpty()) { |
| 1304 | ClearFatalExceptionHandlers(env); |
| 1305 | FatalException(env->isolate(), try_catch); |
| 1306 | return Local<Value>(); |
| 1307 | } |
Trevor Norris | 575b84e | 2016-02-11 20:09:52 | [diff] [blame] | 1308 | } |
| 1309 | |
Trevor Norris | 575b84e | 2016-02-11 20:09:52 | [diff] [blame] | 1310 | if (ret.IsEmpty()) { |
Trevor Norris | 2dadd89 | 2016-03-23 23:02:04 | [diff] [blame] | 1311 | // 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 Norris | b9e6032 | 2014-12-09 04:10:44 | [diff] [blame] | 1315 | } |
| 1316 | |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1317 | if (has_domain) { |
| 1318 | Local<Value> exit_v = domain->Get(env->exit_string()); |
| 1319 | if (exit_v->IsFunction()) { |
Trevor Norris | 95afe28 | 2016-02-11 20:57:26 | [diff] [blame] | 1320 | if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) { |
| 1321 | FatalError("node::MakeCallback", |
| 1322 | "domain exit callback threw, please report this"); |
| 1323 | } |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1324 | } |
| 1325 | } |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1326 | |
Trevor Norris | 41f333e | 2016-03-11 19:55:59 | [diff] [blame] | 1327 | 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 Norris | 8f8db14 | 2016-12-15 00:17:10 | [diff] [blame] | 1341 | return ret; |
Trevor Norris | 41f333e | 2016-03-11 19:55:59 | [diff] [blame] | 1342 | } |
| 1343 | |
| 1344 | if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1345 | return Undefined(env->isolate()); |
Trevor Norris | 95afe28 | 2016-02-11 20:57:26 | [diff] [blame] | 1346 | } |
Trevor Norris | 86c0745 | 2013-02-07 01:26:18 | [diff] [blame] | 1347 | |
Trevor Norris | a0867e1 | 2013-03-17 04:59:47 | [diff] [blame] | 1348 | return ret; |
| 1349 | } |
| 1350 | |
| 1351 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1352 | Local<Value> MakeCallback(Environment* env, |
| 1353 | Local<Object> recv, |
| 1354 | Local<String> symbol, |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1355 | int argc, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1356 | Local<Value> argv[]) { |
Trevor Norris | a1da024 | 2014-12-09 04:24:59 | [diff] [blame] | 1357 | 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 Norris | 86c0745 | 2013-02-07 01:26:18 | [diff] [blame] | 1360 | } |
| 1361 | |
| 1362 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1363 | Local<Value> MakeCallback(Environment* env, |
| 1364 | Local<Object> recv, |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1365 | const char* method, |
| 1366 | int argc, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1367 | Local<Value> argv[]) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1368 | Local<String> method_string = OneByteString(env->isolate(), method); |
Ben Noordhuis | 1f2f3fa | 2014-01-27 02:58:16 | [diff] [blame] | 1369 | return MakeCallback(env, recv, method_string, argc, argv); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1370 | } |
Trevor Norris | 86c0745 | 2013-02-07 01:26:18 | [diff] [blame] | 1371 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1372 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1373 | Local<Value> MakeCallback(Isolate* isolate, |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1374 | Local<Object> recv, |
| 1375 | const char* method, |
| 1376 | int argc, |
| 1377 | Local<Value> argv[]) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1378 | EscapableHandleScope handle_scope(isolate); |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1379 | Local<String> method_string = OneByteString(isolate, method); |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1380 | return handle_scope.Escape( |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1381 | MakeCallback(isolate, recv, method_string, argc, argv)); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1382 | } |
| 1383 | |
| 1384 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1385 | Local<Value> MakeCallback(Isolate* isolate, |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1386 | Local<Object> recv, |
| 1387 | Local<String> symbol, |
| 1388 | int argc, |
| 1389 | Local<Value> argv[]) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1390 | EscapableHandleScope handle_scope(isolate); |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1391 | 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 1396 | } |
| 1397 | |
| 1398 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1399 | Local<Value> MakeCallback(Isolate* isolate, |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1400 | 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 Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1411 | EscapableHandleScope handle_scope(isolate); |
Ben Noordhuis | 921d2b0 | 2016-10-21 09:57:20 | [diff] [blame] | 1412 | 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 Noordhuis | 1f2f3fa | 2014-01-27 02:58:16 | [diff] [blame] | 1416 | } |
| 1417 | |
| 1418 | |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1419 | enum 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 Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1431 | |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1432 | // 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 Norris | 54cc721 | 2016-06-02 16:55:36 | [diff] [blame] | 1439 | case 'l': |
| 1440 | // latin1 |
| 1441 | if (encoding[1] == 'a') { |
| 1442 | if (strncmp(encoding + 2, "tin1", 4) == 0) |
| 1443 | return LATIN1; |
| 1444 | } |
Ben Noordhuis | 6b48324 | 2016-06-10 09:36:42 | [diff] [blame] | 1445 | break; |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1446 | case 'b': |
| 1447 | // binary |
| 1448 | if (encoding[1] == 'i') { |
| 1449 | if (strncmp(encoding + 2, "nary", 4) == 0) |
Trevor Norris | 54cc721 | 2016-06-02 16:55:36 | [diff] [blame] | 1450 | return LATIN1; |
Ryan Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1451 | |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1452 | // 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 Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1463 | |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1464 | if (StringEqualNoCase(encoding, "utf8")) { |
Ryan Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1465 | return UTF8; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1466 | } else if (StringEqualNoCase(encoding, "utf-8")) { |
Ryan Dahl | 2b994d9 | 2009-10-06 08:45:18 | [diff] [blame] | 1467 | return UTF8; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1468 | } else if (StringEqualNoCase(encoding, "ascii")) { |
Ryan Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1469 | return ASCII; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1470 | } else if (StringEqualNoCase(encoding, "base64")) { |
Ben Noordhuis | 95638c9 | 2010-07-28 12:20:23 | [diff] [blame] | 1471 | return BASE64; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1472 | } else if (StringEqualNoCase(encoding, "ucs2")) { |
Konstantin Käfer | 9e101f2 | 2011-02-06 20:49:52 | [diff] [blame] | 1473 | return UCS2; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1474 | } else if (StringEqualNoCase(encoding, "ucs-2")) { |
Konstantin Käfer | 9e101f2 | 2011-02-06 20:49:52 | [diff] [blame] | 1475 | return UCS2; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1476 | } else if (StringEqualNoCase(encoding, "utf16le")) { |
koichik | fbb0ee6 | 2012-10-02 14:57:38 | [diff] [blame] | 1477 | return UCS2; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1478 | } else if (StringEqualNoCase(encoding, "utf-16le")) { |
koichik | fbb0ee6 | 2012-10-02 14:57:38 | [diff] [blame] | 1479 | return UCS2; |
Trevor Norris | 54cc721 | 2016-06-02 16:55:36 | [diff] [blame] | 1480 | } else if (StringEqualNoCase(encoding, "latin1")) { |
| 1481 | return LATIN1; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1482 | } else if (StringEqualNoCase(encoding, "binary")) { |
Ben Noordhuis | a92089b | 2016-06-13 09:37:39 | [diff] [blame] | 1483 | return LATIN1; // BINARY is a deprecated alias of LATIN1. |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1484 | } else if (StringEqualNoCase(encoding, "buffer")) { |
Fedor Indutny | 63ff449 | 2012-09-12 20:35:59 | [diff] [blame] | 1485 | return BUFFER; |
Ben Noordhuis | f6940df | 2016-05-04 18:56:04 | [diff] [blame] | 1486 | } else if (StringEqualNoCase(encoding, "hex")) { |
isaacs | 0aa1a8a | 2011-02-20 01:29:01 | [diff] [blame] | 1487 | return HEX; |
Ryan Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1488 | } else { |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1489 | return default_encoding; |
Ryan Dahl | 07792af | 2009-09-21 10:27:22 | [diff] [blame] | 1490 | } |
| 1491 | } |
| 1492 | |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1493 | |
| 1494 | enum encoding ParseEncoding(Isolate* isolate, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1495 | Local<Value> encoding_v, |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1496 | enum encoding default_encoding) { |
Tobias Nießen | 88351a2 | 2017-04-02 13:00:32 | [diff] [blame] | 1497 | CHECK(!encoding_v.IsEmpty()); |
| 1498 | |
Fedor Indutny | c6367e7 | 2015-01-30 12:05:28 | [diff] [blame] | 1499 | 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 Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1507 | Local<Value> Encode(Isolate* isolate, |
Ben Noordhuis | 56fde66 | 2014-12-10 16:33:56 | [diff] [blame] | 1508 | const char* buf, |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1509 | size_t len, |
| 1510 | enum encoding encoding) { |
Ben Noordhuis | 56fde66 | 2014-12-10 16:33:56 | [diff] [blame] | 1511 | CHECK_NE(encoding, UCS2); |
| 1512 | return StringBytes::Encode(isolate, buf, len, encoding); |
| 1513 | } |
| 1514 | |
| 1515 | Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) { |
| 1516 | return StringBytes::Encode(isolate, buf, len); |
Ryan | 21a1b04 | 2009-09-09 13:51:49 | [diff] [blame] | 1517 | } |
| 1518 | |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 1519 | // Returns -1 if the handle was not valid for decoding |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1520 | ssize_t DecodeBytes(Isolate* isolate, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1521 | Local<Value> val, |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1522 | enum encoding encoding) { |
| 1523 | HandleScope scope(isolate); |
Ryan | 21a1b04 | 2009-09-09 13:51:49 | [diff] [blame] | 1524 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1525 | return StringBytes::Size(isolate, val, encoding); |
Ryan | 21a1b04 | 2009-09-09 13:51:49 | [diff] [blame] | 1526 | } |
| 1527 | |
Ryan | 21a1b04 | 2009-09-09 13:51:49 | [diff] [blame] | 1528 | // Returns number of bytes written. |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1529 | ssize_t DecodeWrite(Isolate* isolate, |
| 1530 | char* buf, |
Ryan Dahl | 53530e9 | 2010-04-02 21:55:28 | [diff] [blame] | 1531 | size_t buflen, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1532 | Local<Value> val, |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 1533 | enum encoding encoding) { |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1534 | return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr); |
Ryan | 21a1b04 | 2009-09-09 13:51:49 | [diff] [blame] | 1535 | } |
| 1536 | |
Brian White | 18490d3 | 2015-12-15 08:55:35 | [diff] [blame] | 1537 | bool IsExceptionDecorated(Environment* env, Local<Value> er) { |
| 1538 | if (!er.IsEmpty() && er->IsObject()) { |
| 1539 | Local<Object> err_obj = er.As<Object>(); |
Ben Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1540 | 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 White | 18490d3 | 2015-12-15 08:55:35 | [diff] [blame] | 1544 | } |
| 1545 | return false; |
| 1546 | } |
| 1547 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1548 | void AppendExceptionLine(Environment* env, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1549 | Local<Value> er, |
Anna Henningsen | 3cac616 | 2016-06-24 03:50:00 | [diff] [blame] | 1550 | Local<Message> message, |
| 1551 | enum ErrorHandlingMode mode) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1552 | if (message.IsEmpty()) |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 1553 | return; |
isaacs | b3cf3f3 | 2012-07-28 21:00:27 | [diff] [blame] | 1554 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1555 | HandleScope scope(env->isolate()); |
| 1556 | Local<Object> err_obj; |
| 1557 | if (!er.IsEmpty() && er->IsObject()) { |
| 1558 | err_obj = er.As<Object>(); |
Ryan Dahl | cdf5d91 | 2011-10-11 20:41:33 | [diff] [blame] | 1559 | |
Ben Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1560 | auto context = env->context(); |
| 1561 | auto processed_private_symbol = env->processed_private_symbol(); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1562 | // Do it only once per message |
Ben Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1563 | if (err_obj->HasPrivate(context, processed_private_symbol).FromJust()) |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1564 | return; |
Ben Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1565 | err_obj->SetPrivate( |
| 1566 | context, |
| 1567 | processed_private_symbol, |
| 1568 | True(env->isolate())); |
Ryan Dahl | 8e6dd52 | 2010-01-15 18:45:04 | [diff] [blame] | 1569 | } |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1570 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1571 | // Print (filename):(line number): (message). |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1572 | node::Utf8Value filename(env->isolate(), message->GetScriptResourceName()); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1573 | const char* filename_string = *filename; |
| 1574 | int linenum = message->GetLineNumber(); |
| 1575 | // Print line of source code. |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1576 | node::Utf8Value sourceline(env->isolate(), message->GetSourceLine()); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1577 | 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 Henningsen | 4bd410b | 2016-05-20 20:55:37 | [diff] [blame] | 1600 | int start = message->GetStartColumn(env->context()).FromMaybe(0); |
| 1601 | int end = message->GetEndColumn(env->context()).FromMaybe(0); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1602 | |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1603 | char arrow[1024]; |
| 1604 | int max_off = sizeof(arrow) - 2; |
| 1605 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1606 | int off = snprintf(arrow, |
| 1607 | sizeof(arrow), |
| 1608 | "%s:%i\n%s\n", |
| 1609 | filename_string, |
| 1610 | linenum, |
| 1611 | sourceline_string); |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 1612 | CHECK_GE(off, 0); |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1613 | if (off > max_off) { |
| 1614 | off = max_off; |
| 1615 | } |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1616 | |
| 1617 | // Print wavy underline (GetUnderline is deprecated). |
| 1618 | for (int i = 0; i < start; i++) { |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1619 | if (sourceline_string[i] == '\0' || off >= max_off) { |
Yazhong Liu | 6b09f9c | 2014-06-25 13:18:50 | [diff] [blame] | 1620 | break; |
| 1621 | } |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1622 | CHECK_LT(off, max_off); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1623 | arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' '; |
| 1624 | } |
| 1625 | for (int i = start; i < end; i++) { |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1626 | if (sourceline_string[i] == '\0' || off >= max_off) { |
Yazhong Liu | 6b09f9c | 2014-06-25 13:18:50 | [diff] [blame] | 1627 | break; |
| 1628 | } |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1629 | CHECK_LT(off, max_off); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1630 | arrow[off++] = '^'; |
| 1631 | } |
Karl Skomski | 3bb9237 | 2015-09-03 08:10:29 | [diff] [blame] | 1632 | CHECK_LE(off, max_off); |
| 1633 | arrow[off] = '\n'; |
| 1634 | arrow[off + 1] = '\0'; |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1635 | |
| 1636 | Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1637 | |
Anna Henningsen | 3cac616 | 2016-06-24 03:50:00 | [diff] [blame] | 1638 | 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 Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1651 | return; |
| 1652 | } |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1653 | |
Anna Henningsen | 3cac616 | 2016-06-24 03:50:00 | [diff] [blame] | 1654 | CHECK(err_obj->SetPrivate( |
| 1655 | env->context(), |
| 1656 | env->arrow_message_private_symbol(), |
| 1657 | arrow_str).FromMaybe(false)); |
Ryan Dahl | b57c1f5 | 2010-11-24 02:46:13 | [diff] [blame] | 1658 | } |
| 1659 | |
| 1660 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1661 | static void ReportException(Environment* env, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1662 | Local<Value> er, |
| 1663 | Local<Message> message) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1664 | HandleScope scope(env->isolate()); |
Ryan Dahl | b57c1f5 | 2010-11-24 02:46:13 | [diff] [blame] | 1665 | |
Anna Henningsen | 3cac616 | 2016-06-24 03:50:00 | [diff] [blame] | 1666 | AppendExceptionLine(env, er, message, FATAL_ERROR); |
Ryan Dahl | 53a841d | 2009-12-29 19:20:51 | [diff] [blame] | 1667 | |
Vladimir Kurchatkin | 259d449 | 2013-12-06 11:56:37 | [diff] [blame] | 1668 | Local<Value> trace_value; |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1669 | Local<Value> arrow; |
Brian White | 18490d3 | 2015-12-15 08:55:35 | [diff] [blame] | 1670 | const bool decorated = IsExceptionDecorated(env, er); |
Vladimir Kurchatkin | 259d449 | 2013-12-06 11:56:37 | [diff] [blame] | 1671 | |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1672 | if (er->IsUndefined() || er->IsNull()) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1673 | trace_value = Undefined(env->isolate()); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1674 | } else { |
| 1675 | Local<Object> err_obj = er->ToObject(env->isolate()); |
| 1676 | |
| 1677 | trace_value = err_obj->Get(env->stack_string()); |
Ben Noordhuis | 924cc6c | 2016-02-02 22:50:07 | [diff] [blame] | 1678 | arrow = |
| 1679 | err_obj->GetPrivate( |
| 1680 | env->context(), |
| 1681 | env->arrow_message_private_symbol()).ToLocalChecked(); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1682 | } |
Vladimir Kurchatkin | 259d449 | 2013-12-06 11:56:37 | [diff] [blame] | 1683 | |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1684 | node::Utf8Value trace(env->isolate(), trace_value); |
Ryan Dahl | da93230 | 2010-05-14 18:48:14 | [diff] [blame] | 1685 | |
isaacs | 8df6f9e | 2011-04-25 19:22:18 | [diff] [blame] | 1686 | // range errors have a trace member set to undefined |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 1687 | if (trace.length() > 0 && !trace_value->IsUndefined()) { |
Brian White | 18490d3 | 2015-12-15 08:55:35 | [diff] [blame] | 1688 | if (arrow.IsEmpty() || !arrow->IsString() || decorated) { |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 1689 | PrintErrorString("%s\n", *trace); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1690 | } else { |
| 1691 | node::Utf8Value arrow_string(env->isolate(), arrow); |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 1692 | PrintErrorString("%s\n%s\n", *arrow_string, *trace); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1693 | } |
isaacs | e9b6b0b | 2010-10-02 06:22:34 | [diff] [blame] | 1694 | } else { |
| 1695 | // this really only happens for RangeErrors, since they're the only |
isaacs | 8df6f9e | 2011-04-25 19:22:18 | [diff] [blame] | 1696 | // kind that won't have all this info in the trace, or when non-Error |
| 1697 | // objects are thrown manually. |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1698 | Local<Value> message; |
| 1699 | Local<Value> name; |
isaacs | 8df6f9e | 2011-04-25 19:22:18 | [diff] [blame] | 1700 | |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1701 | if (er->IsObject()) { |
| 1702 | Local<Object> err_obj = er.As<Object>(); |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1703 | message = err_obj->Get(env->message_string()); |
| 1704 | name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name")); |
isaacs | 8df6f9e | 2011-04-25 19:22:18 | [diff] [blame] | 1705 | } |
| 1706 | |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1707 | if (message.IsEmpty() || |
| 1708 | message->IsUndefined() || |
| 1709 | name.IsEmpty() || |
| 1710 | name->IsUndefined()) { |
| 1711 | // Not an error object. Just print as-is. |
cjihrig | 1ec09b0 | 2015-12-02 01:34:45 | [diff] [blame] | 1712 | String::Utf8Value message(er); |
| 1713 | |
| 1714 | PrintErrorString("%s\n", *message ? *message : |
| 1715 | "<toString() threw exception>"); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1716 | } else { |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1717 | node::Utf8Value name_string(env->isolate(), name); |
| 1718 | node::Utf8Value message_string(env->isolate(), message); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1719 | |
Brian White | 18490d3 | 2015-12-15 08:55:35 | [diff] [blame] | 1720 | if (arrow.IsEmpty() || !arrow->IsString() || decorated) { |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 1721 | PrintErrorString("%s: %s\n", *name_string, *message_string); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1722 | } else { |
| 1723 | node::Utf8Value arrow_string(env->isolate(), arrow); |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 1724 | PrintErrorString("%s\n%s: %s\n", |
| 1725 | *arrow_string, |
| 1726 | *name_string, |
| 1727 | *message_string); |
Fedor Indutny | ef65321 | 2015-07-05 18:20:26 | [diff] [blame] | 1728 | } |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 1729 | } |
Ryan | 5131e0a | 2009-03-09 00:23:41 | [diff] [blame] | 1730 | } |
isaacs | e9b6b0b | 2010-10-02 06:22:34 | [diff] [blame] | 1731 | |
Ryan | d7e220c | 2009-09-09 20:35:40 | [diff] [blame] | 1732 | fflush(stderr); |
Ryan | 5131e0a | 2009-03-09 00:23:41 | [diff] [blame] | 1733 | } |
| 1734 | |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 1735 | |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1736 | static void ReportException(Environment* env, const TryCatch& try_catch) { |
| 1737 | ReportException(env, try_catch.Exception(), try_catch.Message()); |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 1738 | } |
| 1739 | |
| 1740 | |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 1741 | // Executes a str within the current v8 context. |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1742 | static Local<Value> ExecuteString(Environment* env, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 1743 | Local<String> source, |
| 1744 | Local<String> filename) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1745 | EscapableHandleScope scope(env->isolate()); |
Michaël Zasso | 79d7475 | 2016-01-26 08:06:43 | [diff] [blame] | 1746 | TryCatch try_catch(env->isolate()); |
Ryan | 408526a | 2009-04-21 11:52:21 | [diff] [blame] | 1747 | |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 1748 | // try_catch must be nonverbose to disable FatalException() handler, |
| 1749 | // we will handle exceptions ourself. |
| 1750 | try_catch.SetVerbose(false); |
| 1751 | |
Michaël Zasso | 023c317 | 2016-02-08 21:34:05 | [diff] [blame] | 1752 | ScriptOrigin origin(filename); |
| 1753 | MaybeLocal<v8::Script> script = |
| 1754 | v8::Script::Compile(env->context(), source, &origin); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 1755 | if (script.IsEmpty()) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1756 | ReportException(env, try_catch); |
isaacs | 95862b2 | 2013-02-27 19:23:20 | [diff] [blame] | 1757 | exit(3); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 1758 | } |
| 1759 | |
Michaël Zasso | 023c317 | 2016-02-08 21:34:05 | [diff] [blame] | 1760 | Local<Value> result = script.ToLocalChecked()->Run(); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 1761 | if (result.IsEmpty()) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 1762 | ReportException(env, try_catch); |
isaacs | 95862b2 | 2013-02-27 19:23:20 | [diff] [blame] | 1763 | exit(4); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 1764 | } |
| 1765 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1766 | return scope.Escape(result); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 1767 | } |
| 1768 | |
Felix Geisendörfer | 7371fcb | 2009-11-11 17:10:58 | [diff] [blame] | 1769 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1770 | static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1771 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1772 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1773 | Local<Array> ary = Array::New(args.GetIsolate()); |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1774 | Local<Context> ctx = env->context(); |
Trevor Norris | 83524b3 | 2015-11-10 09:58:51 | [diff] [blame] | 1775 | Local<Function> fn = env->push_values_to_array_function(); |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1776 | Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; |
| 1777 | size_t idx = 0; |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1778 | |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1779 | for (auto w : *env->req_wrap_queue()) { |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1780 | if (w->persistent().IsEmpty()) |
| 1781 | continue; |
| 1782 | argv[idx] = w->object(); |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 1783 | if (++idx >= arraysize(argv)) { |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1784 | fn->Call(ctx, ary, idx, argv).ToLocalChecked(); |
| 1785 | idx = 0; |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1786 | } |
| 1787 | } |
| 1788 | |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1789 | if (idx > 0) { |
| 1790 | fn->Call(ctx, ary, idx, argv).ToLocalChecked(); |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 1791 | } |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1792 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1793 | args.GetReturnValue().Set(ary); |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1794 | } |
| 1795 | |
| 1796 | |
| 1797 | // Non-static, friend of HandleWrap. Could have been a HandleWrap method but |
| 1798 | // implemented here for consistency with GetActiveRequests(). |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1799 | void GetActiveHandles(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1800 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1801 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 1802 | Local<Array> ary = Array::New(env->isolate()); |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1803 | 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 Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1807 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1808 | Local<String> owner_sym = env->owner_string(); |
Ben Noordhuis | e813e34 | 2012-05-15 15:24:06 | [diff] [blame] | 1809 | |
Ben Noordhuis | 38dc0cd | 2015-01-30 11:54:53 | [diff] [blame] | 1810 | for (auto w : *env->handle_wrap_queue()) { |
Ben Noordhuis | cad1a62 | 2016-04-26 10:01:46 | [diff] [blame] | 1811 | if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w)) |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 1812 | continue; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1813 | Local<Object> object = w->object(); |
| 1814 | Local<Value> owner = object->Get(owner_sym); |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 1815 | if (owner->IsUndefined()) |
| 1816 | owner = object; |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1817 | argv[idx] = owner; |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 1818 | if (++idx >= arraysize(argv)) { |
Trevor Norris | 946315f | 2015-11-11 00:04:56 | [diff] [blame] | 1819 | 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 Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1825 | } |
| 1826 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1827 | args.GetReturnValue().Set(ary); |
Ben Noordhuis | 5f04065 | 2012-04-28 16:45:10 | [diff] [blame] | 1828 | } |
| 1829 | |
| 1830 | |
Ben Noordhuis | be767cf | 2016-06-19 08:44:22 | [diff] [blame] | 1831 | NO_RETURN void Abort() { |
| 1832 | DumpBacktrace(stderr); |
| 1833 | fflush(stderr); |
| 1834 | ABORT_NO_BACKTRACE(); |
| 1835 | } |
| 1836 | |
| 1837 | |
Ben Noordhuis | 92dab4a | 2016-06-19 10:10:45 | [diff] [blame] | 1838 | NO_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 Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1863 | static void Abort(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | be767cf | 2016-06-19 08:44:22 | [diff] [blame] | 1864 | Abort(); |
Robert Mustacchi | 2240486 | 2011-12-15 01:02:15 | [diff] [blame] | 1865 | } |
| 1866 | |
| 1867 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1868 | static void Chdir(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1869 | Environment* env = Environment::GetCurrent(args); |
Ryan Dahl | b20c343 | 2010-02-12 05:55:08 | [diff] [blame] | 1870 | |
Brandon Beacher | 47fcf78 | 2009-11-03 18:13:38 | [diff] [blame] | 1871 | if (args.Length() != 1 || !args[0]->IsString()) { |
Caitlin Potter | be2404e | 2015-01-09 16:38:28 | [diff] [blame] | 1872 | return env->ThrowTypeError("Bad argument."); |
Brandon Beacher | 47fcf78 | 2009-11-03 18:13:38 | [diff] [blame] | 1873 | } |
Ryan Dahl | b20c343 | 2010-02-12 05:55:08 | [diff] [blame] | 1874 | |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1875 | node::Utf8Value path(args.GetIsolate(), args[0]); |
Ben Noordhuis | ca9eb71 | 2013-07-18 21:18:50 | [diff] [blame] | 1876 | int err = uv_chdir(*path); |
| 1877 | if (err) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1878 | return env->ThrowUVException(err, "uv_chdir"); |
Brandon Beacher | 47fcf78 | 2009-11-03 18:13:38 | [diff] [blame] | 1879 | } |
Brandon Beacher | 47fcf78 | 2009-11-03 18:13:38 | [diff] [blame] | 1880 | } |
| 1881 | |
Bert Belder | cbcf4fe | 2011-11-24 01:19:54 | [diff] [blame] | 1882 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1883 | static void Cwd(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1884 | Environment* env = Environment::GetCurrent(args); |
Bert Belder | e84edd2 | 2011-12-01 23:24:44 | [diff] [blame] | 1885 | #ifdef _WIN32 |
| 1886 | /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ |
Saúl Ibarra Corretgé | d2f2a32 | 2014-03-02 22:18:26 | [diff] [blame] | 1887 | char buf[MAX_PATH * 4]; |
Bert Belder | e84edd2 | 2011-12-01 23:24:44 | [diff] [blame] | 1888 | #else |
Saúl Ibarra Corretgé | d2f2a32 | 2014-03-02 22:18:26 | [diff] [blame] | 1889 | char buf[PATH_MAX]; |
Bert Belder | e84edd2 | 2011-12-01 23:24:44 | [diff] [blame] | 1890 | #endif |
Michael Carter | 8ea6adc | 2009-09-01 09:39:30 | [diff] [blame] | 1891 | |
Saúl Ibarra Corretgé | d2f2a32 | 2014-03-02 22:18:26 | [diff] [blame] | 1892 | size_t cwd_len = sizeof(buf); |
| 1893 | int err = uv_cwd(buf, &cwd_len); |
Ben Noordhuis | ca9eb71 | 2013-07-18 21:18:50 | [diff] [blame] | 1894 | if (err) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1895 | return env->ThrowUVException(err, "uv_cwd"); |
Michael Carter | 8ea6adc | 2009-09-01 09:39:30 | [diff] [blame] | 1896 | } |
Peter Griess | 4e3c5d8 | 2010-07-12 15:47:45 | [diff] [blame] | 1897 | |
Saúl Ibarra Corretgé | d2f2a32 | 2014-03-02 22:18:26 | [diff] [blame] | 1898 | Local<String> cwd = String::NewFromUtf8(env->isolate(), |
| 1899 | buf, |
| 1900 | String::kNormalString, |
Saúl Ibarra Corretgé | e46cbaa | 2014-10-17 07:31:59 | [diff] [blame] | 1901 | cwd_len); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1902 | args.GetReturnValue().Set(cwd); |
Michael Carter | 8ea6adc | 2009-09-01 09:39:30 | [diff] [blame] | 1903 | } |
| 1904 | |
Bert Belder | e84edd2 | 2011-12-01 23:24:44 | [diff] [blame] | 1905 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1906 | static void Umask(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 1907 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1908 | uint32_t old; |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1909 | |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 1910 | if (args.Length() < 1 || args[0]->IsUndefined()) { |
Rasmus Andersson | 374300c | 2010-02-27 17:18:41 | [diff] [blame] | 1911 | old = umask(0); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1912 | umask(static_cast<mode_t>(old)); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 1913 | } else if (!args[0]->IsInt32() && !args[0]->IsString()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1914 | return env->ThrowTypeError("argument must be an integer or octal string."); |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1915 | } else { |
| 1916 | int oct; |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 1917 | if (args[0]->IsInt32()) { |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1918 | oct = args[0]->Uint32Value(); |
| 1919 | } else { |
| 1920 | oct = 0; |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 1921 | node::Utf8Value str(env->isolate(), args[0]); |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1922 | |
| 1923 | // Parse the octal string. |
Timothy J Fontaine | 1a09da6 | 2014-06-10 23:36:04 | [diff] [blame] | 1924 | for (size_t i = 0; i < str.length(); i++) { |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1925 | char c = (*str)[i]; |
| 1926 | if (c > '7' || c < '0') { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 1927 | return env->ThrowTypeError("invalid octal string"); |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1928 | } |
| 1929 | oct *= 8; |
| 1930 | oct += c - '0'; |
| 1931 | } |
| 1932 | } |
| 1933 | old = umask(static_cast<mode_t>(oct)); |
Friedemann Altrock | 0433d82 | 2009-11-22 18:52:52 | [diff] [blame] | 1934 | } |
isaacs | 5f2e909 | 2011-01-25 18:40:12 | [diff] [blame] | 1935 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 1936 | args.GetReturnValue().Set(old); |
Friedemann Altrock | 0433d82 | 2009-11-22 18:52:52 | [diff] [blame] | 1937 | } |
| 1938 | |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 1939 | |
Linus MÃ¥rtensson | 5e4e8ec | 2013-05-08 12:10:07 | [diff] [blame] | 1940 | #if defined(__POSIX__) && !defined(__ANDROID__) |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 1941 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1942 | static const uid_t uid_not_found = static_cast<uid_t>(-1); |
| 1943 | static const gid_t gid_not_found = static_cast<gid_t>(-1); |
| 1944 | |
| 1945 | |
| 1946 | static uid_t uid_by_name(const char* name) { |
| 1947 | struct passwd pwd; |
| 1948 | struct passwd* pp; |
| 1949 | char buf[8192]; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1950 | |
| 1951 | errno = 0; |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1952 | pp = nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1953 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1954 | if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1955 | return pp->pw_uid; |
| 1956 | } |
| 1957 | |
| 1958 | return uid_not_found; |
| 1959 | } |
| 1960 | |
| 1961 | |
| 1962 | static 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 Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1969 | pp = nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1970 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1971 | if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 && |
| 1972 | pp != nullptr) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1973 | return strdup(pp->pw_name); |
| 1974 | } |
| 1975 | |
| 1976 | if (rc == 0) { |
| 1977 | errno = ENOENT; |
| 1978 | } |
| 1979 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1980 | return nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1981 | } |
| 1982 | |
| 1983 | |
| 1984 | static gid_t gid_by_name(const char* name) { |
| 1985 | struct group pwd; |
| 1986 | struct group* pp; |
| 1987 | char buf[8192]; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1988 | |
| 1989 | errno = 0; |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1990 | pp = nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1991 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 1992 | if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 1993 | return pp->gr_gid; |
| 1994 | } |
| 1995 | |
| 1996 | return gid_not_found; |
| 1997 | } |
| 1998 | |
| 1999 | |
| 2000 | #if 0 // For future use. |
| 2001 | static 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 Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2008 | pp = nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2009 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2010 | if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 && |
| 2011 | pp != nullptr) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2012 | return strdup(pp->gr_name); |
| 2013 | } |
| 2014 | |
| 2015 | if (rc == 0) { |
| 2016 | errno = ENOENT; |
| 2017 | } |
| 2018 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2019 | return nullptr; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2020 | } |
| 2021 | #endif |
| 2022 | |
| 2023 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 2024 | static uid_t uid_by_name(Isolate* isolate, Local<Value> value) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2025 | if (value->IsUint32()) { |
| 2026 | return static_cast<uid_t>(value->Uint32Value()); |
| 2027 | } else { |
Vladimir Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2028 | node::Utf8Value name(isolate, value); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2029 | return uid_by_name(*name); |
| 2030 | } |
| 2031 | } |
| 2032 | |
| 2033 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 2034 | static gid_t gid_by_name(Isolate* isolate, Local<Value> value) { |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2035 | if (value->IsUint32()) { |
| 2036 | return static_cast<gid_t>(value->Uint32Value()); |
| 2037 | } else { |
Vladimir Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2038 | node::Utf8Value name(isolate, value); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2039 | return gid_by_name(*name); |
| 2040 | } |
| 2041 | } |
| 2042 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2043 | static void GetUid(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | 6df4741 | 2013-09-05 19:47:08 | [diff] [blame] | 2044 | // uid_t is an uint32_t on all supported platforms. |
| 2045 | args.GetReturnValue().Set(static_cast<uint32_t>(getuid())); |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2046 | } |
| 2047 | |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 2048 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2049 | static void GetGid(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | 6df4741 | 2013-09-05 19:47:08 | [diff] [blame] | 2050 | // gid_t is an uint32_t on all supported platforms. |
| 2051 | args.GetReturnValue().Set(static_cast<uint32_t>(getgid())); |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 2052 | } |
| 2053 | |
| 2054 | |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 2055 | static 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 | |
| 2061 | static 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 Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2067 | static void SetGid(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2068 | Environment* env = Environment::GetCurrent(args); |
Ryan Dahl | 3994340 | 2010-03-15 19:49:40 | [diff] [blame] | 2069 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2070 | if (!args[0]->IsUint32() && !args[0]->IsString()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2071 | return env->ThrowTypeError("setgid argument must be a number or a string"); |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 2072 | } |
| 2073 | |
Vladimir Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2074 | gid_t gid = gid_by_name(env->isolate(), args[0]); |
Blake Mizerany | 8c85340 | 2010-06-30 06:12:46 | [diff] [blame] | 2075 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2076 | if (gid == gid_not_found) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2077 | return env->ThrowError("setgid group id does not exist"); |
Peter Griess | 2420f07 | 2010-05-19 00:40:44 | [diff] [blame] | 2078 | } |
| 2079 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2080 | if (setgid(gid)) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2081 | return env->ThrowErrnoException(errno, "setgid"); |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 2082 | } |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 2083 | } |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2084 | |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 2085 | |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 2086 | static 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 Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2105 | static void SetUid(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2106 | Environment* env = Environment::GetCurrent(args); |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2107 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2108 | if (!args[0]->IsUint32() && !args[0]->IsString()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2109 | return env->ThrowTypeError("setuid argument must be a number or a string"); |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2110 | } |
| 2111 | |
Vladimir Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2112 | uid_t uid = uid_by_name(env->isolate(), args[0]); |
Peter Griess | 2420f07 | 2010-05-19 00:40:44 | [diff] [blame] | 2113 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2114 | if (uid == uid_not_found) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2115 | return env->ThrowError("setuid user id does not exist"); |
Peter Griess | 2420f07 | 2010-05-19 00:40:44 | [diff] [blame] | 2116 | } |
| 2117 | |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2118 | if (setuid(uid)) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2119 | return env->ThrowErrnoException(errno, "setuid"); |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2120 | } |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2121 | } |
| 2122 | |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 2123 | |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 2124 | static 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 Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2143 | static void GetGroups(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2144 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2145 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2146 | int ngroups = getgroups(0, nullptr); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2147 | |
| 2148 | if (ngroups == -1) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2149 | return env->ThrowErrnoException(errno, "getgroups"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2150 | } |
| 2151 | |
| 2152 | gid_t* groups = new gid_t[ngroups]; |
| 2153 | |
| 2154 | ngroups = getgroups(ngroups, groups); |
| 2155 | |
| 2156 | if (ngroups == -1) { |
| 2157 | delete[] groups; |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2158 | return env->ThrowErrnoException(errno, "getgroups"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2159 | } |
| 2160 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2161 | Local<Array> groups_list = Array::New(env->isolate(), ngroups); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2162 | bool seen_egid = false; |
| 2163 | gid_t egid = getegid(); |
| 2164 | |
| 2165 | for (int i = 0; i < ngroups; i++) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2166 | groups_list->Set(i, Integer::New(env->isolate(), groups[i])); |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 2167 | if (groups[i] == egid) |
| 2168 | seen_egid = true; |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2169 | } |
| 2170 | |
| 2171 | delete[] groups; |
| 2172 | |
| 2173 | if (seen_egid == false) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2174 | groups_list->Set(ngroups, Integer::New(env->isolate(), egid)); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2175 | } |
| 2176 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2177 | args.GetReturnValue().Set(groups_list); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2178 | } |
| 2179 | |
| 2180 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2181 | static void SetGroups(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2182 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2183 | |
| 2184 | if (!args[0]->IsArray()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2185 | return env->ThrowTypeError("argument 1 must be an array"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2186 | } |
| 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 Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2193 | gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i)); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2194 | |
| 2195 | if (gid == gid_not_found) { |
| 2196 | delete[] groups; |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2197 | return env->ThrowError("group name not found"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2198 | } |
| 2199 | |
| 2200 | groups[i] = gid; |
| 2201 | } |
| 2202 | |
| 2203 | int rc = setgroups(size, groups); |
| 2204 | delete[] groups; |
| 2205 | |
| 2206 | if (rc == -1) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2207 | return env->ThrowErrnoException(errno, "setgroups"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2208 | } |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2209 | } |
| 2210 | |
| 2211 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2212 | static void InitGroups(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2213 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2214 | |
| 2215 | if (!args[0]->IsUint32() && !args[0]->IsString()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2216 | return env->ThrowTypeError("argument 1 must be a number or a string"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2217 | } |
| 2218 | |
| 2219 | if (!args[1]->IsUint32() && !args[1]->IsString()) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2220 | return env->ThrowTypeError("argument 2 must be a number or a string"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2221 | } |
| 2222 | |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 2223 | node::Utf8Value arg0(env->isolate(), args[0]); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2224 | 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 Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2236 | if (user == nullptr) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2237 | return env->ThrowError("initgroups user not found"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2238 | } |
| 2239 | |
Vladimir Kurchatkin | 8aed9d6 | 2015-02-06 17:48:14 | [diff] [blame] | 2240 | extra_group = gid_by_name(env->isolate(), args[1]); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2241 | |
| 2242 | if (extra_group == gid_not_found) { |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 2243 | if (must_free) |
| 2244 | free(user); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2245 | return env->ThrowError("initgroups extra group not found"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2246 | } |
| 2247 | |
| 2248 | int rc = initgroups(user, extra_group); |
| 2249 | |
| 2250 | if (must_free) { |
| 2251 | free(user); |
| 2252 | } |
| 2253 | |
| 2254 | if (rc) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2255 | return env->ThrowErrnoException(errno, "initgroups"); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2256 | } |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 2257 | } |
| 2258 | |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2259 | #endif // __POSIX__ && !defined(__ANDROID__) |
Bert Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 2260 | |
Michael Carter | a386076 | 2010-02-08 06:13:10 | [diff] [blame] | 2261 | |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 2262 | static 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 Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 2267 | #if defined(__POSIX__) && !defined(NODE_SHARED_MODE) |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 2268 | 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 Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2283 | static void Exit(const FunctionCallbackInfo<Value>& args) { |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 2284 | WaitForInspectorDisconnect(Environment::GetCurrent(args)); |
Rasmus Christian Pedersen | 734fb49 | 2014-09-18 12:10:53 | [diff] [blame] | 2285 | exit(args[0]->Int32Value()); |
Ryan | 0f51703 | 2009-04-29 09:09:32 | [diff] [blame] | 2286 | } |
| 2287 | |
Ryan Dahl | 3ac6dee | 2010-05-08 02:05:59 | [diff] [blame] | 2288 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2289 | static void Uptime(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2290 | Environment* env = Environment::GetCurrent(args); |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 2291 | double uptime; |
Tom Hughes | cf78ce5 | 2011-03-04 23:57:54 | [diff] [blame] | 2292 | |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 2293 | uv_update_time(env->event_loop()); |
| 2294 | uptime = uv_now(env->event_loop()) - prog_start_time; |
Tom Hughes | cf78ce5 | 2011-03-04 23:57:54 | [diff] [blame] | 2295 | |
Timothy J Fontaine | b19b60a | 2014-05-01 20:54:23 | [diff] [blame] | 2296 | args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000)); |
Tom Hughes | cf78ce5 | 2011-03-04 23:57:54 | [diff] [blame] | 2297 | } |
Ryan Dahl | 3ac6dee | 2010-05-08 02:05:59 | [diff] [blame] | 2298 | |
Ryan Dahl | c344fbc | 2011-10-06 21:59:38 | [diff] [blame] | 2299 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2300 | static void MemoryUsage(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2301 | Environment* env = Environment::GetCurrent(args); |
Ryan Dahl | b3b3cfe | 2009-11-03 12:00:42 | [diff] [blame] | 2302 | |
Ryan Dahl | 5783a52 | 2011-10-18 21:30:31 | [diff] [blame] | 2303 | size_t rss; |
Ben Noordhuis | ca9eb71 | 2013-07-18 21:18:50 | [diff] [blame] | 2304 | int err = uv_resident_set_memory(&rss); |
| 2305 | if (err) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2306 | return env->ThrowUVException(err, "uv_resident_set_memory"); |
Ryan Dahl | 3a70129 | 2009-11-03 00:30:01 | [diff] [blame] | 2307 | } |
| 2308 | |
Brian White | f385f77 | 2017-02-22 07:03:49 | [diff] [blame] | 2309 | Isolate* isolate = env->isolate(); |
Ryan Dahl | 38e425d | 2009-11-28 15:31:29 | [diff] [blame] | 2310 | // V8 memory usage |
| 2311 | HeapStatistics v8_heap_stats; |
Brian White | f385f77 | 2017-02-22 07:03:49 | [diff] [blame] | 2312 | isolate->GetHeapStatistics(&v8_heap_stats); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2313 | |
Brian White | f385f77 | 2017-02-22 07:03:49 | [diff] [blame] | 2314 | // 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2320 | |
Brian White | f385f77 | 2017-02-22 07:03:49 | [diff] [blame] | 2321 | 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 Dahl | 3a70129 | 2009-11-03 00:30:01 | [diff] [blame] | 2325 | } |
Ryan Dahl | b3b3cfe | 2009-11-03 12:00:42 | [diff] [blame] | 2326 | |
Bert Belder | 4a2cb07 | 2010-11-29 17:40:14 | [diff] [blame] | 2327 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2328 | static void Kill(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2329 | Environment* env = Environment::GetCurrent(args); |
Ryan Dahl | b20c343 | 2010-02-12 05:55:08 | [diff] [blame] | 2330 | |
Ryan Dahl | 4227e9d | 2010-12-21 23:40:10 | [diff] [blame] | 2331 | if (args.Length() != 2) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2332 | return env->ThrowError("Bad argument."); |
Brandon Beacher | 334d56d | 2009-10-14 21:56:12 | [diff] [blame] | 2333 | } |
Ryan Dahl | b20c343 | 2010-02-12 05:55:08 | [diff] [blame] | 2334 | |
Rasmus Christian Pedersen | 734fb49 | 2014-09-18 12:10:53 | [diff] [blame] | 2335 | int pid = args[0]->Int32Value(); |
Ryan Dahl | 6eca948 | 2010-09-17 06:13:03 | [diff] [blame] | 2336 | int sig = args[1]->Int32Value(); |
Ben Noordhuis | ca9eb71 | 2013-07-18 21:18:50 | [diff] [blame] | 2337 | int err = uv_kill(pid, sig); |
| 2338 | args.GetReturnValue().Set(err); |
Brandon Beacher | 334d56d | 2009-10-14 21:56:12 | [diff] [blame] | 2339 | } |
| 2340 | |
Nathan Rajlich | 07c886f | 2012-03-05 16:51:58 | [diff] [blame] | 2341 | // 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 Cheung | a647d82 | 2017-01-12 12:03:29 | [diff] [blame] | 2346 | // 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 Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2352 | static void Hrtime(const FunctionCallbackInfo<Value>& args) { |
Nathan Rajlich | 07c886f | 2012-03-05 16:51:58 | [diff] [blame] | 2353 | uint64_t t = uv_hrtime(); |
| 2354 | |
Trevor Norris | 36e8a2c | 2015-11-11 07:15:15 | [diff] [blame] | 2355 | Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer(); |
| 2356 | uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data()); |
| 2357 | |
Trevor Norris | 36e8a2c | 2015-11-11 07:15:15 | [diff] [blame] | 2358 | fields[0] = (t / NANOS_PER_SEC) >> 32; |
| 2359 | fields[1] = (t / NANOS_PER_SEC) & 0xffffffff; |
| 2360 | fields[2] = t % NANOS_PER_SEC; |
Nathan Rajlich | 07c886f | 2012-03-05 16:51:58 | [diff] [blame] | 2361 | } |
| 2362 | |
Patrick Mueller | 52cb410 | 2016-04-05 13:17:48 | [diff] [blame] | 2363 | // 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 Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2371 | static void CPUUsage(const FunctionCallbackInfo<Value>& args) { |
Patrick Mueller | 52cb410 | 2016-04-05 13:17:48 | [diff] [blame] | 2372 | 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 Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2395 | extern "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 Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2401 | } 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 Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2407 | } else { |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2408 | modpending = mp; |
| 2409 | } |
| 2410 | } |
| 2411 | |
| 2412 | struct node_module* get_builtin_module(const char* name) { |
| 2413 | struct node_module* mp; |
| 2414 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2415 | for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) { |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2416 | if (strcmp(mp->nm_modname, name) == 0) |
| 2417 | break; |
| 2418 | } |
| 2419 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2420 | CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2421 | return (mp); |
| 2422 | } |
Bert Belder | dd93c53 | 2011-10-28 10:05:09 | [diff] [blame] | 2423 | |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2424 | struct node_module* get_linked_module(const char* name) { |
| 2425 | struct node_module* mp; |
| 2426 | |
Bert Belder | 9483bfe | 2014-12-09 04:57:17 | [diff] [blame] | 2427 | for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) { |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2428 | if (strcmp(mp->nm_modname, name) == 0) |
| 2429 | break; |
| 2430 | } |
| 2431 | |
Bert Belder | 9483bfe | 2014-12-09 04:57:17 | [diff] [blame] | 2432 | CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2433 | return mp; |
| 2434 | } |
| 2435 | |
isaacs | 1550858 | 2013-01-24 23:40:58 | [diff] [blame] | 2436 | // DLOpen is process.dlopen(module, filename). |
| 2437 | // Used to load 'module.node' dynamically shared objects. |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2438 | // |
| 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 Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2442 | static void DLOpen(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2443 | Environment* env = Environment::GetCurrent(args); |
Bert Belder | dd93c53 | 2011-10-28 10:05:09 | [diff] [blame] | 2444 | uv_lib_t lib; |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2445 | |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2446 | CHECK_EQ(modpending, nullptr); |
| 2447 | |
toastynerd | 9419e1f | 2015-01-19 18:17:45 | [diff] [blame] | 2448 | if (args.Length() != 2) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2449 | env->ThrowError("process.dlopen takes exactly 2 arguments."); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2450 | return; |
Bert Belder | dd93c53 | 2011-10-28 10:05:09 | [diff] [blame] | 2451 | } |
Ryan | a97dce7 | 2009-08-31 09:14:34 | [diff] [blame] | 2452 | |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 2453 | Local<Object> module = args[0]->ToObject(env->isolate()); // Cast |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 2454 | node::Utf8Value filename(env->isolate(), args[1]); // Cast |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2455 | const bool is_dlopen_error = uv_dlopen(*filename, &lib); |
isaacs | 1550858 | 2013-01-24 23:40:58 | [diff] [blame] | 2456 | |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2457 | // 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; |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2462 | |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2463 | if (is_dlopen_error) { |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2464 | Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib)); |
Karl Skomski | b48385a | 2015-08-14 08:12:16 | [diff] [blame] | 2465 | uv_dlclose(&lib); |
Ben Noordhuis | 039fac6 | 2012-05-17 05:13:29 | [diff] [blame] | 2466 | #ifdef _WIN32 |
| 2467 | // Windows needs to add the filename into the error message |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 2468 | errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate())); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2469 | #endif // _WIN32 |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2470 | env->isolate()->ThrowException(Exception::Error(errmsg)); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2471 | return; |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2472 | } |
| 2473 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2474 | if (mp == nullptr) { |
Karl Skomski | b48385a | 2015-08-14 08:12:16 | [diff] [blame] | 2475 | uv_dlclose(&lib); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2476 | env->ThrowError("Module did not self-register."); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2477 | return; |
Paul Querna | 367b87d | 2010-07-13 08:33:51 | [diff] [blame] | 2478 | } |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2479 | if (mp->nm_version != NODE_MODULE_VERSION) { |
Ben Noordhuis | f692347 | 2012-07-26 23:06:12 | [diff] [blame] | 2480 | char errmsg[1024]; |
Jason Ginchereau | 56e881d | 2017-03-20 21:55:26 | [diff] [blame] | 2481 | 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 Indutny | a6d674d | 2015-09-10 11:01:20 | [diff] [blame] | 2500 | |
| 2501 | // NOTE: `mp` is allocated inside of the shared library's memory, calling |
| 2502 | // `uv_dlclose` will deallocate it |
| 2503 | uv_dlclose(&lib); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2504 | env->ThrowError(errmsg); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2505 | return; |
| 2506 | } |
| 2507 | if (mp->nm_flags & NM_F_BUILTIN) { |
Karl Skomski | b48385a | 2015-08-14 08:12:16 | [diff] [blame] | 2508 | uv_dlclose(&lib); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2509 | env->ThrowError("Built-in module self-registered."); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2510 | return; |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2511 | } |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2512 | |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2513 | mp->nm_dso_handle = lib.handle; |
| 2514 | mp->nm_link = modlist_addon; |
| 2515 | modlist_addon = mp; |
| 2516 | |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2517 | Local<String> exports_string = env->exports_string(); |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 2518 | Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate()); |
Ben Noordhuis | a60056d | 2014-12-11 14:29:52 | [diff] [blame] | 2519 | |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2520 | if (mp->nm_context_register_func != nullptr) { |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2521 | mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2522 | } else if (mp->nm_register_func != nullptr) { |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2523 | mp->nm_register_func(exports, module, mp->nm_priv); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2524 | } else { |
Karl Skomski | b48385a | 2015-08-14 08:12:16 | [diff] [blame] | 2525 | uv_dlclose(&lib); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2526 | env->ThrowError("Module has no declared entry point."); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2527 | return; |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2528 | } |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2529 | |
Peter Griess | 4e3c5d8 | 2010-07-12 15:47:45 | [diff] [blame] | 2530 | // Tell coverity that 'handle' should not be freed when we return. |
| 2531 | // coverity[leaked_storage] |
Ryan | 2b6d724 | 2009-06-20 13:07:10 | [diff] [blame] | 2532 | } |
| 2533 | |
Tim-Smart | ae10a48 | 2010-03-12 08:36:00 | [diff] [blame] | 2534 | |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 2535 | static void OnFatalError(const char* location, const char* message) { |
Ryan Dahl | 53a841d | 2009-12-29 19:20:51 | [diff] [blame] | 2536 | if (location) { |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 2537 | PrintErrorString("FATAL ERROR: %s %s\n", location, message); |
Ryan Dahl | 53a841d | 2009-12-29 19:20:51 | [diff] [blame] | 2538 | } else { |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 2539 | PrintErrorString("FATAL ERROR: %s\n", message); |
Ryan Dahl | 53a841d | 2009-12-29 19:20:51 | [diff] [blame] | 2540 | } |
Ben Noordhuis | c56a96c | 2013-06-29 05:30:11 | [diff] [blame] | 2541 | fflush(stderr); |
Evan Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 2542 | ABORT(); |
Ryan | 63a9cd3 | 2009-04-15 08:08:28 | [diff] [blame] | 2543 | } |
| 2544 | |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2545 | |
Trevor Norris | fa10b75 | 2013-06-20 23:44:02 | [diff] [blame] | 2546 | NO_RETURN void FatalError(const char* location, const char* message) { |
| 2547 | OnFatalError(location, message); |
James M Snell | 936c9ff | 2015-06-24 03:42:49 | [diff] [blame] | 2548 | // to suppress compiler warning |
Evan Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 2549 | ABORT(); |
Trevor Norris | fa10b75 | 2013-06-20 23:44:02 | [diff] [blame] | 2550 | } |
| 2551 | |
| 2552 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2553 | void FatalException(Isolate* isolate, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 2554 | Local<Value> error, |
| 2555 | Local<Message> message) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2556 | HandleScope scope(isolate); |
Felix Geisendörfer | 2b252ac | 2009-11-14 22:07:54 | [diff] [blame] | 2557 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2558 | Environment* env = Environment::GetCurrent(isolate); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2559 | 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 Dahl | 45a806a | 2009-12-09 08:02:21 | [diff] [blame] | 2563 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2564 | int exit_code = 0; |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2565 | if (!fatal_exception_function->IsFunction()) { |
isaacs | 4401bb4 | 2012-12-26 20:28:33 | [diff] [blame] | 2566 | // failed before the process._fatalException function was added! |
| 2567 | // this is probably pretty bad. Nothing to do but report and exit. |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 2568 | ReportException(env, error, message); |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2569 | exit_code = 6; |
Felix Geisendörfer | 2b252ac | 2009-11-14 22:07:54 | [diff] [blame] | 2570 | } |
| 2571 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2572 | if (exit_code == 0) { |
| 2573 | TryCatch fatal_try_catch(isolate); |
isaacs | 07be9fc | 2012-05-09 22:12:13 | [diff] [blame] | 2574 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2575 | // Do not call FatalException when _fatalException handler throws |
| 2576 | fatal_try_catch.SetVerbose(false); |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2577 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2578 | // 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); |
isaacs | 4401bb4 | 2012-12-26 20:28:33 | [diff] [blame] | 2581 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2582 | 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 | } |
isaacs | 4401bb4 | 2012-12-26 20:28:33 | [diff] [blame] | 2592 | } |
| 2593 | |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2594 | if (exit_code) { |
| 2595 | #if HAVE_INSPECTOR |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 2596 | env->inspector_agent()->FatalException(error, message); |
Aleksei Koziatinskii | 26cd48f | 2016-08-10 02:03:47 | [diff] [blame] | 2597 | #endif |
| 2598 | exit(exit_code); |
isaacs | 80a55e9 | 2012-04-07 02:23:16 | [diff] [blame] | 2599 | } |
Ryan | e78917b | 2009-03-09 13:08:31 | [diff] [blame] | 2600 | } |
| 2601 | |
Ryan | 0e9e927 | 2009-04-04 14:53:43 | [diff] [blame] | 2602 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2603 | void FatalException(Isolate* isolate, const TryCatch& try_catch) { |
| 2604 | HandleScope scope(isolate); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2605 | // TODO(bajtos) do not call FatalException if try_catch is verbose |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2606 | // (requires V8 API to expose getter for try_catch.is_verbose_) |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2607 | FatalException(isolate, try_catch.Exception(), try_catch.Message()); |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2608 | } |
| 2609 | |
| 2610 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 2611 | static void OnMessage(Local<Message> message, Local<Value> error) { |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2612 | // The current version of V8 sends messages for errors only |
| 2613 | // (thus `error` is always set). |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2614 | FatalException(Isolate::GetCurrent(), error, message); |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 2615 | } |
| 2616 | |
| 2617 | |
Trevor Norris | a17200b | 2016-03-14 18:35:22 | [diff] [blame] | 2618 | void 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 Roberts | 213134f | 2016-11-07 21:18:23 | [diff] [blame] | 2636 | // Call process.emitWarning(str), fmt is a snprintf() format string |
| 2637 | void 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 Norris | a17200b | 2016-03-14 18:35:22 | [diff] [blame] | 2663 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2664 | static void Binding(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 2665 | Environment* env = Environment::GetCurrent(args); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2666 | |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 2667 | Local<String> module = args[0]->ToString(env->isolate()); |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 2668 | node::Utf8Value module_v(env->isolate(), module); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2669 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2670 | Local<Object> cache = env->binding_cache_object(); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2671 | Local<Object> exports; |
| 2672 | |
Michaël Zasso | a729208 | 2016-02-08 21:54:00 | [diff] [blame] | 2673 | if (cache->Has(env->context(), module).FromJust()) { |
Trevor Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 2674 | exports = cache->Get(module)->ToObject(env->isolate()); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2675 | args.GetReturnValue().Set(exports); |
| 2676 | return; |
Ryan Dahl | ea9ee1f | 2011-07-28 02:30:32 | [diff] [blame] | 2677 | } |
Ryan Dahl | 6eca948 | 2010-09-17 06:13:03 | [diff] [blame] | 2678 | |
Ryan Dahl | ea9ee1f | 2011-07-28 02:30:32 | [diff] [blame] | 2679 | // Append a string to process.moduleLoadList |
| 2680 | char buf[1024]; |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2681 | snprintf(buf, sizeof(buf), "Binding %s", *module_v); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2682 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2683 | Local<Array> modules = env->module_load_list_array(); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2684 | uint32_t l = modules->Length(); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2685 | modules->Set(l, OneByteString(env->isolate(), buf)); |
Ryan Dahl | ea9ee1f | 2011-07-28 02:30:32 | [diff] [blame] | 2686 | |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2687 | node_module* mod = get_builtin_module(*module_v); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2688 | if (mod != nullptr) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2689 | exports = Object::New(env->isolate()); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2690 | // Internal bindings don't have a "module" object, only exports. |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2691 | CHECK_EQ(mod->nm_register_func, nullptr); |
| 2692 | CHECK_NE(mod->nm_context_register_func, nullptr); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 2693 | Local<Value> unused = Undefined(env->isolate()); |
Keith M Wesolowski | 76b9846 | 2013-12-17 00:00:44 | [diff] [blame] | 2694 | mod->nm_context_register_func(exports, unused, |
| 2695 | env->context(), mod->nm_priv); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2696 | cache->Set(module, exports); |
Ryan Dahl | 6eca948 | 2010-09-17 06:13:03 | [diff] [blame] | 2697 | } else if (!strcmp(*module_v, "constants")) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2698 | exports = Object::New(env->isolate()); |
Sakthipriyan Vairamani (thefourtheye) | caf9ae7 | 2016-12-26 11:12:09 | [diff] [blame] | 2699 | CHECK(exports->SetPrototype(env->context(), |
| 2700 | Null(env->isolate())).FromJust()); |
James M Snell | dcccbfd | 2016-05-02 17:27:12 | [diff] [blame] | 2701 | DefineConstants(env->isolate(), exports); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2702 | cache->Set(module, exports); |
Ryan Dahl | c90546f | 2010-03-15 21:22:50 | [diff] [blame] | 2703 | } else if (!strcmp(*module_v, "natives")) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2704 | exports = Object::New(env->isolate()); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2705 | DefineJavaScript(env, exports); |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2706 | cache->Set(module, exports); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2707 | } else { |
Jackson Tian | 962e651 | 2014-08-01 11:26:09 | [diff] [blame] | 2708 | char errmsg[1024]; |
| 2709 | snprintf(errmsg, |
| 2710 | sizeof(errmsg), |
| 2711 | "No such module: %s", |
| 2712 | *module_v); |
| 2713 | return env->ThrowError(errmsg); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2714 | } |
| 2715 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2716 | args.GetReturnValue().Set(exports); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 2717 | } |
| 2718 | |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2719 | static void LinkedBinding(const FunctionCallbackInfo<Value>& args) { |
| 2720 | Environment* env = Environment::GetCurrent(args.GetIsolate()); |
| 2721 | |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2722 | Local<String> module_name = args[0]->ToString(env->isolate()); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2723 | |
| 2724 | Local<Object> cache = env->binding_cache_object(); |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2725 | Local<Value> exports_v = cache->Get(module_name); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2726 | |
| 2727 | if (exports_v->IsObject()) |
| 2728 | return args.GetReturnValue().Set(exports_v.As<Object>()); |
| 2729 | |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2730 | node::Utf8Value module_name_v(env->isolate(), module_name); |
| 2731 | node_module* mod = get_linked_module(*module_name_v); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2732 | |
Bert Belder | 9483bfe | 2014-12-09 04:57:17 | [diff] [blame] | 2733 | if (mod == nullptr) { |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2734 | char errmsg[1024]; |
| 2735 | snprintf(errmsg, |
| 2736 | sizeof(errmsg), |
| 2737 | "No such module was linked: %s", |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2738 | *module_name_v); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2739 | return env->ThrowError(errmsg); |
| 2740 | } |
| 2741 | |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2742 | Local<Object> module = Object::New(env->isolate()); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2743 | Local<Object> exports = Object::New(env->isolate()); |
Phillip Kovalev | 71470a8 | 2016-01-19 21:52:16 | [diff] [blame] | 2744 | Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports"); |
| 2745 | module->Set(exports_prop, exports); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2746 | |
Bert Belder | 9483bfe | 2014-12-09 04:57:17 | [diff] [blame] | 2747 | if (mod->nm_context_register_func != nullptr) { |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2748 | mod->nm_context_register_func(exports, |
| 2749 | module, |
| 2750 | env->context(), |
| 2751 | mod->nm_priv); |
Bert Belder | 9483bfe | 2014-12-09 04:57:17 | [diff] [blame] | 2752 | } else if (mod->nm_register_func != nullptr) { |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2753 | 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 Kovalev | 5c14efb | 2016-02-20 08:30:43 | [diff] [blame] | 2758 | auto effective_exports = module->Get(exports_prop); |
| 2759 | cache->Set(module_name, effective_exports); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2760 | |
Phillip Kovalev | 5c14efb | 2016-02-20 08:30:43 | [diff] [blame] | 2761 | args.GetReturnValue().Set(effective_exports); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 2762 | } |
Ryan Dahl | e742d07 | 2009-10-09 11:25:04 | [diff] [blame] | 2763 | |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 2764 | static void ProcessTitleGetter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2765 | const PropertyCallbackInfo<Value>& info) { |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 2766 | char buffer[512]; |
| 2767 | uv_get_process_title(buffer, sizeof(buffer)); |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2768 | info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer)); |
Ryan Dahl | 5185c15 | 2010-06-18 07:26:49 | [diff] [blame] | 2769 | } |
| 2770 | |
| 2771 | |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 2772 | static void ProcessTitleSetter(Local<Name> property, |
Ryan Dahl | 5185c15 | 2010-06-18 07:26:49 | [diff] [blame] | 2773 | Local<Value> value, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2774 | const PropertyCallbackInfo<void>& info) { |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2775 | node::Utf8Value title(info.GetIsolate(), value); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2776 | // TODO(piscisaureus): protect with a lock |
Igor Zinkovsky | 500c8f4 | 2011-12-15 20:36:05 | [diff] [blame] | 2777 | uv_set_process_title(*title); |
Ryan Dahl | 5185c15 | 2010-06-18 07:26:49 | [diff] [blame] | 2778 | } |
| 2779 | |
| 2780 | |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 2781 | static void EnvGetter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2782 | const PropertyCallbackInfo<Value>& info) { |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2783 | Isolate* isolate = info.GetIsolate(); |
Anna Henningsen | 3295a7f | 2016-11-16 01:27:14 | [diff] [blame] | 2784 | if (property->IsSymbol()) { |
| 2785 | return info.GetReturnValue().SetUndefined(); |
| 2786 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2787 | #ifdef __POSIX__ |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2788 | node::Utf8Value key(isolate, property); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2789 | const char* val = getenv(*key); |
| 2790 | if (val) { |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2791 | return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val)); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2792 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2793 | #else // _WIN32 |
cjihrig | 1aa595e | 2016-11-03 16:16:54 | [diff] [blame] | 2794 | node::TwoByteValue key(isolate, property); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2795 | WCHAR buffer[32767]; // The maximum size allowed for environment variables. |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2796 | DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key), |
| 2797 | buffer, |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 2798 | arraysize(buffer)); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2799 | // 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 Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 2803 | result < arraysize(buffer)) { |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 2804 | const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer); |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2805 | Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 2806 | return info.GetReturnValue().Set(rc); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2807 | } |
| 2808 | #endif |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2809 | } |
| 2810 | |
| 2811 | |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 2812 | static void EnvSetter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2813 | Local<Value> value, |
| 2814 | const PropertyCallbackInfo<Value>& info) { |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2815 | #ifdef __POSIX__ |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2816 | node::Utf8Value key(info.GetIsolate(), property); |
| 2817 | node::Utf8Value val(info.GetIsolate(), value); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2818 | setenv(*key, *val, 1); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2819 | #else // _WIN32 |
cjihrig | 1aa595e | 2016-11-03 16:16:54 | [diff] [blame] | 2820 | node::TwoByteValue key(info.GetIsolate(), property); |
| 2821 | node::TwoByteValue val(info.GetIsolate(), value); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2822 | 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 Dahl | e6b06bc | 2011-08-11 00:14:23 | [diff] [blame] | 2826 | } |
Bert Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 2827 | #endif |
Miguel Angel Asencio Hurtado | 88323e8 | 2016-10-11 08:19:16 | [diff] [blame] | 2828 | // Whether it worked or not, always return value. |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2829 | info.GetReturnValue().Set(value); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2830 | } |
| 2831 | |
| 2832 | |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 2833 | static void EnvQuery(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2834 | const PropertyCallbackInfo<Integer>& info) { |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2835 | int32_t rc = -1; // Not found unless proven otherwise. |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2836 | if (property->IsString()) { |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2837 | #ifdef __POSIX__ |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2838 | node::Utf8Value key(info.GetIsolate(), property); |
| 2839 | if (getenv(*key)) |
| 2840 | rc = 0; |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2841 | #else // _WIN32 |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2842 | 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 Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2853 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2854 | #endif |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2855 | } |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 2856 | if (rc != -1) |
| 2857 | info.GetReturnValue().Set(rc); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2858 | } |
| 2859 | |
| 2860 | |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 2861 | static void EnvDeleter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2862 | const PropertyCallbackInfo<Boolean>& info) { |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2863 | if (property->IsString()) { |
Bert Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 2864 | #ifdef __POSIX__ |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2865 | node::Utf8Value key(info.GetIsolate(), property); |
| 2866 | unsetenv(*key); |
Bert Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 2867 | #else |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2868 | node::TwoByteValue key(info.GetIsolate(), property); |
| 2869 | WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); |
| 2870 | SetEnvironmentVariableW(key_ptr, nullptr); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2871 | #endif |
Timothy Gu | e2f151f | 2017-03-06 06:45:19 | [diff] [blame] | 2872 | } |
Franziska Hinkelmann | ff7a841 | 2016-08-04 07:36:50 | [diff] [blame] | 2873 | |
| 2874 | // process.env never has non-configurable properties, so always |
| 2875 | // return true like the tc39 delete operator. |
| 2876 | info.GetReturnValue().Set(true); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2877 | } |
| 2878 | |
| 2879 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2880 | static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) { |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2881 | 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 Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2888 | #ifdef __POSIX__ |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2889 | int size = 0; |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 2890 | while (environ[size]) |
| 2891 | size++; |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2892 | |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2893 | Local<Array> envarr = Array::New(isolate); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2894 | |
| 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 Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2899 | argv[idx] = String::NewFromUtf8(isolate, |
| 2900 | var, |
| 2901 | String::kNormalString, |
| 2902 | length); |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 2903 | if (++idx >= arraysize(argv)) { |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2904 | 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 Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2910 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2911 | #else // _WIN32 |
| 2912 | WCHAR* environment = GetEnvironmentStringsW(); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2913 | if (environment == nullptr) |
Fedor Indutny | 2bc30f2 | 2013-10-16 16:57:26 | [diff] [blame] | 2914 | return; // This should not happen. |
Ben Noordhuis | 2e5b87a | 2015-03-22 23:38:42 | [diff] [blame] | 2915 | Local<Array> envarr = Array::New(isolate); |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2916 | WCHAR* p = environment; |
Nikolai Vavilov | b105f6f | 2014-10-24 22:36:59 | [diff] [blame] | 2917 | while (*p) { |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2918 | 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 Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 2929 | const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p); |
Ben Noordhuis | 78f709d | 2013-08-09 15:43:10 | [diff] [blame] | 2930 | const size_t two_byte_buffer_len = s - p; |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2931 | argv[idx] = String::NewFromTwoByte(isolate, |
| 2932 | two_byte_buffer, |
| 2933 | String::kNormalString, |
| 2934 | two_byte_buffer_len); |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 2935 | if (++idx >= arraysize(argv)) { |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2936 | fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); |
| 2937 | idx = 0; |
| 2938 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2939 | p = s + wcslen(s) + 1; |
| 2940 | } |
Trevor Norris | 56985ca | 2015-11-11 19:28:41 | [diff] [blame] | 2941 | if (idx > 0) { |
| 2942 | fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); |
| 2943 | } |
Bert Belder | 077f9d7 | 2012-02-15 22:34:18 | [diff] [blame] | 2944 | FreeEnvironmentStringsW(environment); |
| 2945 | #endif |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 2946 | |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2947 | info.GetReturnValue().Set(envarr); |
Ben Noordhuis | b4def48 | 2010-10-15 13:48:34 | [diff] [blame] | 2948 | } |
| 2949 | |
| 2950 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 2951 | static Local<Object> GetFeatures(Environment* env) { |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2952 | EscapableHandleScope scope(env->isolate()); |
Ben Noordhuis | aa0308d | 2011-07-23 21:16:48 | [diff] [blame] | 2953 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2954 | Local<Object> obj = Object::New(env->isolate()); |
Ryan Dahl | 52a40e0 | 2011-08-24 21:16:35 | [diff] [blame] | 2955 | #if defined(DEBUG) && DEBUG |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2956 | Local<Value> debug = True(env->isolate()); |
Ryan Dahl | 52a40e0 | 2011-08-24 21:16:35 | [diff] [blame] | 2957 | #else |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2958 | Local<Value> debug = False(env->isolate()); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2959 | #endif // defined(DEBUG) && DEBUG |
| 2960 | |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2961 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug); |
| 2962 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate())); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 2963 | // TODO(bnoordhuis) ping libuv |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2964 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate())); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 2965 | |
Shigeki Ohtsu | 02c98f4 | 2017-03-02 14:13:19 | [diff] [blame] | 2966 | #ifndef OPENSSL_NO_NEXTPROTONEG |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2967 | Local<Boolean> tls_npn = True(env->isolate()); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2968 | #else |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2969 | Local<Boolean> tls_npn = False(env->isolate()); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2970 | #endif |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2971 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2972 | |
Shigeki Ohtsu | 802a2e7 | 2015-04-23 06:25:15 | [diff] [blame] | 2973 | #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 Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2978 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn); |
Shigeki Ohtsu | 802a2e7 | 2015-04-23 06:25:15 | [diff] [blame] | 2979 | |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2980 | #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2981 | Local<Boolean> tls_sni = True(env->isolate()); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2982 | #else |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 2983 | Local<Boolean> tls_sni = False(env->isolate()); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2984 | #endif |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2985 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni); |
Ben Noordhuis | 8d567f4 | 2013-08-27 14:14:45 | [diff] [blame] | 2986 | |
Fedor Indutny | b3ef289 | 2014-04-14 17:15:57 | [diff] [blame] | 2987 | #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 Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2992 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp); |
Fedor Indutny | b3ef289 | 2014-04-14 17:15:57 | [diff] [blame] | 2993 | |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 2994 | obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"), |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 2995 | Boolean::New(env->isolate(), |
| 2996 | get_builtin_module("crypto") != nullptr)); |
Ben Noordhuis | aa0308d | 2011-07-23 21:16:48 | [diff] [blame] | 2997 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 2998 | return scope.Escape(obj); |
Ben Noordhuis | aa0308d | 2011-07-23 21:16:48 | [diff] [blame] | 2999 | } |
| 3000 | |
| 3001 | |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 3002 | static void DebugPortGetter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3003 | const PropertyCallbackInfo<Value>& info) { |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3004 | info.GetReturnValue().Set(debug_options.port()); |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 3005 | } |
| 3006 | |
| 3007 | |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 3008 | static void DebugPortSetter(Local<Name> property, |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 3009 | Local<Value> value, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3010 | const PropertyCallbackInfo<void>& info) { |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3011 | debug_options.set_port(value->Int32Value()); |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 3012 | } |
| 3013 | |
| 3014 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3015 | static void DebugProcess(const FunctionCallbackInfo<Value>& args); |
| 3016 | static void DebugPause(const FunctionCallbackInfo<Value>& args); |
| 3017 | static void DebugEnd(const FunctionCallbackInfo<Value>& args); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3018 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 3019 | namespace { |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3020 | |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 3021 | void NeedImmediateCallbackGetter(Local<Name> property, |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3022 | const PropertyCallbackInfo<Value>& info) { |
Ben Noordhuis | 7e88a93 | 2015-03-22 23:26:59 | [diff] [blame] | 3023 | Environment* env = Environment::GetCurrent(info); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3024 | 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 Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3028 | } |
| 3029 | |
| 3030 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 3031 | void NeedImmediateCallbackSetter( |
Ali Ijaz Sheikh | c1649a7 | 2016-02-12 08:58:26 | [diff] [blame] | 3032 | Local<Name> property, |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3033 | Local<Value> value, |
| 3034 | const PropertyCallbackInfo<void>& info) { |
Ben Noordhuis | 7e88a93 | 2015-03-22 23:26:59 | [diff] [blame] | 3035 | Environment* env = Environment::GetCurrent(info); |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3036 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3037 | 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 Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3040 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3041 | if (active == value->BooleanValue()) |
| 3042 | return; |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3043 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3044 | uv_idle_t* immediate_idle_handle = env->immediate_idle_handle(); |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3045 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3046 | if (active) { |
| 3047 | uv_check_stop(immediate_check_handle); |
| 3048 | uv_idle_stop(immediate_idle_handle); |
Shigeki Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3049 | } else { |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3050 | 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 Ohtsu | cd37251 | 2013-02-06 02:13:02 | [diff] [blame] | 3053 | } |
| 3054 | } |
| 3055 | |
| 3056 | |
Ben Noordhuis | f649626 | 2013-10-03 09:03:46 | [diff] [blame] | 3057 | void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3058 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 58cec4e | 2016-06-01 08:54:42 | [diff] [blame] | 3059 | env->StartProfilerIdleNotifier(); |
Ben Noordhuis | f649626 | 2013-10-03 09:03:46 | [diff] [blame] | 3060 | } |
| 3061 | |
| 3062 | |
| 3063 | void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3064 | Environment* env = Environment::GetCurrent(args); |
Ben Noordhuis | 58cec4e | 2016-06-01 08:54:42 | [diff] [blame] | 3065 | env->StopProfilerIdleNotifier(); |
Ben Noordhuis | f649626 | 2013-10-03 09:03:46 | [diff] [blame] | 3066 | } |
| 3067 | |
| 3068 | |
Trevor Norris | c80f8fa | 2013-08-01 21:53:52 | [diff] [blame] | 3069 | #define READONLY_PROPERTY(obj, str, var) \ |
| 3070 | do { \ |
Michaël Zasso | 67b5a8a | 2016-02-08 21:05:38 | [diff] [blame] | 3071 | obj->DefineOwnProperty(env->context(), \ |
| 3072 | OneByteString(env->isolate(), str), \ |
| 3073 | var, \ |
| 3074 | v8::ReadOnly).FromJust(); \ |
Trevor Norris | c80f8fa | 2013-08-01 21:53:52 | [diff] [blame] | 3075 | } while (0) |
| 3076 | |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 3077 | #define READONLY_DONT_ENUM_PROPERTY(obj, str, var) \ |
| 3078 | do { \ |
Michaël Zasso | 67b5a8a | 2016-02-08 21:05:38 | [diff] [blame] | 3079 | obj->DefineOwnProperty(env->context(), \ |
| 3080 | OneByteString(env->isolate(), str), \ |
| 3081 | var, \ |
| 3082 | static_cast<v8::PropertyAttribute>(v8::ReadOnly | \ |
| 3083 | v8::DontEnum)) \ |
| 3084 | .FromJust(); \ |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 3085 | } while (0) |
| 3086 | |
Anna Henningsen | 9d52222 | 2017-04-12 17:17:24 | [diff] [blame] | 3087 | } // anonymous namespace |
Trevor Norris | c80f8fa | 2013-08-01 21:53:52 | [diff] [blame] | 3088 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3089 | void SetupProcessObject(Environment* env, |
| 3090 | int argc, |
| 3091 | const char* const* argv, |
| 3092 | int exec_argc, |
| 3093 | const char* const* exec_argv) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3094 | HandleScope scope(env->isolate()); |
Ryan Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3095 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3096 | Local<Object> process = env->process_object(); |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 3097 | |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3098 | 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 Dahl | 5185c15 | 2010-06-18 07:26:49 | [diff] [blame] | 3104 | |
Ryan Dahl | f481183 | 2009-11-02 23:21:00 | [diff] [blame] | 3105 | // process.version |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3106 | READONLY_PROPERTY(process, |
| 3107 | "version", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3108 | FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION)); |
Ryan Dahl | 39b432e | 2010-08-17 18:24:10 | [diff] [blame] | 3109 | |
Ryan Dahl | ea9ee1f | 2011-07-28 02:30:32 | [diff] [blame] | 3110 | // process.moduleLoadList |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3111 | READONLY_PROPERTY(process, |
| 3112 | "moduleLoadList", |
| 3113 | env->module_load_list_array()); |
Ryan Dahl | ea9ee1f | 2011-07-28 02:30:32 | [diff] [blame] | 3114 | |
Nathan Rajlich | 35043ad | 2012-03-13 23:04:17 | [diff] [blame] | 3115 | // process.versions |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3116 | Local<Object> versions = Object::New(env->isolate()); |
Trevor Norris | c80f8fa | 2013-08-01 21:53:52 | [diff] [blame] | 3117 | READONLY_PROPERTY(process, "versions", versions); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3118 | |
| 3119 | const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR) |
| 3120 | "." |
Johan Bergström | c0a9d1b | 2015-01-26 23:08:44 | [diff] [blame] | 3121 | NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR) |
| 3122 | "." |
| 3123 | NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3124 | READONLY_PROPERTY(versions, |
| 3125 | "http_parser", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3126 | FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version)); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3127 | |
Ryan Dahl | 39b432e | 2010-08-17 18:24:10 | [diff] [blame] | 3128 | // +1 to get rid of the leading 'v' |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3129 | READONLY_PROPERTY(versions, |
| 3130 | "node", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3131 | OneByteString(env->isolate(), NODE_VERSION + 1)); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3132 | READONLY_PROPERTY(versions, |
| 3133 | "v8", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3134 | OneByteString(env->isolate(), V8::GetVersion())); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3135 | READONLY_PROPERTY(versions, |
| 3136 | "uv", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3137 | OneByteString(env->isolate(), uv_version_string())); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3138 | READONLY_PROPERTY(versions, |
| 3139 | "zlib", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3140 | FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION)); |
Johan Bergström | 01736dd | 2015-01-14 00:12:05 | [diff] [blame] | 3141 | READONLY_PROPERTY(versions, |
| 3142 | "ares", |
| 3143 | FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR)); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3144 | |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3145 | const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3146 | READONLY_PROPERTY( |
| 3147 | versions, |
| 3148 | "modules", |
| 3149 | FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version)); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3150 | |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 3151 | // 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 Bright | 13d6a1f | 2011-08-06 04:23:25 | [diff] [blame] | 3165 | #if HAVE_OPENSSL |
Ryan Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3166 | // Stupid code to slice out the version string. |
Ben Noordhuis | 7acdabb | 2013-11-04 21:42:48 | [diff] [blame] | 3167 | { // NOLINT(whitespace/braces) |
Ben Noordhuis | 962686b | 2013-11-03 20:00:37 | [diff] [blame] | 3168 | 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 Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3179 | } |
Ryan Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3180 | } |
Ben Noordhuis | 962686b | 2013-11-03 20:00:37 | [diff] [blame] | 3181 | READONLY_PROPERTY( |
| 3182 | versions, |
| 3183 | "openssl", |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3184 | OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i)); |
Ryan Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3185 | } |
Ryan Dahl | cd1ec27 | 2011-01-02 09:44:42 | [diff] [blame] | 3186 | #endif |
Ryan Dahl | 39b432e | 2010-08-17 18:24:10 | [diff] [blame] | 3187 | |
Nathan Rajlich | b1be540 | 2011-04-26 03:24:51 | [diff] [blame] | 3188 | // process.arch |
Bert Belder | e1fe270 | 2015-01-08 12:05:51 | [diff] [blame] | 3189 | READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH)); |
Nathan Rajlich | b1be540 | 2011-04-26 03:24:51 | [diff] [blame] | 3190 | |
Ryan Dahl | f481183 | 2009-11-02 23:21:00 | [diff] [blame] | 3191 | // process.platform |
Vladimir Kurchatkin | 9f45799 | 2015-01-09 12:38:09 | [diff] [blame] | 3192 | READONLY_PROPERTY(process, |
| 3193 | "platform", |
| 3194 | OneByteString(env->isolate(), NODE_PLATFORM)); |
Ryan Dahl | f481183 | 2009-11-02 23:21:00 | [diff] [blame] | 3195 | |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3196 | // process.release |
| 3197 | Local<Object> release = Object::New(env->isolate()); |
| 3198 | READONLY_PROPERTY(process, "release", release); |
cjihrig | 4f50d3f | 2015-08-21 01:45:38 | [diff] [blame] | 3199 | READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node")); |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3200 | |
| 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 |
cjihrig | a69ab27 | 2015-08-13 16:14:34 | [diff] [blame] | 3205 | # define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/" |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3206 | # endif |
| 3207 | #endif |
| 3208 | |
| 3209 | #if defined(NODE_RELEASE_URLBASE) |
Rod Vagg | 278a926 | 2015-09-05 04:41:34 | [diff] [blame] | 3210 | # 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 Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3212 | |
| 3213 | READONLY_PROPERTY(release, |
| 3214 | "sourceUrl", |
| 3215 | OneByteString(env->isolate(), |
Rod Vagg | 278a926 | 2015-09-05 04:41:34 | [diff] [blame] | 3216 | NODE_RELEASE_URLFPFX ".tar.gz")); |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3217 | READONLY_PROPERTY(release, |
| 3218 | "headersUrl", |
| 3219 | OneByteString(env->isolate(), |
Rod Vagg | 278a926 | 2015-09-05 04:41:34 | [diff] [blame] | 3220 | NODE_RELEASE_URLFPFX "-headers.tar.gz")); |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3221 | # ifdef _WIN32 |
| 3222 | READONLY_PROPERTY(release, |
| 3223 | "libUrl", |
| 3224 | OneByteString(env->isolate(), |
Rod Vagg | 278a926 | 2015-09-05 04:41:34 | [diff] [blame] | 3225 | strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-" |
| 3226 | NODE_ARCH "/node.lib" |
| 3227 | : NODE_RELEASE_URLPFX |
| 3228 | "win-x86/node.lib")); |
Rod Vagg | 04fd4fa | 2015-01-18 06:41:37 | [diff] [blame] | 3229 | # endif |
| 3230 | #endif |
| 3231 | |
Ryan Dahl | f3ad635 | 2010-02-03 20:19:08 | [diff] [blame] | 3232 | // process.argv |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3233 | Local<Array> arguments = Array::New(env->isolate(), argc); |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 3234 | for (int i = 0; i < argc; ++i) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3235 | arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i])); |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 3236 | } |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3237 | process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments); |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 3238 | |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 3239 | // process.execArgv |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3240 | Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc); |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 3241 | for (int i = 0; i < exec_argc; ++i) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3242 | exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i])); |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 3243 | } |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3244 | process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"), |
| 3245 | exec_arguments); |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 3246 | |
Ryan Dahl | f3ad635 | 2010-02-03 20:19:08 | [diff] [blame] | 3247 | // create process.env |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3248 | Local<ObjectTemplate> process_env_template = |
| 3249 | ObjectTemplate::New(env->isolate()); |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 3250 | process_env_template->SetHandler(NamedPropertyHandlerConfiguration( |
| 3251 | EnvGetter, |
| 3252 | EnvSetter, |
| 3253 | EnvQuery, |
| 3254 | EnvDeleter, |
| 3255 | EnvEnumerator, |
cjihrig | 1aa595e | 2016-11-03 16:16:54 | [diff] [blame] | 3256 | env->as_external())); |
AnnaMag | ab19412 | 2016-10-06 20:50:41 | [diff] [blame] | 3257 | |
Michaël Zasso | ad0ce57 | 2016-01-26 08:41:29 | [diff] [blame] | 3258 | Local<Object> process_env = |
| 3259 | process_env_template->NewInstance(env->context()).ToLocalChecked(); |
Ben Noordhuis | 63c47e7 | 2016-10-20 20:36:17 | [diff] [blame] | 3260 | process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env); |
Ryan Dahl | f3ad635 | 2010-02-03 20:19:08 | [diff] [blame] | 3261 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3262 | READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid())); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3263 | READONLY_PROPERTY(process, "features", GetFeatures(env)); |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3264 | |
| 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()); |
Ryan | dc39e82 | 2009-09-10 12:07:35 | [diff] [blame] | 3271 | |
TJ Holowaychuk | 9481bc1 | 2010-10-07 02:05:01 | [diff] [blame] | 3272 | // -e, --eval |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3273 | if (eval_string) { |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3274 | READONLY_PROPERTY(process, |
| 3275 | "_eval", |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3276 | String::NewFromUtf8(env->isolate(), eval_string)); |
Nathan Rajlich | ef3a874 | 2012-04-24 08:24:13 | [diff] [blame] | 3277 | } |
| 3278 | |
| 3279 | // -p, --print |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3280 | if (print_eval) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3281 | READONLY_PROPERTY(process, "_print_eval", True(env->isolate())); |
TJ Holowaychuk | 9481bc1 | 2010-10-07 02:05:01 | [diff] [blame] | 3282 | } |
| 3283 | |
Dave Eddy | 2e6ece4 | 2015-08-17 21:33:13 | [diff] [blame] | 3284 | // -c, --check |
| 3285 | if (syntax_check_only) { |
| 3286 | READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate())); |
| 3287 | } |
| 3288 | |
Nathan Rajlich | 6292df6 | 2012-04-24 08:32:33 | [diff] [blame] | 3289 | // -i, --interactive |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3290 | if (force_repl) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3291 | READONLY_PROPERTY(process, "_forceRepl", True(env->isolate())); |
Nathan Rajlich | feaa8a4 | 2012-03-21 07:05:25 | [diff] [blame] | 3292 | } |
| 3293 | |
Sam Roberts | e505c07 | 2017-04-05 21:04:44 | [diff] [blame] | 3294 | // -r, --require |
Sam Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 3295 | if (!preload_modules.empty()) { |
Ali Ijaz Sheikh | 1514b82 | 2015-02-17 22:37:37 | [diff] [blame] | 3296 | Local<Array> array = Array::New(env->isolate()); |
Sam Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 3297 | for (unsigned int i = 0; i < preload_modules.size(); ++i) { |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3298 | Local<String> module = String::NewFromUtf8(env->isolate(), |
Sam Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 3299 | preload_modules[i].c_str()); |
Ali Ijaz Sheikh | 1514b82 | 2015-02-17 22:37:37 | [diff] [blame] | 3300 | array->Set(i, module); |
| 3301 | } |
| 3302 | READONLY_PROPERTY(process, |
| 3303 | "_preload_modules", |
| 3304 | array); |
Ali Ijaz Sheikh | f06b16f | 2015-03-25 19:19:46 | [diff] [blame] | 3305 | |
Sam Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 3306 | preload_modules.clear(); |
Ali Ijaz Sheikh | 1514b82 | 2015-02-17 22:37:37 | [diff] [blame] | 3307 | } |
| 3308 | |
isaacs | 5b39929 | 2012-06-21 18:42:33 | [diff] [blame] | 3309 | // --no-deprecation |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3310 | if (no_deprecation) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3311 | READONLY_PROPERTY(process, "noDeprecation", True(env->isolate())); |
isaacs | 5b39929 | 2012-06-21 18:42:33 | [diff] [blame] | 3312 | } |
| 3313 | |
Sam Roberts | e505c07 | 2017-04-05 21:04:44 | [diff] [blame] | 3314 | // --no-warnings |
James M Snell | c6656db | 2016-01-20 19:38:35 | [diff] [blame] | 3315 | if (no_process_warnings) { |
| 3316 | READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate())); |
| 3317 | } |
| 3318 | |
Sam Roberts | e505c07 | 2017-04-05 21:04:44 | [diff] [blame] | 3319 | // --trace-warnings |
James M Snell | c6656db | 2016-01-20 19:38:35 | [diff] [blame] | 3320 | if (trace_warnings) { |
| 3321 | READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate())); |
| 3322 | } |
| 3323 | |
isaacs | 5038f40 | 2013-03-06 01:46:37 | [diff] [blame] | 3324 | // --throw-deprecation |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3325 | if (throw_deprecation) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3326 | READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate())); |
isaacs | 5038f40 | 2013-03-06 01:46:37 | [diff] [blame] | 3327 | } |
| 3328 | |
Fedor Indutny | 8363ede | 2016-03-23 01:05:54 | [diff] [blame] | 3329 | #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 Loring | 49440b7 | 2015-11-25 14:08:58 | [diff] [blame] | 3334 | // --prof-process |
| 3335 | if (prof_process) { |
| 3336 | READONLY_PROPERTY(process, "profProcess", True(env->isolate())); |
| 3337 | } |
| 3338 | |
isaacs | 5b39929 | 2012-06-21 18:42:33 | [diff] [blame] | 3339 | // --trace-deprecation |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3340 | if (trace_deprecation) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3341 | READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate())); |
isaacs | 5b39929 | 2012-06-21 18:42:33 | [diff] [blame] | 3342 | } |
| 3343 | |
Ali Ijaz Sheikh | 4d4cfb2 | 2016-05-05 15:31:34 | [diff] [blame] | 3344 | // --debug-brk |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3345 | if (debug_options.wait_for_connect()) { |
Ali Ijaz Sheikh | 4d4cfb2 | 2016-05-05 15:31:34 | [diff] [blame] | 3346 | READONLY_PROPERTY(process, "_debugWaitConnect", True(env->isolate())); |
| 3347 | } |
| 3348 | |
James M Snell | d387591 | 2016-02-04 01:16:10 | [diff] [blame] | 3349 | // --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 Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3359 | 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 Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3363 | exec_path_value = String::NewFromUtf8(env->isolate(), |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3364 | exec_path, |
| 3365 | String::kNormalString, |
| 3366 | exec_path_len); |
Marshall Culpepper | ca35ba6 | 2010-06-22 06:31:19 | [diff] [blame] | 3367 | } else { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3368 | exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]); |
Marshall Culpepper | ca35ba6 | 2010-06-22 06:31:19 | [diff] [blame] | 3369 | } |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3370 | process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"), |
| 3371 | exec_path_value); |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3372 | delete[] exec_path; |
Marshall Culpepper | ca35ba6 | 2010-06-22 06:31:19 | [diff] [blame] | 3373 | |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3374 | 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 Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 3380 | |
Ryan Dahl | 3881455 | 2009-10-09 15:15:47 | [diff] [blame] | 3381 | // define various internal methods |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3382 | 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 Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 3394 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3395 | env->SetMethod(process, "umask", Umask); |
Ryan Dahl | acc120a | 2011-08-09 20:53:56 | [diff] [blame] | 3396 | |
Linus MÃ¥rtensson | 5e4e8ec | 2013-05-08 12:10:07 | [diff] [blame] | 3397 | #if defined(__POSIX__) && !defined(__ANDROID__) |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3398 | env->SetMethod(process, "getuid", GetUid); |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 3399 | env->SetMethod(process, "geteuid", GetEUid); |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3400 | env->SetMethod(process, "setuid", SetUid); |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 3401 | env->SetMethod(process, "seteuid", SetEUid); |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 3402 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3403 | env->SetMethod(process, "setgid", SetGid); |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 3404 | env->SetMethod(process, "setegid", SetEGid); |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3405 | env->SetMethod(process, "getgid", GetGid); |
Evan Lucas | 3c92ca2 | 2015-04-27 16:24:19 | [diff] [blame] | 3406 | env->SetMethod(process, "getegid", GetEGid); |
Ben Noordhuis | 3ece130 | 2012-12-04 05:36:23 | [diff] [blame] | 3407 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3408 | env->SetMethod(process, "getgroups", GetGroups); |
| 3409 | env->SetMethod(process, "setgroups", SetGroups); |
| 3410 | env->SetMethod(process, "initgroups", InitGroups); |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 3411 | #endif // __POSIX__ && !defined(__ANDROID__) |
James Duncan | df1c1e5 | 2010-02-23 22:45:02 | [diff] [blame] | 3412 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3413 | env->SetMethod(process, "_kill", Kill); |
Bert Belder | 30bab52 | 2010-11-25 00:09:06 | [diff] [blame] | 3414 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3415 | env->SetMethod(process, "_debugProcess", DebugProcess); |
| 3416 | env->SetMethod(process, "_debugPause", DebugPause); |
| 3417 | env->SetMethod(process, "_debugEnd", DebugEnd); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3418 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3419 | env->SetMethod(process, "hrtime", Hrtime); |
Nathan Rajlich | 07c886f | 2012-03-05 16:51:58 | [diff] [blame] | 3420 | |
Patrick Mueller | 52cb410 | 2016-04-05 13:17:48 | [diff] [blame] | 3421 | env->SetMethod(process, "cpuUsage", CPUUsage); |
| 3422 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3423 | env->SetMethod(process, "dlopen", DLOpen); |
Bert Belder | dd93c53 | 2011-10-28 10:05:09 | [diff] [blame] | 3424 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3425 | env->SetMethod(process, "uptime", Uptime); |
| 3426 | env->SetMethod(process, "memoryUsage", MemoryUsage); |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 3427 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3428 | env->SetMethod(process, "binding", Binding); |
Thorsten Lorenz | 0fe7a0d | 2014-09-15 17:00:22 | [diff] [blame] | 3429 | env->SetMethod(process, "_linkedBinding", LinkedBinding); |
Ryan Dahl | 627fb5a | 2010-03-15 20:48:03 | [diff] [blame] | 3430 | |
Trevor Norris | 494227b | 2015-10-14 20:58:52 | [diff] [blame] | 3431 | env->SetMethod(process, "_setupProcessObject", SetupProcessObject); |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3432 | env->SetMethod(process, "_setupNextTick", SetupNextTick); |
Petka Antonov | 872702d | 2015-02-22 12:44:12 | [diff] [blame] | 3433 | env->SetMethod(process, "_setupPromises", SetupPromises); |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3434 | env->SetMethod(process, "_setupDomainUse", SetupDomainUse); |
Trevor Norris | f0b6889 | 2013-03-26 05:32:41 | [diff] [blame] | 3435 | |
Trevor Norris | 4f7f8bb | 2013-02-26 17:47:36 | [diff] [blame] | 3436 | // pre-set _events object for faster emit checks |
Brian White | e38bade | 2016-04-07 00:33:28 | [diff] [blame] | 3437 | Local<Object> events_obj = Object::New(env->isolate()); |
Ben Noordhuis | b4ea3a0 | 2016-08-21 10:31:20 | [diff] [blame] | 3438 | CHECK(events_obj->SetPrototype(env->context(), |
| 3439 | Null(env->isolate())).FromJust()); |
Brian White | e38bade | 2016-04-07 00:33:28 | [diff] [blame] | 3440 | process->Set(env->events_string(), events_obj); |
Dean McNamee | f67e8f2 | 2011-03-15 22:39:16 | [diff] [blame] | 3441 | } |
| 3442 | |
| 3443 | |
Trevor Norris | c80f8fa | 2013-08-01 21:53:52 | [diff] [blame] | 3444 | #undef READONLY_PROPERTY |
| 3445 | |
| 3446 | |
Anna Henningsen | 0815b94 | 2016-05-08 01:28:47 | [diff] [blame] | 3447 | void SignalExit(int signo) { |
Ryan Dahl | 4e43afd | 2011-09-30 20:11:47 | [diff] [blame] | 3448 | uv_tty_reset_mode(); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3449 | if (trace_enabled) { |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 3450 | v8_platform.StopTracingAgent(); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3451 | } |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 3452 | #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 Hauge | c61b0e9 | 2014-03-31 07:52:03 | [diff] [blame] | 3459 | raise(signo); |
Dean McNamee | f67e8f2 | 2011-03-15 22:39:16 | [diff] [blame] | 3460 | } |
| 3461 | |
| 3462 | |
isaacs | 906a175 | 2013-08-21 22:36:50 | [diff] [blame] | 3463 | // 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. |
| 3467 | static void RawDebug(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 3468 | CHECK(args.Length() == 1 && args[0]->IsString() && |
| 3469 | "must be called with a single string"); |
Trevor Norris | cbf76c1 | 2015-01-07 22:13:35 | [diff] [blame] | 3470 | node::Utf8Value message(args.GetIsolate(), args[0]); |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 3471 | PrintErrorString("%s\n", *message); |
isaacs | 906a175 | 2013-08-21 22:36:50 | [diff] [blame] | 3472 | fflush(stderr); |
| 3473 | } |
| 3474 | |
| 3475 | |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3476 | void LoadEnvironment(Environment* env) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3477 | HandleScope handle_scope(env->isolate()); |
Ben Noordhuis | 34b0a36 | 2013-07-29 03:07:07 | [diff] [blame] | 3478 | |
Michaël Zasso | 79d7475 | 2016-01-26 08:06:43 | [diff] [blame] | 3479 | TryCatch try_catch(env->isolate()); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 3480 | |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 3481 | // 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 Bevenius | 81b6882 | 2016-06-12 11:14:34 | [diff] [blame] | 3486 | // 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 Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3491 | Local<Value> f_value = ExecuteString(env, MainSource(env), script_name); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 3492 | if (try_catch.HasCaught()) { |
Fedor Indutny | f1de13b | 2014-02-05 16:38:33 | [diff] [blame] | 3493 | ReportException(env, try_catch); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 3494 | exit(10); |
| 3495 | } |
Daniel Bevenius | 0441f2a | 2016-08-03 08:08:47 | [diff] [blame] | 3496 | // The bootstrap_node.js file returns a function 'f' |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 3497 | CHECK(f_value->IsFunction()); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 3498 | Local<Function> f = Local<Function>::Cast(f_value); |
| 3499 | |
Ryan Dahl | f8ce848 | 2010-09-17 07:01:07 | [diff] [blame] | 3500 | // Add a reference to the global object |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3501 | Local<Object> global = env->context()->Global(); |
Zoran Tomicic | d98ea70 | 2010-02-22 05:15:44 | [diff] [blame] | 3502 | |
Ben Noordhuis | c4def50 | 2013-10-28 19:18:59 | [diff] [blame] | 3503 | #if defined HAVE_DTRACE || defined HAVE_ETW |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3504 | InitDTrace(env, global); |
Ryan Dahl | e9257b8 | 2011-02-10 02:50:26 | [diff] [blame] | 3505 | #endif |
Ryan Dahl | 068b733 | 2011-01-25 01:50:10 | [diff] [blame] | 3506 | |
Glen Keane | 5e825d1 | 2015-01-22 12:35:16 | [diff] [blame] | 3507 | #if defined HAVE_LTTNG |
| 3508 | InitLTTNG(env, global); |
| 3509 | #endif |
| 3510 | |
Scott Blomquist | f657ce6 | 2012-11-20 23:27:22 | [diff] [blame] | 3511 | #if defined HAVE_PERFCTR |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3512 | InitPerfCounters(env, global); |
Scott Blomquist | f657ce6 | 2012-11-20 23:27:22 | [diff] [blame] | 3513 | #endif |
| 3514 | |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 3515 | // 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 Fleischer | 4897ae2 | 2017-02-06 01:18:46 | [diff] [blame] | 3519 | // to attach the debugger fast enough to break on exception |
Miroslav Bajtos | c16963b | 2013-06-17 19:19:59 | [diff] [blame] | 3520 | // thrown during process startup. |
| 3521 | try_catch.SetVerbose(true); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 3522 | |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3523 | env->SetMethod(env->process_object(), "_rawDebug", RawDebug); |
isaacs | 906a175 | 2013-08-21 22:36:50 | [diff] [blame] | 3524 | |
Jeremiah Senkpiel | 21d66d6 | 2016-03-23 22:09:10 | [diff] [blame] | 3525 | // 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 Bevenius | a01e8bc | 2016-09-04 18:49:09 | [diff] [blame] | 3529 | // Now we call 'f' with the 'process' variable that we've built up with |
Daniel Bevenius | 8afde12 | 2016-09-06 07:31:02 | [diff] [blame] | 3530 | // all our bindings. Inside bootstrap_node.js and internal/process we'll |
| 3531 | // take care of assigning things to their places. |
Daniel Bevenius | a01e8bc | 2016-09-04 18:49:09 | [diff] [blame] | 3532 | |
| 3533 | // We start the process this way in order to be more modular. Developers |
Daniel Bevenius | 8afde12 | 2016-09-06 07:31:02 | [diff] [blame] | 3534 | // who do not like how bootstrap_node.js sets up the module system but do |
Daniel Bevenius | a01e8bc | 2016-09-04 18:49:09 | [diff] [blame] | 3535 | // like Node's I/O bindings may want to replace 'f' with their own function. |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3536 | Local<Value> arg = env->process_object(); |
Ben Noordhuis | 00c876d | 2016-03-31 10:39:37 | [diff] [blame] | 3537 | f->Call(Null(env->isolate()), 1, &arg); |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 3538 | } |
| 3539 | |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3540 | static void PrintHelp() { |
Jeremiah Senkpiel | 91cf55b | 2016-03-18 17:26:41 | [diff] [blame] | 3541 | // XXX: If you add an option here, please also add it to doc/node.1 and |
Robert Jefe Lindstaedt | 0800c0a | 2016-04-20 22:12:40 | [diff] [blame] | 3542 | // doc/api/cli.md |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3543 | printf("Usage: node [options] [ -e script | script.js ] [arguments]\n" |
Ali Ijaz Sheikh | a235ccd | 2017-03-14 21:20:38 | [diff] [blame] | 3544 | " node inspect script.js [arguments]\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3545 | "\n" |
| 3546 | "Options:\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3547 | " -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 " |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3554 | "repeated)\n" |
Josh Gavant | 6ff3b03 | 2016-12-15 04:18:15 | [diff] [blame] | 3555 | #if HAVE_INSPECTOR |
Gibson Fahnestock | 2d2970e | 2017-03-28 15:54:30 | [diff] [blame] | 3556 | " --inspect[=[host:]port] activate inspector on host:port\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3557 | " (default: 127.0.0.1:9229)\n" |
Gibson Fahnestock | 2d2970e | 2017-03-28 15:54:30 | [diff] [blame] | 3558 | " --inspect-brk[=[host:]port]\n" |
| 3559 | " activate inspector on host:port\n" |
Josh Gavant | 6ff3b03 | 2016-12-15 04:18:15 | [diff] [blame] | 3560 | " and break at start of user script\n" |
| 3561 | #endif |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3562 | " --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 Ginchereau | 56e881d | 2017-03-20 21:55:26 | [diff] [blame] | 3566 | " --napi-modules load N-API modules\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3567 | " --trace-warnings show stack traces on process warnings\n" |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 3568 | " --redirect-warnings=path\n" |
| 3569 | " write warnings to path instead of\n" |
| 3570 | " stderr\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3571 | " --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 Meck | cf14a24 | 2015-07-09 16:15:26 | [diff] [blame] | 3577 | "snapshots\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3578 | " --prof-process process v8 profiler output generated\n" |
| 3579 | " using --prof\n" |
| 3580 | " --zero-fill-buffers automatically zero-fill all newly " |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3581 | "allocated\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3582 | " 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 Snell | 5ba868f | 2015-08-17 22:51:51 | [diff] [blame] | 3585 | #if HAVE_OPENSSL |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3586 | " --tls-cipher-list=val use an alternative default TLS cipher " |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3587 | "list\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3588 | " --use-bundled-ca use bundled CA store" |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 3589 | #if !defined(NODE_OPENSSL_CERT_STORE) |
| 3590 | " (default)" |
| 3591 | #endif |
| 3592 | "\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3593 | " --use-openssl-ca use OpenSSL's default CA store" |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 3594 | #if defined(NODE_OPENSSL_CERT_STORE) |
| 3595 | " (default)" |
| 3596 | #endif |
| 3597 | "\n" |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 3598 | #if NODE_FIPS_MODE |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3599 | " --enable-fips enable FIPS crypto at startup\n" |
| 3600 | " --force-fips force FIPS crypto (cannot be disabled)\n" |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 3601 | #endif /* NODE_FIPS_MODE */ |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 3602 | " --openssl-config=file load OpenSSL configuration from the\n" |
| 3603 | " specified file (overrides\n" |
| 3604 | " OPENSSL_CONF)\n" |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 3605 | #endif /* HAVE_OPENSSL */ |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3606 | #if defined(NODE_HAVE_I18N_SUPPORT) |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3607 | " --icu-data-dir=dir set ICU data load path to dir\n" |
| 3608 | " (overrides NODE_ICU_DATA)\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3609 | #if !defined(NODE_HAVE_SMALL_ICU) |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3610 | " note: linked-in ICU data is present\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3611 | #endif |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3612 | " --preserve-symlinks preserve symbolic links when resolving\n" |
| 3613 | " and caching modules\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3614 | #endif |
| 3615 | "\n" |
| 3616 | "Environment variables:\n" |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3617 | "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 Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3622 | #if defined(NODE_HAVE_I18N_SUPPORT) |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3623 | "NODE_ICU_DATA data path for ICU (Intl object) data\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3624 | #if !defined(NODE_HAVE_SMALL_ICU) |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3625 | " (will extend linked-in data)\n" |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3626 | #endif |
| 3627 | #endif |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3628 | "NODE_NO_WARNINGS set to 1 to silence process warnings\n" |
Roman Reiss | 2d23562 | 2016-12-22 06:10:22 | [diff] [blame] | 3629 | #ifdef _WIN32 |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3630 | "NODE_PATH ';'-separated list of directories\n" |
Roman Reiss | 2d23562 | 2016-12-22 06:10:22 | [diff] [blame] | 3631 | #else |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3632 | "NODE_PATH ':'-separated list of directories\n" |
Roman Reiss | 2d23562 | 2016-12-22 06:10:22 | [diff] [blame] | 3633 | #endif |
Aashil Patel | 5d27cc1 | 2017-01-21 22:44:29 | [diff] [blame] | 3634 | " prefixed to the module search path\n" |
| 3635 | "NODE_REPL_HISTORY path to the persistent REPL history\n" |
| 3636 | " file\n" |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 3637 | "NODE_REDIRECT_WARNINGS write warnings to path instead of\n" |
| 3638 | " stderr\n" |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 3639 | "OPENSSL_CONF load OpenSSL configuration from file\n" |
| 3640 | "\n" |
cjihrig | a69ab27 | 2015-08-13 16:14:34 | [diff] [blame] | 3641 | "Documentation can be found at https://nodejs.org/\n"); |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3642 | } |
| 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 |
| 3656 | static 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 Bevenius | de168b4 | 2017-04-10 13:13:24 | [diff] [blame] | 3666 | #if HAVE_OPENSSL |
Daniel Bevenius | 8a7db9d | 2017-03-28 06:56:39 | [diff] [blame] | 3667 | bool use_bundled_ca = false; |
| 3668 | bool use_openssl_ca = false; |
Daniel Bevenius | de168b4 | 2017-04-10 13:13:24 | [diff] [blame] | 3669 | #endif // HAVE_INSPECTOR |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3670 | |
| 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 Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3675 | } |
| 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 Loring | 49440b7 | 2015-11-25 14:08:58 | [diff] [blame] | 3685 | bool short_circuit = false; |
| 3686 | while (index < nargs && argv[index][0] == '-' && !short_circuit) { |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3687 | const char* const arg = argv[index]; |
| 3688 | unsigned int args_consumed = 1; |
| 3689 | |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3690 | if (debug_options.ParseOption(arg)) { |
| 3691 | // Done, consumed by DebugOptions::ParseOption(). |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3692 | } 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 Roberts | cecdf7c | 2017-04-05 18:45:52 | [diff] [blame] | 3732 | preload_modules.push_back(module); |
Dave Eddy | 2e6ece4 | 2015-08-17 21:33:13 | [diff] [blame] | 3733 | } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) { |
| 3734 | syntax_check_only = true; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3735 | } 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 Ginchereau | 56e881d | 2017-03-20 21:55:26 | [diff] [blame] | 3739 | } else if (strcmp(arg, "--napi-modules") == 0) { |
| 3740 | load_napi_modules = true; |
James M Snell | c6656db | 2016-01-20 19:38:35 | [diff] [blame] | 3741 | } 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 Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 3745 | } else if (strncmp(arg, "--redirect-warnings=", 20) == 0) { |
| 3746 | config_warning_file = arg + 20; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3747 | } 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; |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 3751 | } 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 Meck | cf14a24 | 2015-07-09 16:15:26 | [diff] [blame] | 3761 | } else if (strcmp(arg, "--track-heap-objects") == 0) { |
| 3762 | track_heap_objects = true; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3763 | } else if (strcmp(arg, "--throw-deprecation") == 0) { |
| 3764 | throw_deprecation = true; |
James M Snell | d387591 | 2016-02-04 01:16:10 | [diff] [blame] | 3765 | } else if (strncmp(arg, "--security-revert=", 18) == 0) { |
| 3766 | const char* cve = arg + 18; |
| 3767 | Revert(cve); |
James M Snell | 5d38d54 | 2016-05-02 23:31:20 | [diff] [blame] | 3768 | } else if (strcmp(arg, "--preserve-symlinks") == 0) { |
| 3769 | config_preserve_symlinks = true; |
Matt Loring | 49440b7 | 2015-11-25 14:08:58 | [diff] [blame] | 3770 | } else if (strcmp(arg, "--prof-process") == 0) { |
| 3771 | prof_process = true; |
| 3772 | short_circuit = true; |
James M Snell | 85ab4a5 | 2016-01-25 23:00:06 | [diff] [blame] | 3773 | } else if (strcmp(arg, "--zero-fill-buffers") == 0) { |
| 3774 | zero_fill_all_buffers = true; |
James M Snell | a16b570 | 2017-03-11 20:18:53 | [diff] [blame^] | 3775 | } else if (strcmp(arg, "--pending-deprecation") == 0) { |
| 3776 | config_pending_deprecation = true; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3777 | } else if (strcmp(arg, "--v8-options") == 0) { |
| 3778 | new_v8_argv[new_v8_argc] = "--help"; |
| 3779 | new_v8_argc += 1; |
Tom Gallacher | 03e07d3 | 2015-12-18 12:24:56 | [diff] [blame] | 3780 | } else if (strncmp(arg, "--v8-pool-size=", 15) == 0) { |
| 3781 | v8_thread_pool_size = atoi(arg + 15); |
James M Snell | 5ba868f | 2015-08-17 22:51:51 | [diff] [blame] | 3782 | #if HAVE_OPENSSL |
| 3783 | } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) { |
| 3784 | default_cipher_list = arg + 18; |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 3785 | } else if (strncmp(arg, "--use-openssl-ca", 16) == 0) { |
| 3786 | ssl_openssl_cert_store = true; |
Daniel Bevenius | 8a7db9d | 2017-03-28 06:56:39 | [diff] [blame] | 3787 | use_openssl_ca = true; |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 3788 | } else if (strncmp(arg, "--use-bundled-ca", 16) == 0) { |
Daniel Bevenius | 8a7db9d | 2017-03-28 06:56:39 | [diff] [blame] | 3789 | use_bundled_ca = true; |
Adam Majer | 33012e9 | 2016-12-21 10:16:39 | [diff] [blame] | 3790 | ssl_openssl_cert_store = false; |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 3791 | #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 Indutny | db411cf | 2016-09-29 08:53:30 | [diff] [blame] | 3797 | } else if (strncmp(arg, "--openssl-config=", 17) == 0) { |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 3798 | openssl_config.assign(arg + 17); |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 3799 | #endif /* HAVE_OPENSSL */ |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3800 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 3801 | } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) { |
Ben Noordhuis | 291b599 | 2017-02-11 13:04:58 | [diff] [blame] | 3802 | icu_data_dir.assign(arg + 15); |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3803 | #endif |
| 3804 | } else if (strcmp(arg, "--expose-internals") == 0 || |
| 3805 | strcmp(arg, "--expose_internals") == 0) { |
Sam Roberts | 8086cb6 | 2017-04-05 21:06:52 | [diff] [blame] | 3806 | config_expose_internals = true; |
John Barboza | 0a9f360 | 2016-12-30 05:28:38 | [diff] [blame] | 3807 | } else if (strcmp(arg, "--") == 0) { |
| 3808 | index += 1; |
| 3809 | break; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3810 | } 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 Bevenius | 8a7db9d | 2017-03-28 06:56:39 | [diff] [blame] | 3824 | #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 Katz | a5f91ab | 2017-03-30 06:35:03 | [diff] [blame] | 3834 | 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 Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3840 | // 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 Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 3854 | } |
| 3855 | |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3856 | |
Peter Rybin | 688859a | 2012-07-03 19:21:37 | [diff] [blame] | 3857 | // Called from V8 Debug Agent TCP thread. |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3858 | static void DispatchMessagesDebugAgentCallback(Environment* env) { |
| 3859 | // TODO(indutny): move async handle to environment |
Peter Rybin | 688859a | 2012-07-03 19:21:37 | [diff] [blame] | 3860 | uv_async_send(&dispatch_debug_messages_async); |
| 3861 | } |
| 3862 | |
| 3863 | |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3864 | static void StartDebug(Environment* env, const char* path, |
| 3865 | DebugOptions debug_options) { |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3866 | CHECK(!debugger_running); |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3867 | if (debug_options.debugger_enabled()) { |
Pavel Feldman | 84ad31f | 2016-02-07 16:47:14 | [diff] [blame] | 3868 | env->debugger_agent()->set_dispatch_handler( |
| 3869 | DispatchMessagesDebugAgentCallback); |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3870 | debugger_running = env->debugger_agent()->Start(debug_options); |
Ali Ijaz Sheikh | a766ebf | 2016-06-08 01:02:03 | [diff] [blame] | 3871 | if (debugger_running == false) { |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3872 | fprintf(stderr, "Starting debugger on %s:%d failed\n", |
| 3873 | debug_options.host_name().c_str(), debug_options.port()); |
Ali Ijaz Sheikh | a766ebf | 2016-06-08 01:02:03 | [diff] [blame] | 3874 | fflush(stderr); |
Ali Ijaz Sheikh | a766ebf | 2016-06-08 01:02:03 | [diff] [blame] | 3875 | } |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 3876 | #if HAVE_INSPECTOR |
| 3877 | } else { |
| 3878 | debugger_running = v8_platform.StartInspector(env, path, debug_options); |
| 3879 | #endif // HAVE_INSPECTOR |
Pavel Feldman | 84ad31f | 2016-02-07 16:47:14 | [diff] [blame] | 3880 | } |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3881 | } |
Ben Noordhuis | ca363cf | 2013-10-15 21:32:18 | [diff] [blame] | 3882 | |
Ben Noordhuis | ca363cf | 2013-10-15 21:32:18 | [diff] [blame] | 3883 | |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3884 | // Called from the main thread. |
| 3885 | static void EnableDebug(Environment* env) { |
| 3886 | CHECK(debugger_running); |
Ben Noordhuis | c5c28c3 | 2015-10-10 13:01:49 | [diff] [blame] | 3887 | |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3888 | // Send message to enable debug in workers |
| 3889 | HandleScope handle_scope(env->isolate()); |
| 3890 | |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 3891 | Local<Object> message = Object::New(env->isolate()); |
Ben Noordhuis | ca363cf | 2013-10-15 21:32:18 | [diff] [blame] | 3892 | 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 Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3896 | message |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 3897 | }; |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 3898 | MakeCallback(env, env->process_object(), "emit", arraysize(argv), argv); |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3899 | |
| 3900 | // Enabled debugger, possibly making it wait on a semaphore |
| 3901 | env->debugger_agent()->Enable(); |
Miroslav Bajtoš | 43ec1b1 | 2013-05-02 06:34:22 | [diff] [blame] | 3902 | } |
| 3903 | |
| 3904 | |
Ben Noordhuis | ca363cf | 2013-10-15 21:32:18 | [diff] [blame] | 3905 | // Called from the main thread. |
Saúl Ibarra Corretgé | 42b9343 | 2014-03-12 23:08:29 | [diff] [blame] | 3906 | static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) { |
Ben Noordhuis | d7087df | 2016-06-17 23:39:05 | [diff] [blame] | 3907 | Mutex::ScopedLock scoped_lock(node_isolate_mutex); |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 3908 | if (auto isolate = node_isolate) { |
| 3909 | if (debugger_running == false) { |
| 3910 | fprintf(stderr, "Starting debugger agent.\n"); |
Ben Noordhuis | 53e64bb | 2015-10-26 13:11:03 | [diff] [blame] | 3911 | |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 3912 | HandleScope scope(isolate); |
| 3913 | Environment* env = Environment::GetCurrent(isolate); |
| 3914 | Context::Scope context_scope(env->context()); |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 3915 | debug_options.EnableDebugAgent(DebugAgentType::kDebugger); |
| 3916 | StartDebug(env, nullptr, debug_options); |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 3917 | EnableDebug(env); |
| 3918 | } |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 3919 | |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 3920 | Isolate::Scope isolate_scope(isolate); |
| 3921 | v8::Debug::ProcessDebugMessages(isolate); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 3922 | } |
Ryan Dahl | 2a7e7b1 | 2010-12-18 19:17:29 | [diff] [blame] | 3923 | } |
| 3924 | |
| 3925 | |
Fedor Indutny | 82d0ac7 | 2011-09-24 13:51:59 | [diff] [blame] | 3926 | #ifdef __POSIX__ |
Anna Henningsen | 0815b94 | 2016-05-08 01:28:47 | [diff] [blame] | 3927 | void RegisterSignalHandler(int signal, |
| 3928 | void (*handler)(int signal), |
| 3929 | bool reset_handler) { |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 3930 | struct sigaction sa; |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 3931 | memset(&sa, 0, sizeof(sa)); |
| 3932 | sa.sa_handler = handler; |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 3933 | #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 Hauge | c61b0e9 | 2014-03-31 07:52:03 | [diff] [blame] | 3937 | sa.sa_flags = reset_handler ? SA_RESETHAND : 0; |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 3938 | #endif |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 3939 | sigfillset(&sa.sa_mask); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 3940 | CHECK_EQ(sigaction(signal, &sa, nullptr), 0); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3941 | } |
| 3942 | |
| 3943 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3944 | void DebugProcess(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3945 | Environment* env = Environment::GetCurrent(args); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3946 | |
| 3947 | if (args.Length() != 1) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3948 | return env->ThrowError("Invalid number of arguments."); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3949 | } |
| 3950 | |
| 3951 | pid_t pid; |
| 3952 | int r; |
| 3953 | |
| 3954 | pid = args[0]->IntegerValue(); |
| 3955 | r = kill(pid, SIGUSR1); |
| 3956 | if (r != 0) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3957 | return env->ThrowErrnoException(errno, "kill"); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3958 | } |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 3959 | } |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 3960 | #endif // __POSIX__ |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 3961 | |
| 3962 | |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3963 | #ifdef _WIN32 |
Bert Belder | 8f2694b | 2012-02-16 21:19:48 | [diff] [blame] | 3964 | static 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 Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3967 | } |
| 3968 | |
| 3969 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 3970 | static void DebugProcess(const FunctionCallbackInfo<Value>& args) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 3971 | Environment* env = Environment::GetCurrent(args); |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 3972 | Isolate* isolate = args.GetIsolate(); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3973 | DWORD pid; |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 3974 | HANDLE process = nullptr; |
| 3975 | HANDLE thread = nullptr; |
| 3976 | HANDLE mapping = nullptr; |
Bert Belder | 8f2694b | 2012-02-16 21:19:48 | [diff] [blame] | 3977 | wchar_t mapping_name[32]; |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 3978 | LPTHREAD_START_ROUTINE* handler = nullptr; |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3979 | |
| 3980 | if (args.Length() != 1) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 3981 | env->ThrowError("Invalid number of arguments."); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3982 | goto out; |
| 3983 | } |
| 3984 | |
| 3985 | pid = (DWORD) args[0]->IntegerValue(); |
| 3986 | |
Bert Belder | 68db206 | 2012-02-03 14:37:46 | [diff] [blame] | 3987 | process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3988 | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | |
| 3989 | PROCESS_VM_READ, |
| 3990 | FALSE, |
| 3991 | pid); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 3992 | if (process == nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 3993 | isolate->ThrowException( |
| 3994 | WinapiErrnoException(isolate, GetLastError(), "OpenProcess")); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 3995 | goto out; |
| 3996 | } |
| 3997 | |
| 3998 | if (GetDebugSignalHandlerMappingName(pid, |
| 3999 | mapping_name, |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 4000 | arraysize(mapping_name)) < 0) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 4001 | env->ThrowErrnoException(errno, "sprintf"); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4002 | goto out; |
| 4003 | } |
| 4004 | |
Bert Belder | 8f2694b | 2012-02-16 21:19:48 | [diff] [blame] | 4005 | mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4006 | if (mapping == nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 4007 | isolate->ThrowException(WinapiErrnoException(isolate, |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 4008 | GetLastError(), |
| 4009 | "OpenFileMappingW")); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4010 | goto out; |
| 4011 | } |
| 4012 | |
Bert Belder | 8f2694b | 2012-02-16 21:19:48 | [diff] [blame] | 4013 | handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>( |
| 4014 | MapViewOfFile(mapping, |
| 4015 | FILE_MAP_READ, |
| 4016 | 0, |
| 4017 | 0, |
| 4018 | sizeof *handler)); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4019 | if (handler == nullptr || *handler == nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 4020 | isolate->ThrowException( |
| 4021 | WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile")); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4022 | goto out; |
| 4023 | } |
| 4024 | |
Bert Belder | 68db206 | 2012-02-03 14:37:46 | [diff] [blame] | 4025 | thread = CreateRemoteThread(process, |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4026 | nullptr, |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4027 | 0, |
| 4028 | *handler, |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4029 | nullptr, |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4030 | 0, |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4031 | nullptr); |
| 4032 | if (thread == nullptr) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 4033 | isolate->ThrowException(WinapiErrnoException(isolate, |
| 4034 | GetLastError(), |
| 4035 | "CreateRemoteThread")); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4036 | goto out; |
| 4037 | } |
| 4038 | |
| 4039 | // Wait for the thread to terminate |
| 4040 | if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) { |
Alexis Campailla | 440b9e2 | 2014-02-24 18:55:27 | [diff] [blame] | 4041 | isolate->ThrowException(WinapiErrnoException(isolate, |
| 4042 | GetLastError(), |
| 4043 | "WaitForSingleObject")); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4044 | goto out; |
| 4045 | } |
| 4046 | |
| 4047 | out: |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4048 | if (process != nullptr) |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 4049 | CloseHandle(process); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4050 | if (thread != nullptr) |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4051 | CloseHandle(thread); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4052 | if (handler != nullptr) |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4053 | UnmapViewOfFile(handler); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4054 | if (mapping != nullptr) |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4055 | CloseHandle(mapping); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4056 | } |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 4057 | #endif // _WIN32 |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 4058 | |
| 4059 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 4060 | static void DebugPause(const FunctionCallbackInfo<Value>& args) { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 4061 | v8::Debug::DebugBreak(args.GetIsolate()); |
Fedor Indutny | b0388cc | 2011-12-10 16:52:07 | [diff] [blame] | 4062 | } |
| 4063 | |
| 4064 | |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 4065 | static void DebugEnd(const FunctionCallbackInfo<Value>& args) { |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 4066 | if (debugger_running) { |
Ben Noordhuis | d3c317e | 2014-10-13 13:19:55 | [diff] [blame] | 4067 | Environment* env = Environment::GetCurrent(args); |
Pavel Feldman | 84ad31f | 2016-02-07 16:47:14 | [diff] [blame] | 4068 | #if HAVE_INSPECTOR |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 4069 | if (!debug_options.debugger_enabled()) { |
Pavel Feldman | 84ad31f | 2016-02-07 16:47:14 | [diff] [blame] | 4070 | env->inspector_agent()->Stop(); |
| 4071 | } else { |
| 4072 | #endif |
| 4073 | env->debugger_agent()->Stop(); |
| 4074 | #if HAVE_INSPECTOR |
| 4075 | } |
| 4076 | #endif |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 4077 | debugger_running = false; |
| 4078 | } |
Fedor Indutny | 3f43b1c | 2012-02-12 15:53:43 | [diff] [blame] | 4079 | } |
| 4080 | |
| 4081 | |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 4082 | inline void PlatformInit() { |
| 4083 | #ifdef __POSIX__ |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 4084 | #if HAVE_INSPECTOR |
Ben Noordhuis | 63ae1d2 | 2015-01-26 22:26:33 | [diff] [blame] | 4085 | sigset_t sigmask; |
| 4086 | sigemptyset(&sigmask); |
| 4087 | sigaddset(&sigmask, SIGUSR1); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 4088 | const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr); |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 4089 | #endif // HAVE_INSPECTOR |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 4090 | |
| 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 Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 4099 | ABORT(); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 4100 | if (fd != open("/dev/null", O_RDWR)) |
Evan Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 4101 | ABORT(); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 4102 | } |
| 4103 | |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 4104 | #if HAVE_INSPECTOR |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 4105 | CHECK_EQ(err, 0); |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 4106 | #endif // HAVE_INSPECTOR |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 4107 | |
Stewart X Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 4108 | #ifndef NODE_SHARED_MODE |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 4109 | // 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 Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 4116 | for (unsigned nr = 1; nr < kMaxSignal; nr += 1) { |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 4117 | 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 Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 4122 | #endif // !NODE_SHARED_MODE |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 4123 | |
Ben Noordhuis | 63ae1d2 | 2015-01-26 22:26:33 | [diff] [blame] | 4124 | RegisterSignalHandler(SIGINT, SignalExit, true); |
| 4125 | RegisterSignalHandler(SIGTERM, SignalExit, true); |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 4126 | |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 4127 | // 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 Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 4147 | #endif // __POSIX__ |
Bartosz Sosnowski | bd496e0 | 2017-03-14 17:22:53 | [diff] [blame] | 4148 | #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 Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 4161 | } |
| 4162 | |
| 4163 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4164 | void Init(int* argc, |
| 4165 | const char** argv, |
| 4166 | int* exec_argc, |
| 4167 | const char*** exec_argv) { |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 4168 | // Initialize prog_start_time to get relative uptime. |
Rasmus Christian Pedersen | 734fb49 | 2014-09-18 12:10:53 | [diff] [blame] | 4169 | prog_start_time = static_cast<double>(uv_now(uv_default_loop())); |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 4170 | |
Bert Belder | 09be360 | 2012-06-13 23:28:51 | [diff] [blame] | 4171 | // Make inherited handles noninheritable. |
| 4172 | uv_disable_stdio_inheritance(); |
| 4173 | |
Miroslav Bajtoš | fbf4641 | 2013-05-02 14:42:49 | [diff] [blame] | 4174 | // init async debug messages dispatching |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4175 | // Main thread uses uv_default_loop |
Ben Noordhuis | 5e60ded | 2016-06-22 11:03:46 | [diff] [blame] | 4176 | CHECK_EQ(0, uv_async_init(uv_default_loop(), |
| 4177 | &dispatch_debug_messages_async, |
| 4178 | DispatchDebugMessagesAsyncCallback)); |
Ben Noordhuis | 9b02442 | 2015-10-29 12:33:03 | [diff] [blame] | 4179 | uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async)); |
Miroslav Bajtoš | fbf4641 | 2013-05-02 14:42:49 | [diff] [blame] | 4180 | |
Steven R. Loomis | 1a55e9a | 2016-11-03 21:36:19 | [diff] [blame] | 4181 | #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 Noordhuis | 490d5ab | 2014-03-31 12:22:49 | [diff] [blame] | 4189 | #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 Indutny | b55c9d6 | 2014-03-26 20:30:49 | [diff] [blame] | 4195 | |
James M Snell | a16b570 | 2017-03-11 20:18:53 | [diff] [blame^] | 4196 | { |
| 4197 | std::string text; |
| 4198 | config_pending_deprecation = |
| 4199 | SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1'; |
| 4200 | } |
| 4201 | |
Marc Udoff | d3b1a2b | 2016-09-20 22:21:44 | [diff] [blame] | 4202 | // Allow for environment set preserving symlinks. |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4203 | { |
| 4204 | std::string text; |
| 4205 | config_preserve_symlinks = |
| 4206 | SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1'; |
Marc Udoff | d3b1a2b | 2016-09-20 22:21:44 | [diff] [blame] | 4207 | } |
| 4208 | |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4209 | if (config_warning_file.empty()) |
| 4210 | SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file); |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 4211 | |
Daniel Bevenius | e1d8899 | 2017-02-28 19:04:12 | [diff] [blame] | 4212 | #if HAVE_OPENSSL |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 4213 | if (openssl_config.empty()) |
| 4214 | SafeGetenv("OPENSSL_CONF", &openssl_config); |
Daniel Bevenius | e1d8899 | 2017-02-28 19:04:12 | [diff] [blame] | 4215 | #endif |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 4216 | |
Ryan Dahl | 3881455 | 2009-10-09 15:15:47 | [diff] [blame] | 4217 | // Parse a few arguments which are specific to Node. |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4218 | int v8_argc; |
| 4219 | const char** v8_argv; |
Evan Lucas | 5b6f575 | 2015-06-01 14:15:10 | [diff] [blame] | 4220 | ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv); |
| 4221 | |
Ben Noordhuis | 9566fe8 | 2013-10-03 08:45:32 | [diff] [blame] | 4222 | // 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 Chekhovskyi | 8e14135 | 2015-08-07 13:03:04 | [diff] [blame] | 4233 | #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. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 4242 | #if defined(NODE_HAVE_I18N_SUPPORT) |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4243 | // 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. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 4246 | // Initialize ICU. |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4247 | // If icu_data_dir is empty here, it will load the 'minimal' data. |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 4248 | if (!i18n::InitializeICUDirectory(icu_data_dir)) { |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4249 | FatalError(nullptr, "Could not initialize ICU " |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 4250 | "(check NODE_ICU_DATA or --icu-data-dir parameters)"); |
| 4251 | } |
| 4252 | #endif |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4253 | // The const_cast doesn't violate conceptual const-ness. V8 doesn't modify |
| 4254 | // the argv array or the elements it points to. |
Evan Lucas | 45fb340 | 2015-09-02 07:59:21 | [diff] [blame] | 4255 | if (v8_argc > 1) |
Evan Lucas | 1c20b87 | 2015-08-21 09:15:55 | [diff] [blame] | 4256 | V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true); |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4257 | |
| 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 Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4263 | v8_argv = nullptr; |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4264 | |
| 4265 | if (v8_argc > 1) { |
isaacs | b30a03e | 2013-09-07 00:47:56 | [diff] [blame] | 4266 | exit(9); |
Ryan Dahl | adec544 | 2010-08-04 17:38:19 | [diff] [blame] | 4267 | } |
Tom Hughes | 78da9cb | 2010-10-18 22:50:56 | [diff] [blame] | 4268 | |
Trevor Norris | 16f86d6 | 2015-09-16 04:14:18 | [diff] [blame] | 4269 | // 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 Zhao | 22e1aea | 2015-01-12 21:31:25 | [diff] [blame] | 4275 | // 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 Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 4279 | } |
Ben Noordhuis | 356992f | 2011-11-22 16:10:09 | [diff] [blame] | 4280 | |
Ben Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 4281 | |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4282 | void RunAtExit(Environment* env) { |
Daniel Bevenius | ec53921 | 2017-03-21 07:06:43 | [diff] [blame] | 4283 | env->RunAtExitCallbacks(); |
Ben Noordhuis | e4a8d26 | 2012-04-21 05:13:25 | [diff] [blame] | 4284 | } |
| 4285 | |
| 4286 | |
Daniel Bevenius | ec53921 | 2017-03-21 07:06:43 | [diff] [blame] | 4287 | static uv_key_t thread_local_env; |
| 4288 | |
| 4289 | |
Ben Noordhuis | e4a8d26 | 2012-04-21 05:13:25 | [diff] [blame] | 4290 | void AtExit(void (*cb)(void* arg), void* arg) { |
Daniel Bevenius | ec53921 | 2017-03-21 07:06:43 | [diff] [blame] | 4291 | auto env = static_cast<Environment*>(uv_key_get(&thread_local_env)); |
| 4292 | AtExit(env, cb, arg); |
| 4293 | } |
| 4294 | |
| 4295 | |
| 4296 | void AtExit(Environment* env, void (*cb)(void* arg), void* arg) { |
| 4297 | CHECK_NE(env, nullptr); |
| 4298 | env->AtExit(cb, arg); |
Ben Noordhuis | e4a8d26 | 2012-04-21 05:13:25 | [diff] [blame] | 4299 | } |
| 4300 | |
| 4301 | |
Ben Noordhuis | a2eeb43 | 2013-10-07 13:39:39 | [diff] [blame] | 4302 | void EmitBeforeExit(Environment* env) { |
Ben Noordhuis | a2eeb43 | 2013-10-07 13:39:39 | [diff] [blame] | 4303 | HandleScope handle_scope(env->isolate()); |
Fedor Indutny | e2c9040 | 2015-03-12 21:19:16 | [diff] [blame] | 4304 | Context::Scope context_scope(env->context()); |
Ben Noordhuis | a2eeb43 | 2013-10-07 13:39:39 | [diff] [blame] | 4305 | 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 Norris | d553386 | 2015-01-07 21:29:58 | [diff] [blame] | 4309 | process_object->Get(exit_code)->ToInteger(env->isolate()) |
Ben Noordhuis | a2eeb43 | 2013-10-07 13:39:39 | [diff] [blame] | 4310 | }; |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 4311 | MakeCallback(env, process_object, "emit", arraysize(args), args); |
Ben Noordhuis | a2eeb43 | 2013-10-07 13:39:39 | [diff] [blame] | 4312 | } |
| 4313 | |
| 4314 | |
Fedor Indutny | e57ab7b | 2014-01-18 22:49:33 | [diff] [blame] | 4315 | int EmitExit(Environment* env) { |
Ben Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 4316 | // process.emit('exit') |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4317 | HandleScope handle_scope(env->isolate()); |
Ben Noordhuis | 27f115d | 2013-11-11 09:53:00 | [diff] [blame] | 4318 | Context::Scope context_scope(env->context()); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4319 | Local<Object> process_object = env->process_object(); |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 4320 | process_object->Set(env->exiting_string(), True(env->isolate())); |
isaacs | a5dba82 | 2013-09-06 23:46:35 | [diff] [blame] | 4321 | |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 4322 | Local<String> exitCode = env->exit_code_string(); |
Rasmus Christian Pedersen | 734fb49 | 2014-09-18 12:10:53 | [diff] [blame] | 4323 | int code = process_object->Get(exitCode)->Int32Value(); |
isaacs | a5dba82 | 2013-09-06 23:46:35 | [diff] [blame] | 4324 | |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 4325 | Local<Value> args[] = { |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 4326 | env->exit_string(), |
Fedor Indutny | ce04c72 | 2014-03-13 16:38:14 | [diff] [blame] | 4327 | Integer::New(env->isolate(), code) |
Ben Noordhuis | f674b09 | 2013-08-07 19:50:41 | [diff] [blame] | 4328 | }; |
isaacs | a5dba82 | 2013-09-06 23:46:35 | [diff] [blame] | 4329 | |
Ben Noordhuis | a7581d0 | 2016-03-31 10:47:06 | [diff] [blame] | 4330 | MakeCallback(env, process_object, "emit", arraysize(args), args); |
Fedor Indutny | c0d81f9 | 2014-02-09 10:40:57 | [diff] [blame] | 4331 | |
| 4332 | // Reload exit code, it may be changed by `emit('exit')` |
Rasmus Christian Pedersen | 734fb49 | 2014-09-18 12:10:53 | [diff] [blame] | 4333 | return process_object->Get(exitCode)->Int32Value(); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4334 | } |
| 4335 | |
| 4336 | |
Ben Noordhuis | c3cd453 | 2016-05-31 14:42:52 | [diff] [blame] | 4337 | IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) { |
| 4338 | return new IsolateData(isolate, loop); |
| 4339 | } |
| 4340 | |
| 4341 | |
| 4342 | void FreeIsolateData(IsolateData* isolate_data) { |
| 4343 | delete isolate_data; |
| 4344 | } |
| 4345 | |
| 4346 | |
| 4347 | Environment* CreateEnvironment(IsolateData* isolate_data, |
Michaël Zasso | 4abc896 | 2015-07-18 09:34:16 | [diff] [blame] | 4348 | Local<Context> context, |
Fedor Indutny | 6a610a0 | 2014-10-04 14:44:39 | [diff] [blame] | 4349 | int argc, |
| 4350 | const char* const* argv, |
| 4351 | int exec_argc, |
| 4352 | const char* const* exec_argv) { |
Ben Noordhuis | c3cd453 | 2016-05-31 14:42:52 | [diff] [blame] | 4353 | Isolate* isolate = context->GetIsolate(); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4354 | HandleScope handle_scope(isolate); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4355 | Context::Scope context_scope(context); |
Ben Noordhuis | aac79df | 2016-06-01 09:18:02 | [diff] [blame] | 4356 | auto env = new Environment(isolate_data, context); |
Ben Noordhuis | 58cec4e | 2016-06-01 08:54:42 | [diff] [blame] | 4357 | env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling); |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 4358 | return env; |
Ben Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 4359 | } |
| 4360 | |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 4361 | |
Ben Noordhuis | aac79df | 2016-06-01 09:18:02 | [diff] [blame] | 4362 | void FreeEnvironment(Environment* env) { |
| 4363 | delete env; |
| 4364 | } |
| 4365 | |
| 4366 | |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4367 | inline 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 Bevenius | ec53921 | 2017-03-21 07:06:43 | [diff] [blame] | 4374 | CHECK_EQ(0, uv_key_create(&thread_local_env)); |
| 4375 | uv_key_set(&thread_local_env, &env); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4376 | env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling); |
| 4377 | |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 4378 | const char* path = argc > 1 ? argv[1] : nullptr; |
| 4379 | StartDebug(&env, path, debug_options); |
Eugene Ostroukhov | f9aadfb | 2016-11-18 21:52:22 | [diff] [blame] | 4380 | |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 4381 | 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 Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4385 | |
| 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 Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 4394 | if (debug_options.debugger_enabled()) |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4395 | EnableDebug(&env); |
| 4396 | |
Jason Ginchereau | 56e881d | 2017-03-20 21:55:26 | [diff] [blame] | 4397 | if (load_napi_modules) { |
| 4398 | ProcessEmitWarning(&env, "N-API is an experimental feature " |
| 4399 | "and could change at any time."); |
| 4400 | } |
| 4401 | |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4402 | { |
| 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 Bevenius | ec53921 | 2017-03-21 07:06:43 | [diff] [blame] | 4426 | uv_key_delete(&thread_local_env); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4427 | |
| 4428 | WaitForInspectorDisconnect(&env); |
| 4429 | #if defined(LEAK_SANITIZER) |
| 4430 | __lsan_do_leak_check(); |
| 4431 | #endif |
| 4432 | |
| 4433 | return exit_code; |
| 4434 | } |
| 4435 | |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 4436 | inline int Start(uv_loop_t* event_loop, |
| 4437 | int argc, const char* const* argv, |
| 4438 | int exec_argc, const char* const* exec_argv) { |
Ben Noordhuis | 9a03ae6 | 2015-07-01 21:47:37 | [diff] [blame] | 4439 | Isolate::CreateParams params; |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4440 | ArrayBufferAllocator allocator; |
| 4441 | params.array_buffer_allocator = &allocator; |
Chunyang Dai | a881b53 | 2015-10-21 16:24:12 | [diff] [blame] | 4442 | #ifdef NODE_ENABLE_VTUNE_PROFILING |
| 4443 | params.code_event_handler = vTune::GetVtuneCodeEventHandler(); |
| 4444 | #endif |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4445 | |
| 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 Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 4458 | |
Ben Noordhuis | d7087df | 2016-06-17 23:39:05 | [diff] [blame] | 4459 | { |
| 4460 | Mutex::ScopedLock scoped_lock(node_isolate_mutex); |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 4461 | CHECK_EQ(node_isolate, nullptr); |
| 4462 | node_isolate = isolate; |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 4463 | } |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 4464 | |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 4465 | int exit_code; |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4466 | { |
| 4467 | Locker locker(isolate); |
| 4468 | Isolate::Scope isolate_scope(isolate); |
| 4469 | HandleScope handle_scope(isolate); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4470 | IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field()); |
| 4471 | exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv); |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4472 | } |
| 4473 | |
Ben Noordhuis | d7087df | 2016-06-17 23:39:05 | [diff] [blame] | 4474 | { |
| 4475 | Mutex::ScopedLock scoped_lock(node_isolate_mutex); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4476 | CHECK_EQ(node_isolate, isolate); |
| 4477 | node_isolate = nullptr; |
Ben Noordhuis | d7087df | 2016-06-17 23:39:05 | [diff] [blame] | 4478 | } |
Ben Noordhuis | 53e64bb | 2015-10-26 13:11:03 | [diff] [blame] | 4479 | |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4480 | isolate->Dispose(); |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 4481 | |
| 4482 | return exit_code; |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4483 | } |
| 4484 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4485 | int Start(int argc, char** argv) { |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 4486 | atexit([] () { uv_tty_reset_mode(); }); |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 4487 | PlatformInit(); |
| 4488 | |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 4489 | CHECK_GT(argc, 0); |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 4490 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4491 | // Hack around with the argv pointer. Used for process.title = "blah". |
Ben Noordhuis | 1a97998 | 2012-03-15 22:10:32 | [diff] [blame] | 4492 | argv = uv_setup_args(argc, argv); |
| 4493 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4494 | // 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 Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 4499 | |
Ben Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 4500 | #if HAVE_OPENSSL |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4501 | { |
| 4502 | std::string extra_ca_certs; |
| 4503 | if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs)) |
| 4504 | crypto::UseExtraCaCerts(extra_ca_certs); |
| 4505 | } |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 4506 | #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 Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 4511 | // V8 on Windows doesn't have a good source of entropy. Seed it from |
| 4512 | // OpenSSL's pool. |
| 4513 | V8::SetEntropySource(crypto::EntropySource); |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 4514 | #endif // HAVE_OPENSSL |
Ben Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 4515 | |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 4516 | v8_platform.Initialize(v8_thread_pool_size); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 4517 | // 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 Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 4521 | v8_platform.StartTracingAgent(); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 4522 | } |
Ben Noordhuis | 75ea566 | 2013-09-23 12:27:26 | [diff] [blame] | 4523 | V8::Initialize(); |
Anna Henningsen | 72c60e8 | 2016-09-10 16:21:20 | [diff] [blame] | 4524 | v8_initialized = true; |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 4525 | const int exit_code = |
| 4526 | Start(uv_default_loop(), argc, argv, exec_argc, exec_argv); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 4527 | if (trace_enabled) { |
Myk Melez | 046f66a | 2017-01-31 17:56:09 | [diff] [blame] | 4528 | v8_platform.StopTracingAgent(); |
misterpoe | ba4847e | 2016-08-05 21:04:25 | [diff] [blame] | 4529 | } |
Anna Henningsen | 72c60e8 | 2016-09-10 16:21:20 | [diff] [blame] | 4530 | v8_initialized = false; |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 4531 | V8::Dispose(); |
Igor Zinkovsky | a58b643 | 2011-07-07 20:54:30 | [diff] [blame] | 4532 | |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 4533 | v8_platform.Dispose(); |
Ben Noordhuis | 4a801c2 | 2015-04-02 21:51:01 | [diff] [blame] | 4534 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 4535 | delete[] exec_argv; |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 4536 | exec_argv = nullptr; |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 4537 | |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 4538 | return exit_code; |
Ryan | 19478ed | 2009-03-03 00:56:15 | [diff] [blame] | 4539 | } |
Ryan Dahl | 124fbed | 2010-09-19 20:13:57 | [diff] [blame] | 4540 | |
| 4541 | |
| 4542 | } // namespace node |