Run Tizen Webapps in single process mode
[platform/framework/web/crosswalk-tizen.git] / vendor / node / src / node.cc
1 #include "node.h"
2 #include "node_buffer.h"
3 #include "node_constants.h"
4 #include "node_file.h"
5 #include "node_http_parser.h"
6 #include "node_javascript.h"
7 #include "node_version.h"
8 #include "node_internals.h"
9 #include "node_revert.h"
10
11 #if defined HAVE_PERFCTR
12 #include "node_counters.h"
13 #endif
14
15 #if HAVE_OPENSSL
16 #include "node_crypto.h"
17 #endif
18
19 #if defined(NODE_HAVE_I18N_SUPPORT)
20 #include "node_i18n.h"
21 #endif
22
23 #if defined HAVE_DTRACE || defined HAVE_ETW
24 #include "node_dtrace.h"
25 #endif
26
27 #if defined HAVE_LTTNG
28 #include "node_lttng.h"
29 #endif
30
31 #include "ares.h"
32 #include "async-wrap.h"
33 #include "async-wrap-inl.h"
34 #include "env.h"
35 #include "env-inl.h"
36 #include "handle_wrap.h"
37 #include "req-wrap.h"
38 #include "req-wrap-inl.h"
39 #include "string_bytes.h"
40 #include "util.h"
41 #include "uv.h"
42 #if NODE_USE_V8_PLATFORM
43 #include "libplatform/libplatform.h"
44 #endif  // NODE_USE_V8_PLATFORM
45 #include "v8-debug.h"
46 #include "v8-profiler.h"
47 #include "zlib.h"
48
49 #ifdef NODE_ENABLE_VTUNE_PROFILING
50 #include "../deps/v8/src/third_party/vtune/v8-vtune.h"
51 #endif
52
53 #include <errno.h>
54 #include <limits.h>  // PATH_MAX
55 #include <locale.h>
56 #include <signal.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <sys/types.h>
61
62 #include <string>
63 #include <vector>
64
65 #if defined(NODE_HAVE_I18N_SUPPORT)
66 #include <unicode/uvernum.h>
67 #endif
68
69 #if defined(LEAK_SANITIZER)
70 #include <sanitizer/lsan_interface.h>
71 #endif
72
73 #if defined(_MSC_VER)
74 #include <direct.h>
75 #include <io.h>
76 #define getpid GetCurrentProcessId
77 #define umask _umask
78 typedef int mode_t;
79 #else
80 #include <pthread.h>
81 #include <sys/resource.h>  // getrlimit, setrlimit
82 #include <unistd.h>  // setuid, getuid
83 #endif
84
85 #if defined(__POSIX__) && !defined(__ANDROID__)
86 #include <pwd.h>  // getpwnam()
87 #include <grp.h>  // getgrnam()
88 #endif
89
90 #ifdef __APPLE__
91 #include <crt_externs.h>
92 #define environ (*_NSGetEnviron())
93 #elif !defined(_MSC_VER)
94 extern char **environ;
95 #endif
96
97 #if defined(OS_TIZEN)
98 #include <dlog/dlog.h>
99 #endif
100
101 namespace node {
102
103 using v8::Array;
104 using v8::ArrayBuffer;
105 using v8::Boolean;
106 using v8::Context;
107 using v8::EscapableHandleScope;
108 using v8::Exception;
109 using v8::Float64Array;
110 using v8::Function;
111 using v8::FunctionCallbackInfo;
112 using v8::HandleScope;
113 using v8::HeapStatistics;
114 using v8::Integer;
115 using v8::Isolate;
116 using v8::Local;
117 using v8::Locker;
118 using v8::MaybeLocal;
119 using v8::Message;
120 using v8::Name;
121 using v8::NamedPropertyHandlerConfiguration;
122 using v8::Null;
123 using v8::Number;
124 using v8::Object;
125 using v8::ObjectTemplate;
126 using v8::Promise;
127 using v8::PromiseRejectMessage;
128 using v8::PropertyCallbackInfo;
129 using v8::PropertyHandlerFlags;
130 using v8::ScriptOrigin;
131 using v8::SealHandleScope;
132 using v8::String;
133 using v8::TryCatch;
134 using v8::Uint32Array;
135 using v8::V8;
136 using v8::Value;
137
138 bool g_standalone_mode = true;
139 bool g_upstream_node_mode = true;
140
141 static bool print_eval = false;
142 static bool force_repl = false;
143 static bool syntax_check_only = false;
144 static bool trace_deprecation = false;
145 static bool throw_deprecation = false;
146 static bool trace_sync_io = false;
147 static bool track_heap_objects = false;
148 static const char* eval_string = nullptr;
149 static unsigned int preload_module_count = 0;
150 static const char** preload_modules = nullptr;
151 #if HAVE_INSPECTOR
152 static bool use_inspector = false;
153 #else
154 static const bool use_inspector = false;
155 #endif
156 static bool use_debug_agent = false;
157 static bool debug_wait_connect = false;
158 static std::string* debug_host;  // coverity[leaked_storage]
159 static const int default_debugger_port = 5858;
160 static const int default_inspector_port = 9229;
161 static int debug_port = -1;
162 static const int v8_default_thread_pool_size = 4;
163 static int v8_thread_pool_size = v8_default_thread_pool_size;
164 static bool prof_process = false;
165 static bool v8_is_profiling = false;
166 static bool node_is_initialized = false;
167 static node_module* modpending;
168 static node_module* modlist_builtin;
169 static node_module* modlist_linked;
170 static node_module* modlist_addon;
171
172 #if defined(NODE_HAVE_I18N_SUPPORT)
173 // Path to ICU data (for i18n / Intl)
174 static const char* icu_data_dir = nullptr;
175 #endif
176
177 // used by C++ modules as well
178 bool no_deprecation = false;
179
180 #if HAVE_OPENSSL
181 # if NODE_FIPS_MODE
182 // used by crypto module
183 bool enable_fips_crypto = false;
184 bool force_fips_crypto = false;
185 # endif  // NODE_FIPS_MODE
186 const char* openssl_config = nullptr;
187 #endif  // HAVE_OPENSSL
188
189 // true if process warnings should be suppressed
190 bool no_process_warnings = false;
191 bool trace_warnings = false;
192
193 // Set in node.cc by ParseArgs when --preserve-symlinks is used.
194 // Used in node_config.cc to set a constant on process.binding('config')
195 // that is used by lib/module.js
196 bool config_preserve_symlinks = false;
197
198 bool v8_initialized = false;
199
200 // process-relative uptime base, initialized at start-up
201 static double prog_start_time;
202 static bool debugger_running;
203 static uv_async_t dispatch_debug_messages_async;
204
205 static Mutex node_isolate_mutex;
206 static v8::Isolate* node_isolate;
207
208 static struct {
209 #if NODE_USE_V8_PLATFORM
210   void Initialize(int thread_pool_size) {
211     platform_ = v8::platform::CreateDefaultPlatform(thread_pool_size);
212     V8::InitializePlatform(platform_);
213   }
214
215   void PumpMessageLoop(Isolate* isolate) {
216     v8::platform::PumpMessageLoop(platform_, isolate);
217   }
218
219   void Dispose() {
220     delete platform_;
221     platform_ = nullptr;
222   }
223
224   bool StartInspector(Environment *env, const char* script_path,
225                       int port, bool wait) {
226 #if HAVE_INSPECTOR
227     return env->inspector_agent()->Start(platform_, script_path, port, wait);
228 #else
229     return true;
230 #endif  // HAVE_INSPECTOR
231   }
232
233   v8::Platform* platform_;
234 #else  // !NODE_USE_V8_PLATFORM
235   void Initialize(int thread_pool_size) {}
236   void PumpMessageLoop(Isolate* isolate) {}
237   void Dispose() {}
238   bool StartInspector(Environment *env, const char* script_path,
239                       int port, bool wait) {
240     env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
241     return false;  // make compiler happy
242   }
243 #endif  // !NODE_USE_V8_PLATFORM
244 } v8_platform;
245
246 #ifdef __POSIX__
247 static uv_sem_t debug_semaphore;
248 static const unsigned kMaxSignal = 32;
249 #endif
250
251 static void PrintErrorString(const char* format, ...) {
252   va_list ap;
253   va_start(ap, format);
254 #ifdef _WIN32
255   HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
256
257   // Check if stderr is something other than a tty/console
258   if (stderr_handle == INVALID_HANDLE_VALUE ||
259       stderr_handle == nullptr ||
260       uv_guess_handle(_fileno(stderr)) != UV_TTY) {
261     vfprintf(stderr, format, ap);
262     va_end(ap);
263     return;
264   }
265
266   // Fill in any placeholders
267   int n = _vscprintf(format, ap);
268   std::vector<char> out(n + 1);
269   vsprintf(out.data(), format, ap);
270
271   // Get required wide buffer size
272   n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
273
274   std::vector<wchar_t> wbuf(n);
275   MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
276
277   // Don't include the null character in the output
278   CHECK_GT(n, 0);
279   WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
280 #elif defined(OS_TIZEN)
281   dlog_print(DLOG_ERROR, "WRT", "[Node.js ERROR]");
282   dlog_vprint(DLOG_ERROR, "WRT", format, ap);
283 #else
284   vfprintf(stderr, format, ap);
285 #endif
286   va_end(ap);
287 }
288
289
290 static void CheckImmediate(uv_check_t* handle) {
291   Environment* env = Environment::from_immediate_check_handle(handle);
292   HandleScope scope(env->isolate());
293   Context::Scope context_scope(env->context());
294   MakeCallback(env, env->process_object(), env->immediate_callback_string());
295 }
296
297
298 static void IdleImmediateDummy(uv_idle_t* handle) {
299   // Do nothing. Only for maintaining event loop.
300   // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
301 }
302
303
304 static inline const char *errno_string(int errorno) {
305 #define ERRNO_CASE(e)  case e: return #e;
306   switch (errorno) {
307 #ifdef EACCES
308   ERRNO_CASE(EACCES);
309 #endif
310
311 #ifdef EADDRINUSE
312   ERRNO_CASE(EADDRINUSE);
313 #endif
314
315 #ifdef EADDRNOTAVAIL
316   ERRNO_CASE(EADDRNOTAVAIL);
317 #endif
318
319 #ifdef EAFNOSUPPORT
320   ERRNO_CASE(EAFNOSUPPORT);
321 #endif
322
323 #ifdef EAGAIN
324   ERRNO_CASE(EAGAIN);
325 #endif
326
327 #ifdef EWOULDBLOCK
328 # if EAGAIN != EWOULDBLOCK
329   ERRNO_CASE(EWOULDBLOCK);
330 # endif
331 #endif
332
333 #ifdef EALREADY
334   ERRNO_CASE(EALREADY);
335 #endif
336
337 #ifdef EBADF
338   ERRNO_CASE(EBADF);
339 #endif
340
341 #ifdef EBADMSG
342   ERRNO_CASE(EBADMSG);
343 #endif
344
345 #ifdef EBUSY
346   ERRNO_CASE(EBUSY);
347 #endif
348
349 #ifdef ECANCELED
350   ERRNO_CASE(ECANCELED);
351 #endif
352
353 #ifdef ECHILD
354   ERRNO_CASE(ECHILD);
355 #endif
356
357 #ifdef ECONNABORTED
358   ERRNO_CASE(ECONNABORTED);
359 #endif
360
361 #ifdef ECONNREFUSED
362   ERRNO_CASE(ECONNREFUSED);
363 #endif
364
365 #ifdef ECONNRESET
366   ERRNO_CASE(ECONNRESET);
367 #endif
368
369 #ifdef EDEADLK
370   ERRNO_CASE(EDEADLK);
371 #endif
372
373 #ifdef EDESTADDRREQ
374   ERRNO_CASE(EDESTADDRREQ);
375 #endif
376
377 #ifdef EDOM
378   ERRNO_CASE(EDOM);
379 #endif
380
381 #ifdef EDQUOT
382   ERRNO_CASE(EDQUOT);
383 #endif
384
385 #ifdef EEXIST
386   ERRNO_CASE(EEXIST);
387 #endif
388
389 #ifdef EFAULT
390   ERRNO_CASE(EFAULT);
391 #endif
392
393 #ifdef EFBIG
394   ERRNO_CASE(EFBIG);
395 #endif
396
397 #ifdef EHOSTUNREACH
398   ERRNO_CASE(EHOSTUNREACH);
399 #endif
400
401 #ifdef EIDRM
402   ERRNO_CASE(EIDRM);
403 #endif
404
405 #ifdef EILSEQ
406   ERRNO_CASE(EILSEQ);
407 #endif
408
409 #ifdef EINPROGRESS
410   ERRNO_CASE(EINPROGRESS);
411 #endif
412
413 #ifdef EINTR
414   ERRNO_CASE(EINTR);
415 #endif
416
417 #ifdef EINVAL
418   ERRNO_CASE(EINVAL);
419 #endif
420
421 #ifdef EIO
422   ERRNO_CASE(EIO);
423 #endif
424
425 #ifdef EISCONN
426   ERRNO_CASE(EISCONN);
427 #endif
428
429 #ifdef EISDIR
430   ERRNO_CASE(EISDIR);
431 #endif
432
433 #ifdef ELOOP
434   ERRNO_CASE(ELOOP);
435 #endif
436
437 #ifdef EMFILE
438   ERRNO_CASE(EMFILE);
439 #endif
440
441 #ifdef EMLINK
442   ERRNO_CASE(EMLINK);
443 #endif
444
445 #ifdef EMSGSIZE
446   ERRNO_CASE(EMSGSIZE);
447 #endif
448
449 #ifdef EMULTIHOP
450   ERRNO_CASE(EMULTIHOP);
451 #endif
452
453 #ifdef ENAMETOOLONG
454   ERRNO_CASE(ENAMETOOLONG);
455 #endif
456
457 #ifdef ENETDOWN
458   ERRNO_CASE(ENETDOWN);
459 #endif
460
461 #ifdef ENETRESET
462   ERRNO_CASE(ENETRESET);
463 #endif
464
465 #ifdef ENETUNREACH
466   ERRNO_CASE(ENETUNREACH);
467 #endif
468
469 #ifdef ENFILE
470   ERRNO_CASE(ENFILE);
471 #endif
472
473 #ifdef ENOBUFS
474   ERRNO_CASE(ENOBUFS);
475 #endif
476
477 #ifdef ENODATA
478   ERRNO_CASE(ENODATA);
479 #endif
480
481 #ifdef ENODEV
482   ERRNO_CASE(ENODEV);
483 #endif
484
485 #ifdef ENOENT
486   ERRNO_CASE(ENOENT);
487 #endif
488
489 #ifdef ENOEXEC
490   ERRNO_CASE(ENOEXEC);
491 #endif
492
493 #ifdef ENOLINK
494   ERRNO_CASE(ENOLINK);
495 #endif
496
497 #ifdef ENOLCK
498 # if ENOLINK != ENOLCK
499   ERRNO_CASE(ENOLCK);
500 # endif
501 #endif
502
503 #ifdef ENOMEM
504   ERRNO_CASE(ENOMEM);
505 #endif
506
507 #ifdef ENOMSG
508   ERRNO_CASE(ENOMSG);
509 #endif
510
511 #ifdef ENOPROTOOPT
512   ERRNO_CASE(ENOPROTOOPT);
513 #endif
514
515 #ifdef ENOSPC
516   ERRNO_CASE(ENOSPC);
517 #endif
518
519 #ifdef ENOSR
520   ERRNO_CASE(ENOSR);
521 #endif
522
523 #ifdef ENOSTR
524   ERRNO_CASE(ENOSTR);
525 #endif
526
527 #ifdef ENOSYS
528   ERRNO_CASE(ENOSYS);
529 #endif
530
531 #ifdef ENOTCONN
532   ERRNO_CASE(ENOTCONN);
533 #endif
534
535 #ifdef ENOTDIR
536   ERRNO_CASE(ENOTDIR);
537 #endif
538
539 #ifdef ENOTEMPTY
540 # if ENOTEMPTY != EEXIST
541   ERRNO_CASE(ENOTEMPTY);
542 # endif
543 #endif
544
545 #ifdef ENOTSOCK
546   ERRNO_CASE(ENOTSOCK);
547 #endif
548
549 #ifdef ENOTSUP
550   ERRNO_CASE(ENOTSUP);
551 #else
552 # ifdef EOPNOTSUPP
553   ERRNO_CASE(EOPNOTSUPP);
554 # endif
555 #endif
556
557 #ifdef ENOTTY
558   ERRNO_CASE(ENOTTY);
559 #endif
560
561 #ifdef ENXIO
562   ERRNO_CASE(ENXIO);
563 #endif
564
565
566 #ifdef EOVERFLOW
567   ERRNO_CASE(EOVERFLOW);
568 #endif
569
570 #ifdef EPERM
571   ERRNO_CASE(EPERM);
572 #endif
573
574 #ifdef EPIPE
575   ERRNO_CASE(EPIPE);
576 #endif
577
578 #ifdef EPROTO
579   ERRNO_CASE(EPROTO);
580 #endif
581
582 #ifdef EPROTONOSUPPORT
583   ERRNO_CASE(EPROTONOSUPPORT);
584 #endif
585
586 #ifdef EPROTOTYPE
587   ERRNO_CASE(EPROTOTYPE);
588 #endif
589
590 #ifdef ERANGE
591   ERRNO_CASE(ERANGE);
592 #endif
593
594 #ifdef EROFS
595   ERRNO_CASE(EROFS);
596 #endif
597
598 #ifdef ESPIPE
599   ERRNO_CASE(ESPIPE);
600 #endif
601
602 #ifdef ESRCH
603   ERRNO_CASE(ESRCH);
604 #endif
605
606 #ifdef ESTALE
607   ERRNO_CASE(ESTALE);
608 #endif
609
610 #ifdef ETIME
611   ERRNO_CASE(ETIME);
612 #endif
613
614 #ifdef ETIMEDOUT
615   ERRNO_CASE(ETIMEDOUT);
616 #endif
617
618 #ifdef ETXTBSY
619   ERRNO_CASE(ETXTBSY);
620 #endif
621
622 #ifdef EXDEV
623   ERRNO_CASE(EXDEV);
624 #endif
625
626   default: return "";
627   }
628 }
629
630 const char *signo_string(int signo) {
631 #define SIGNO_CASE(e)  case e: return #e;
632   switch (signo) {
633 #ifdef SIGHUP
634   SIGNO_CASE(SIGHUP);
635 #endif
636
637 #ifdef SIGINT
638   SIGNO_CASE(SIGINT);
639 #endif
640
641 #ifdef SIGQUIT
642   SIGNO_CASE(SIGQUIT);
643 #endif
644
645 #ifdef SIGILL
646   SIGNO_CASE(SIGILL);
647 #endif
648
649 #ifdef SIGTRAP
650   SIGNO_CASE(SIGTRAP);
651 #endif
652
653 #ifdef SIGABRT
654   SIGNO_CASE(SIGABRT);
655 #endif
656
657 #ifdef SIGIOT
658 # if SIGABRT != SIGIOT
659   SIGNO_CASE(SIGIOT);
660 # endif
661 #endif
662
663 #ifdef SIGBUS
664   SIGNO_CASE(SIGBUS);
665 #endif
666
667 #ifdef SIGFPE
668   SIGNO_CASE(SIGFPE);
669 #endif
670
671 #ifdef SIGKILL
672   SIGNO_CASE(SIGKILL);
673 #endif
674
675 #ifdef SIGUSR1
676   SIGNO_CASE(SIGUSR1);
677 #endif
678
679 #ifdef SIGSEGV
680   SIGNO_CASE(SIGSEGV);
681 #endif
682
683 #ifdef SIGUSR2
684   SIGNO_CASE(SIGUSR2);
685 #endif
686
687 #ifdef SIGPIPE
688   SIGNO_CASE(SIGPIPE);
689 #endif
690
691 #ifdef SIGALRM
692   SIGNO_CASE(SIGALRM);
693 #endif
694
695   SIGNO_CASE(SIGTERM);
696
697 #ifdef SIGCHLD
698   SIGNO_CASE(SIGCHLD);
699 #endif
700
701 #ifdef SIGSTKFLT
702   SIGNO_CASE(SIGSTKFLT);
703 #endif
704
705
706 #ifdef SIGCONT
707   SIGNO_CASE(SIGCONT);
708 #endif
709
710 #ifdef SIGSTOP
711   SIGNO_CASE(SIGSTOP);
712 #endif
713
714 #ifdef SIGTSTP
715   SIGNO_CASE(SIGTSTP);
716 #endif
717
718 #ifdef SIGBREAK
719   SIGNO_CASE(SIGBREAK);
720 #endif
721
722 #ifdef SIGTTIN
723   SIGNO_CASE(SIGTTIN);
724 #endif
725
726 #ifdef SIGTTOU
727   SIGNO_CASE(SIGTTOU);
728 #endif
729
730 #ifdef SIGURG
731   SIGNO_CASE(SIGURG);
732 #endif
733
734 #ifdef SIGXCPU
735   SIGNO_CASE(SIGXCPU);
736 #endif
737
738 #ifdef SIGXFSZ
739   SIGNO_CASE(SIGXFSZ);
740 #endif
741
742 #ifdef SIGVTALRM
743   SIGNO_CASE(SIGVTALRM);
744 #endif
745
746 #ifdef SIGPROF
747   SIGNO_CASE(SIGPROF);
748 #endif
749
750 #ifdef SIGWINCH
751   SIGNO_CASE(SIGWINCH);
752 #endif
753
754 #ifdef SIGIO
755   SIGNO_CASE(SIGIO);
756 #endif
757
758 #ifdef SIGPOLL
759 # if SIGPOLL != SIGIO
760   SIGNO_CASE(SIGPOLL);
761 # endif
762 #endif
763
764 #ifdef SIGLOST
765 # if SIGLOST != SIGABRT
766   SIGNO_CASE(SIGLOST);
767 # endif
768 #endif
769
770 #ifdef SIGPWR
771 # if SIGPWR != SIGLOST
772   SIGNO_CASE(SIGPWR);
773 # endif
774 #endif
775
776 #ifdef SIGINFO
777 # if !defined(SIGPWR) || SIGINFO != SIGPWR
778   SIGNO_CASE(SIGINFO);
779 # endif
780 #endif
781
782 #ifdef SIGSYS
783   SIGNO_CASE(SIGSYS);
784 #endif
785
786   default: return "";
787   }
788 }
789
790
791 Local<Value> ErrnoException(Isolate* isolate,
792                             int errorno,
793                             const char *syscall,
794                             const char *msg,
795                             const char *path) {
796   Environment* env = Environment::GetCurrent(isolate);
797
798   Local<Value> e;
799   Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
800   if (msg == nullptr || msg[0] == '\0') {
801     msg = strerror(errorno);
802   }
803   Local<String> message = OneByteString(env->isolate(), msg);
804
805   Local<String> cons =
806       String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
807   cons = String::Concat(cons, message);
808
809   Local<String> path_string;
810   if (path != nullptr) {
811     // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
812     path_string = String::NewFromUtf8(env->isolate(), path);
813   }
814
815   if (path_string.IsEmpty() == false) {
816     cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
817     cons = String::Concat(cons, path_string);
818     cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
819   }
820   e = Exception::Error(cons);
821
822   Local<Object> obj = e->ToObject(env->isolate());
823   obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
824   obj->Set(env->code_string(), estring);
825
826   if (path_string.IsEmpty() == false) {
827     obj->Set(env->path_string(), path_string);
828   }
829
830   if (syscall != nullptr) {
831     obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
832   }
833
834   return e;
835 }
836
837
838 static Local<String> StringFromPath(Isolate* isolate, const char* path) {
839 #ifdef _WIN32
840   if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
841     return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
842                           String::NewFromUtf8(isolate, path + 8));
843   } else if (strncmp(path, "\\\\?\\", 4) == 0) {
844     return String::NewFromUtf8(isolate, path + 4);
845   }
846 #endif
847
848   return String::NewFromUtf8(isolate, path);
849 }
850
851
852 Local<Value> UVException(Isolate* isolate,
853                          int errorno,
854                          const char* syscall,
855                          const char* msg,
856                          const char* path) {
857   return UVException(isolate, errorno, syscall, msg, path, nullptr);
858 }
859
860
861 Local<Value> UVException(Isolate* isolate,
862                          int errorno,
863                          const char* syscall,
864                          const char* msg,
865                          const char* path,
866                          const char* dest) {
867   Environment* env = Environment::GetCurrent(isolate);
868
869   if (!msg || !msg[0])
870     msg = uv_strerror(errorno);
871
872   const char* err_name = uv_err_name(errorno);
873   if (err_name == NULL)
874     err_name = "UnknownSystemError";
875
876   Local<String> js_code = OneByteString(isolate, err_name);
877   Local<String> js_syscall = OneByteString(isolate, syscall);
878   Local<String> js_path;
879   Local<String> js_dest;
880
881   Local<String> js_msg = js_code;
882   js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
883   js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
884   js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
885   js_msg = String::Concat(js_msg, js_syscall);
886
887   if (path != nullptr) {
888     js_path = StringFromPath(isolate, path);
889
890     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
891     js_msg = String::Concat(js_msg, js_path);
892     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
893   }
894
895   if (dest != nullptr) {
896     js_dest = StringFromPath(isolate, dest);
897
898     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
899     js_msg = String::Concat(js_msg, js_dest);
900     js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
901   }
902
903   Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
904
905   // TODO(piscisaureus) errno should probably go; the user has no way of
906   // knowing which uv errno value maps to which error.
907   e->Set(env->errno_string(), Integer::New(isolate, errorno));
908   e->Set(env->code_string(), js_code);
909   e->Set(env->syscall_string(), js_syscall);
910   if (!js_path.IsEmpty())
911     e->Set(env->path_string(), js_path);
912   if (!js_dest.IsEmpty())
913     e->Set(env->dest_string(), js_dest);
914
915   return e;
916 }
917
918
919 // Look up environment variable unless running as setuid root.
920 inline const char* secure_getenv(const char* key) {
921 #ifndef _WIN32
922   if (getuid() != geteuid() || getgid() != getegid())
923     return nullptr;
924 #endif
925   return getenv(key);
926 }
927
928
929 #ifdef _WIN32
930 // Does about the same as strerror(),
931 // but supports all windows error messages
932 static const char *winapi_strerror(const int errorno, bool* must_free) {
933   char *errmsg = nullptr;
934
935   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
936       FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
937       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
938
939   if (errmsg) {
940     *must_free = true;
941
942     // Remove trailing newlines
943     for (int i = strlen(errmsg) - 1;
944         i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
945       errmsg[i] = '\0';
946     }
947
948     return errmsg;
949   } else {
950     // FormatMessage failed
951     *must_free = false;
952     return "Unknown error";
953   }
954 }
955
956
957 Local<Value> WinapiErrnoException(Isolate* isolate,
958                                   int errorno,
959                                   const char* syscall,
960                                   const char* msg,
961                                   const char* path) {
962   Environment* env = Environment::GetCurrent(isolate);
963   Local<Value> e;
964   bool must_free = false;
965   if (!msg || !msg[0]) {
966     msg = winapi_strerror(errorno, &must_free);
967   }
968   Local<String> message = OneByteString(env->isolate(), msg);
969
970   if (path) {
971     Local<String> cons1 =
972         String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
973     Local<String> cons2 =
974         String::Concat(cons1, String::NewFromUtf8(isolate, path));
975     Local<String> cons3 =
976         String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
977     e = Exception::Error(cons3);
978   } else {
979     e = Exception::Error(message);
980   }
981
982   Local<Object> obj = e->ToObject(env->isolate());
983   obj->Set(env->errno_string(), Integer::New(isolate, errorno));
984
985   if (path != nullptr) {
986     obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
987   }
988
989   if (syscall != nullptr) {
990     obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
991   }
992
993   if (must_free)
994     LocalFree((HLOCAL)msg);
995
996   return e;
997 }
998 #endif
999
1000
1001 void* ArrayBufferAllocator::Allocate(size_t size) {
1002   if (zero_fill_field_ || zero_fill_all_buffers)
1003     return node::UncheckedCalloc(size);
1004   else
1005     return node::UncheckedMalloc(size);
1006 }
1007
1008 static bool DomainHasErrorHandler(const Environment* env,
1009                                   const Local<Object>& domain) {
1010   HandleScope scope(env->isolate());
1011
1012   Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
1013   if (!domain_event_listeners_v->IsObject())
1014     return false;
1015
1016   Local<Object> domain_event_listeners_o =
1017       domain_event_listeners_v.As<Object>();
1018
1019   Local<Value> domain_error_listeners_v =
1020       domain_event_listeners_o->Get(env->error_string());
1021
1022   if (domain_error_listeners_v->IsFunction() ||
1023       (domain_error_listeners_v->IsArray() &&
1024       domain_error_listeners_v.As<Array>()->Length() > 0))
1025     return true;
1026
1027   return false;
1028 }
1029
1030 static bool DomainsStackHasErrorHandler(const Environment* env) {
1031   HandleScope scope(env->isolate());
1032
1033   if (!env->using_domains())
1034     return false;
1035
1036   Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
1037   if (domains_stack_array->Length() == 0)
1038     return false;
1039
1040   uint32_t domains_stack_length = domains_stack_array->Length();
1041   for (uint32_t i = domains_stack_length; i > 0; --i) {
1042     Local<Value> domain_v = domains_stack_array->Get(i - 1);
1043     if (!domain_v->IsObject())
1044       return false;
1045
1046     Local<Object> domain = domain_v.As<Object>();
1047     if (DomainHasErrorHandler(env, domain))
1048       return true;
1049   }
1050
1051   return false;
1052 }
1053
1054
1055 static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
1056   HandleScope scope(isolate);
1057
1058   Environment* env = Environment::GetCurrent(isolate);
1059   Local<Object> process_object = env->process_object();
1060   Local<String> emitting_top_level_domain_error_key =
1061     env->emitting_top_level_domain_error_string();
1062   bool isEmittingTopLevelDomainError =
1063       process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1064
1065   return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env);
1066 }
1067
1068
1069 void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
1070   Environment* env = Environment::GetCurrent(args);
1071
1072   if (env->using_domains())
1073     return;
1074   env->set_using_domains(true);
1075
1076   HandleScope scope(env->isolate());
1077   Local<Object> process_object = env->process_object();
1078
1079   Local<String> tick_callback_function_key = env->tick_domain_cb_string();
1080   Local<Function> tick_callback_function =
1081       process_object->Get(tick_callback_function_key).As<Function>();
1082
1083   if (!tick_callback_function->IsFunction()) {
1084     fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
1085     ABORT();
1086   }
1087
1088   process_object->Set(env->tick_callback_string(), tick_callback_function);
1089   env->set_tick_callback_function(tick_callback_function);
1090
1091   CHECK(args[0]->IsArray());
1092   env->set_domain_array(args[0].As<Array>());
1093
1094   CHECK(args[1]->IsArray());
1095   env->set_domains_stack_array(args[1].As<Array>());
1096
1097   // Do a little housekeeping.
1098   env->process_object()->Delete(
1099       env->context(),
1100       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust();
1101
1102   uint32_t* const fields = env->domain_flag()->fields();
1103   uint32_t const fields_count = env->domain_flag()->fields_count();
1104
1105   Local<ArrayBuffer> array_buffer =
1106       ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1107
1108   args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1109 }
1110
1111 void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
1112   args.GetIsolate()->RunMicrotasks();
1113 }
1114
1115
1116 void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
1117   Environment* env = Environment::GetCurrent(args);
1118
1119   CHECK(args[0]->IsFunction());
1120
1121   env->set_push_values_to_array_function(args[0].As<Function>());
1122   env->process_object()->Delete(
1123       env->context(),
1124       FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust();
1125 }
1126
1127
1128 void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
1129   Environment* env = Environment::GetCurrent(args);
1130
1131   CHECK(args[0]->IsFunction());
1132   CHECK(args[1]->IsObject());
1133
1134   env->set_tick_callback_function(args[0].As<Function>());
1135
1136   env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks);
1137
1138   // Do a little housekeeping.
1139   env->process_object()->Delete(
1140       env->context(),
1141       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick")).FromJust();
1142
1143   // Values use to cross communicate with processNextTick.
1144   uint32_t* const fields = env->tick_info()->fields();
1145   uint32_t const fields_count = env->tick_info()->fields_count();
1146
1147   Local<ArrayBuffer> array_buffer =
1148       ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1149
1150   args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1151 }
1152
1153 void PromiseRejectCallback(PromiseRejectMessage message) {
1154   Local<Promise> promise = message.GetPromise();
1155   Isolate* isolate = promise->GetIsolate();
1156   Local<Value> value = message.GetValue();
1157   Local<Integer> event = Integer::New(isolate, message.GetEvent());
1158
1159   Environment* env = Environment::GetCurrent(isolate);
1160   Local<Function> callback = env->promise_reject_function();
1161
1162   if (value.IsEmpty())
1163     value = Undefined(isolate);
1164
1165   Local<Value> args[] = { event, promise, value };
1166   Local<Object> process = env->process_object();
1167
1168   callback->Call(process, arraysize(args), args);
1169 }
1170
1171 void SetupPromises(const FunctionCallbackInfo<Value>& args) {
1172   Environment* env = Environment::GetCurrent(args);
1173   Isolate* isolate = env->isolate();
1174
1175   CHECK(args[0]->IsFunction());
1176
1177   if (g_standalone_mode) {  // No indent to minimize diff.
1178   isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1179   }
1180   env->set_promise_reject_function(args[0].As<Function>());
1181
1182   env->process_object()->Delete(
1183       env->context(),
1184       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises")).FromJust();
1185 }
1186
1187
1188 Local<Value> MakeCallback(Environment* env,
1189                           Local<Value> recv,
1190                           const Local<Function> callback,
1191                           int argc,
1192                           Local<Value> argv[]) {
1193   // If you hit this assertion, you forgot to enter the v8::Context first.
1194   CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
1195
1196   Local<Function> pre_fn = env->async_hooks_pre_function();
1197   Local<Function> post_fn = env->async_hooks_post_function();
1198   Local<Object> object, domain;
1199   bool ran_init_callback = false;
1200   bool has_domain = false;
1201
1202   Environment::AsyncCallbackScope callback_scope(env);
1203
1204   // TODO(trevnorris): Adding "_asyncQueue" to the "this" in the init callback
1205   // is a horrible way to detect usage. Rethink how detection should happen.
1206   if (recv->IsObject()) {
1207     object = recv.As<Object>();
1208     Local<Value> async_queue_v = object->Get(env->async_queue_string());
1209     if (async_queue_v->IsObject())
1210       ran_init_callback = true;
1211   }
1212
1213   if (env->using_domains()) {
1214     CHECK(recv->IsObject());
1215     Local<Value> domain_v = object->Get(env->domain_string());
1216     has_domain = domain_v->IsObject();
1217     if (has_domain) {
1218       domain = domain_v.As<Object>();
1219       if (domain->Get(env->disposed_string())->IsTrue())
1220         return Undefined(env->isolate());
1221     }
1222   }
1223
1224   if (has_domain) {
1225     Local<Value> enter_v = domain->Get(env->enter_string());
1226     if (enter_v->IsFunction()) {
1227       if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1228         FatalError("node::MakeCallback",
1229                    "domain enter callback threw, please report this");
1230       }
1231     }
1232   }
1233
1234   if (ran_init_callback && !pre_fn.IsEmpty()) {
1235     TryCatch try_catch(env->isolate());
1236     MaybeLocal<Value> ar = pre_fn->Call(env->context(), object, 0, nullptr);
1237     if (ar.IsEmpty()) {
1238       ClearFatalExceptionHandlers(env);
1239       FatalException(env->isolate(), try_catch);
1240       return Local<Value>();
1241     }
1242   }
1243
1244   Local<Value> ret = callback->Call(recv, argc, argv);
1245
1246   if (ran_init_callback && !post_fn.IsEmpty()) {
1247     Local<Value> did_throw = Boolean::New(env->isolate(), ret.IsEmpty());
1248     // Currently there's no way to retrieve an uid from node::MakeCallback().
1249     // This needs to be fixed.
1250     Local<Value> vals[] =
1251         { Undefined(env->isolate()).As<Value>(), did_throw };
1252     TryCatch try_catch(env->isolate());
1253     MaybeLocal<Value> ar =
1254         post_fn->Call(env->context(), object, arraysize(vals), vals);
1255     if (ar.IsEmpty()) {
1256       ClearFatalExceptionHandlers(env);
1257       FatalException(env->isolate(), try_catch);
1258       return Local<Value>();
1259     }
1260   }
1261
1262   if (ret.IsEmpty()) {
1263     // NOTE: For backwards compatibility with public API we return Undefined()
1264     // if the top level call threw.
1265     return callback_scope.in_makecallback() ?
1266         ret : Undefined(env->isolate()).As<Value>();
1267   }
1268
1269   if (has_domain) {
1270     Local<Value> exit_v = domain->Get(env->exit_string());
1271     if (exit_v->IsFunction()) {
1272       if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1273         FatalError("node::MakeCallback",
1274                    "domain exit callback threw, please report this");
1275       }
1276     }
1277   }
1278
1279   if (callback_scope.in_makecallback()) {
1280     return ret;
1281   }
1282
1283   Environment::TickInfo* tick_info = env->tick_info();
1284
1285   if (tick_info->length() == 0) {
1286     env->isolate()->RunMicrotasks();
1287   }
1288
1289   Local<Object> process = env->process_object();
1290
1291   if (tick_info->length() == 0) {
1292     tick_info->set_index(0);
1293     return ret;
1294   }
1295
1296   if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
1297     return Undefined(env->isolate());
1298   }
1299
1300   return ret;
1301 }
1302
1303
1304 Local<Value> MakeCallback(Environment* env,
1305                            Local<Object> recv,
1306                            Local<String> symbol,
1307                            int argc,
1308                            Local<Value> argv[]) {
1309   Local<Value> cb_v = recv->Get(symbol);
1310   CHECK(cb_v->IsFunction());
1311   return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1312 }
1313
1314
1315 Local<Value> MakeCallback(Environment* env,
1316                            Local<Object> recv,
1317                            const char* method,
1318                            int argc,
1319                            Local<Value> argv[]) {
1320   Local<String> method_string = OneByteString(env->isolate(), method);
1321   return MakeCallback(env, recv, method_string, argc, argv);
1322 }
1323
1324
1325 Local<Value> MakeCallback(Isolate* isolate,
1326                           Local<Object> recv,
1327                           const char* method,
1328                           int argc,
1329                           Local<Value> argv[]) {
1330   EscapableHandleScope handle_scope(isolate);
1331   Local<String> method_string = OneByteString(isolate, method);
1332   return handle_scope.Escape(
1333       MakeCallback(isolate, recv, method_string, argc, argv));
1334 }
1335
1336
1337 Local<Value> MakeCallback(Isolate* isolate,
1338                           Local<Object> recv,
1339                           Local<String> symbol,
1340                           int argc,
1341                           Local<Value> argv[]) {
1342   EscapableHandleScope handle_scope(isolate);
1343   Local<Value> callback_v = recv->Get(symbol);
1344   if (callback_v.IsEmpty()) return Local<Value>();
1345   if (!callback_v->IsFunction()) return Local<Value>();
1346   Local<Function> callback = callback_v.As<Function>();
1347   return handle_scope.Escape(MakeCallback(isolate, recv, callback, argc, argv));
1348 }
1349
1350
1351 Local<Value> MakeCallback(Isolate* isolate,
1352                           Local<Object> recv,
1353                           Local<Function> callback,
1354                           int argc,
1355                           Local<Value> argv[]) {
1356   // Observe the following two subtleties:
1357   //
1358   // 1. The environment is retrieved from the callback function's context.
1359   // 2. The context to enter is retrieved from the environment.
1360   //
1361   // Because of the AssignToContext() call in src/node_contextify.cc,
1362   // the two contexts need not be the same.
1363   EscapableHandleScope handle_scope(isolate);
1364   Environment* env = Environment::GetCurrent(callback->CreationContext());
1365   Context::Scope context_scope(env->context());
1366   return handle_scope.Escape(
1367       MakeCallback(env, recv.As<Value>(), callback, argc, argv));
1368 }
1369
1370
1371 enum encoding ParseEncoding(const char* encoding,
1372                             enum encoding default_encoding) {
1373   switch (encoding[0]) {
1374     case 'u':
1375       // utf8, utf16le
1376       if (encoding[1] == 't' && encoding[2] == 'f') {
1377         // Skip `-`
1378         encoding += encoding[3] == '-' ? 4 : 3;
1379         if (encoding[0] == '8' && encoding[1] == '\0')
1380           return UTF8;
1381         if (strncmp(encoding, "16le", 4) == 0)
1382           return UCS2;
1383
1384       // ucs2
1385       } else if (encoding[1] == 'c' && encoding[2] == 's') {
1386         encoding += encoding[3] == '-' ? 4 : 3;
1387         if (encoding[0] == '2' && encoding[1] == '\0')
1388           return UCS2;
1389       }
1390       break;
1391     case 'l':
1392       // latin1
1393       if (encoding[1] == 'a') {
1394         if (strncmp(encoding + 2, "tin1", 4) == 0)
1395           return LATIN1;
1396       }
1397       break;
1398     case 'b':
1399       // binary
1400       if (encoding[1] == 'i') {
1401         if (strncmp(encoding + 2, "nary", 4) == 0)
1402           return LATIN1;
1403
1404       // buffer
1405       } else if (encoding[1] == 'u') {
1406         if (strncmp(encoding + 2, "ffer", 4) == 0)
1407           return BUFFER;
1408       }
1409       break;
1410     case '\0':
1411       return default_encoding;
1412     default:
1413       break;
1414   }
1415
1416   if (StringEqualNoCase(encoding, "utf8")) {
1417     return UTF8;
1418   } else if (StringEqualNoCase(encoding, "utf-8")) {
1419     return UTF8;
1420   } else if (StringEqualNoCase(encoding, "ascii")) {
1421     return ASCII;
1422   } else if (StringEqualNoCase(encoding, "base64")) {
1423     return BASE64;
1424   } else if (StringEqualNoCase(encoding, "ucs2")) {
1425     return UCS2;
1426   } else if (StringEqualNoCase(encoding, "ucs-2")) {
1427     return UCS2;
1428   } else if (StringEqualNoCase(encoding, "utf16le")) {
1429     return UCS2;
1430   } else if (StringEqualNoCase(encoding, "utf-16le")) {
1431     return UCS2;
1432   } else if (StringEqualNoCase(encoding, "latin1")) {
1433     return LATIN1;
1434   } else if (StringEqualNoCase(encoding, "binary")) {
1435     return LATIN1;  // BINARY is a deprecated alias of LATIN1.
1436   } else if (StringEqualNoCase(encoding, "buffer")) {
1437     return BUFFER;
1438   } else if (StringEqualNoCase(encoding, "hex")) {
1439     return HEX;
1440   } else {
1441     return default_encoding;
1442   }
1443 }
1444
1445
1446 enum encoding ParseEncoding(Isolate* isolate,
1447                             Local<Value> encoding_v,
1448                             enum encoding default_encoding) {
1449   if (!encoding_v->IsString())
1450     return default_encoding;
1451
1452   node::Utf8Value encoding(isolate, encoding_v);
1453
1454   return ParseEncoding(*encoding, default_encoding);
1455 }
1456
1457 Local<Value> Encode(Isolate* isolate,
1458                     const char* buf,
1459                     size_t len,
1460                     enum encoding encoding) {
1461   CHECK_NE(encoding, UCS2);
1462   return StringBytes::Encode(isolate, buf, len, encoding);
1463 }
1464
1465 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1466   return StringBytes::Encode(isolate, buf, len);
1467 }
1468
1469 // Returns -1 if the handle was not valid for decoding
1470 ssize_t DecodeBytes(Isolate* isolate,
1471                     Local<Value> val,
1472                     enum encoding encoding) {
1473   HandleScope scope(isolate);
1474
1475   return StringBytes::Size(isolate, val, encoding);
1476 }
1477
1478 // Returns number of bytes written.
1479 ssize_t DecodeWrite(Isolate* isolate,
1480                     char* buf,
1481                     size_t buflen,
1482                     Local<Value> val,
1483                     enum encoding encoding) {
1484   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
1485 }
1486
1487 bool IsExceptionDecorated(Environment* env, Local<Value> er) {
1488   if (!er.IsEmpty() && er->IsObject()) {
1489     Local<Object> err_obj = er.As<Object>();
1490     auto maybe_value =
1491         err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1492     Local<Value> decorated;
1493     return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
1494   }
1495   return false;
1496 }
1497
1498 void AppendExceptionLine(Environment* env,
1499                          Local<Value> er,
1500                          Local<Message> message,
1501                          enum ErrorHandlingMode mode) {
1502   if (message.IsEmpty())
1503     return;
1504
1505   HandleScope scope(env->isolate());
1506   Local<Object> err_obj;
1507   if (!er.IsEmpty() && er->IsObject()) {
1508     err_obj = er.As<Object>();
1509
1510     auto context = env->context();
1511     auto processed_private_symbol = env->processed_private_symbol();
1512     // Do it only once per message
1513     if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
1514       return;
1515     err_obj->SetPrivate(
1516         context,
1517         processed_private_symbol,
1518         True(env->isolate()));
1519   }
1520
1521   // Print (filename):(line number): (message).
1522   node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1523   const char* filename_string = *filename;
1524   int linenum = message->GetLineNumber();
1525   // Print line of source code.
1526   node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1527   const char* sourceline_string = *sourceline;
1528
1529   // Because of how node modules work, all scripts are wrapped with a
1530   // "function (module, exports, __filename, ...) {"
1531   // to provide script local variables.
1532   //
1533   // When reporting errors on the first line of a script, this wrapper
1534   // function is leaked to the user. There used to be a hack here to
1535   // truncate off the first 62 characters, but it caused numerous other
1536   // problems when vm.runIn*Context() methods were used for non-module
1537   // code.
1538   //
1539   // If we ever decide to re-instate such a hack, the following steps
1540   // must be taken:
1541   //
1542   // 1. Pass a flag around to say "this code was wrapped"
1543   // 2. Update the stack frame output so that it is also correct.
1544   //
1545   // It would probably be simpler to add a line rather than add some
1546   // number of characters to the first line, since V8 truncates the
1547   // sourceline to 78 characters, and we end up not providing very much
1548   // useful debugging info to the user if we remove 62 characters.
1549
1550   int start = message->GetStartColumn(env->context()).FromMaybe(0);
1551   int end = message->GetEndColumn(env->context()).FromMaybe(0);
1552
1553   char arrow[1024];
1554   int max_off = sizeof(arrow) - 2;
1555
1556   int off = snprintf(arrow,
1557                      sizeof(arrow),
1558                      "%s:%i\n%s\n",
1559                      filename_string,
1560                      linenum,
1561                      sourceline_string);
1562   CHECK_GE(off, 0);
1563   if (off > max_off) {
1564     off = max_off;
1565   }
1566
1567   // Print wavy underline (GetUnderline is deprecated).
1568   for (int i = 0; i < start; i++) {
1569     if (sourceline_string[i] == '\0' || off >= max_off) {
1570       break;
1571     }
1572     CHECK_LT(off, max_off);
1573     arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1574   }
1575   for (int i = start; i < end; i++) {
1576     if (sourceline_string[i] == '\0' || off >= max_off) {
1577       break;
1578     }
1579     CHECK_LT(off, max_off);
1580     arrow[off++] = '^';
1581   }
1582   CHECK_LE(off, max_off);
1583   arrow[off] = '\n';
1584   arrow[off + 1] = '\0';
1585
1586   Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1587
1588   const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1589   // If allocating arrow_str failed, print it out. There's not much else to do.
1590   // If it's not an error, but something needs to be printed out because
1591   // it's a fatal exception, also print it out from here.
1592   // Otherwise, the arrow property will be attached to the object and handled
1593   // by the caller.
1594   if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1595     if (env->printed_error())
1596       return;
1597     env->set_printed_error(true);
1598
1599     uv_tty_reset_mode();
1600     PrintErrorString("\n%s", arrow);
1601     return;
1602   }
1603
1604   CHECK(err_obj->SetPrivate(
1605             env->context(),
1606             env->arrow_message_private_symbol(),
1607             arrow_str).FromMaybe(false));
1608 }
1609
1610
1611 static void ReportException(Environment* env,
1612                             Local<Value> er,
1613                             Local<Message> message) {
1614   HandleScope scope(env->isolate());
1615
1616   AppendExceptionLine(env, er, message, FATAL_ERROR);
1617
1618   Local<Value> trace_value;
1619   Local<Value> arrow;
1620   const bool decorated = IsExceptionDecorated(env, er);
1621
1622   if (er->IsUndefined() || er->IsNull()) {
1623     trace_value = Undefined(env->isolate());
1624   } else {
1625     Local<Object> err_obj = er->ToObject(env->isolate());
1626
1627     trace_value = err_obj->Get(env->stack_string());
1628     arrow =
1629         err_obj->GetPrivate(
1630             env->context(),
1631             env->arrow_message_private_symbol()).ToLocalChecked();
1632   }
1633
1634   node::Utf8Value trace(env->isolate(), trace_value);
1635
1636   // range errors have a trace member set to undefined
1637   if (trace.length() > 0 && !trace_value->IsUndefined()) {
1638     if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1639       PrintErrorString("%s\n", *trace);
1640     } else {
1641       node::Utf8Value arrow_string(env->isolate(), arrow);
1642       PrintErrorString("%s\n%s\n", *arrow_string, *trace);
1643     }
1644   } else {
1645     // this really only happens for RangeErrors, since they're the only
1646     // kind that won't have all this info in the trace, or when non-Error
1647     // objects are thrown manually.
1648     Local<Value> message;
1649     Local<Value> name;
1650
1651     if (er->IsObject()) {
1652       Local<Object> err_obj = er.As<Object>();
1653       message = err_obj->Get(env->message_string());
1654       name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
1655     }
1656
1657     if (message.IsEmpty() ||
1658         message->IsUndefined() ||
1659         name.IsEmpty() ||
1660         name->IsUndefined()) {
1661       // Not an error object. Just print as-is.
1662       String::Utf8Value message(er);
1663
1664       PrintErrorString("%s\n", *message ? *message :
1665                                           "<toString() threw exception>");
1666     } else {
1667       node::Utf8Value name_string(env->isolate(), name);
1668       node::Utf8Value message_string(env->isolate(), message);
1669
1670       if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1671         PrintErrorString("%s: %s\n", *name_string, *message_string);
1672       } else {
1673         node::Utf8Value arrow_string(env->isolate(), arrow);
1674         PrintErrorString("%s\n%s: %s\n",
1675                          *arrow_string,
1676                          *name_string,
1677                          *message_string);
1678       }
1679     }
1680   }
1681
1682   fflush(stderr);
1683 }
1684
1685
1686 static void ReportException(Environment* env, const TryCatch& try_catch) {
1687   ReportException(env, try_catch.Exception(), try_catch.Message());
1688 }
1689
1690
1691 // Executes a str within the current v8 context.
1692 static Local<Value> ExecuteString(Environment* env,
1693                                   Local<String> source,
1694                                   Local<String> filename) {
1695   EscapableHandleScope scope(env->isolate());
1696   TryCatch try_catch(env->isolate());
1697
1698   // try_catch must be nonverbose to disable FatalException() handler,
1699   // we will handle exceptions ourself.
1700   try_catch.SetVerbose(false);
1701
1702   ScriptOrigin origin(filename);
1703   MaybeLocal<v8::Script> script =
1704       v8::Script::Compile(env->context(), source, &origin);
1705   if (script.IsEmpty()) {
1706     ReportException(env, try_catch);
1707     exit(3);
1708   }
1709
1710   Local<Value> result = script.ToLocalChecked()->Run();
1711   if (result.IsEmpty()) {
1712     ReportException(env, try_catch);
1713     exit(4);
1714   }
1715
1716   return scope.Escape(result);
1717 }
1718
1719
1720 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1721   Environment* env = Environment::GetCurrent(args);
1722
1723   Local<Array> ary = Array::New(args.GetIsolate());
1724   Local<Context> ctx = env->context();
1725   Local<Function> fn = env->push_values_to_array_function();
1726   Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1727   size_t idx = 0;
1728
1729   for (auto w : *env->req_wrap_queue()) {
1730     if (w->persistent().IsEmpty())
1731       continue;
1732     argv[idx] = w->object();
1733     if (++idx >= arraysize(argv)) {
1734       fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1735       idx = 0;
1736     }
1737   }
1738
1739   if (idx > 0) {
1740     fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1741   }
1742
1743   args.GetReturnValue().Set(ary);
1744 }
1745
1746
1747 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1748 // implemented here for consistency with GetActiveRequests().
1749 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1750   Environment* env = Environment::GetCurrent(args);
1751
1752   Local<Array> ary = Array::New(env->isolate());
1753   Local<Context> ctx = env->context();
1754   Local<Function> fn = env->push_values_to_array_function();
1755   Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1756   size_t idx = 0;
1757
1758   Local<String> owner_sym = env->owner_string();
1759
1760   for (auto w : *env->handle_wrap_queue()) {
1761     if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
1762       continue;
1763     Local<Object> object = w->object();
1764     Local<Value> owner = object->Get(owner_sym);
1765     if (owner->IsUndefined())
1766       owner = object;
1767     argv[idx] = owner;
1768     if (++idx >= arraysize(argv)) {
1769       fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1770       idx = 0;
1771     }
1772   }
1773   if (idx > 0) {
1774     fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1775   }
1776
1777   args.GetReturnValue().Set(ary);
1778 }
1779
1780
1781 NO_RETURN void Abort() {
1782   DumpBacktrace(stderr);
1783   fflush(stderr);
1784   ABORT_NO_BACKTRACE();
1785 }
1786
1787
1788 NO_RETURN void Assert(const char* const (*args)[4]) {
1789   auto filename = (*args)[0];
1790   auto linenum = (*args)[1];
1791   auto message = (*args)[2];
1792   auto function = (*args)[3];
1793
1794   char exepath[256];
1795   size_t exepath_size = sizeof(exepath);
1796   if (uv_exepath(exepath, &exepath_size))
1797     snprintf(exepath, sizeof(exepath), "node");
1798
1799   char pid[12] = {0};
1800 #ifndef _WIN32
1801   snprintf(pid, sizeof(pid), "[%u]", getpid());
1802 #endif
1803
1804   fprintf(stderr, "%s%s: %s:%s:%s%s Assertion `%s' failed.\n",
1805           exepath, pid, filename, linenum,
1806           function, *function ? ":" : "", message);
1807   fflush(stderr);
1808
1809   Abort();
1810 }
1811
1812
1813 static void Abort(const FunctionCallbackInfo<Value>& args) {
1814   Abort();
1815 }
1816
1817
1818 static void Chdir(const FunctionCallbackInfo<Value>& args) {
1819   Environment* env = Environment::GetCurrent(args);
1820
1821   if (args.Length() != 1 || !args[0]->IsString()) {
1822     return env->ThrowTypeError("Bad argument.");
1823   }
1824
1825   node::Utf8Value path(args.GetIsolate(), args[0]);
1826   int err = uv_chdir(*path);
1827   if (err) {
1828     return env->ThrowUVException(err, "uv_chdir");
1829   }
1830 }
1831
1832
1833 static void Cwd(const FunctionCallbackInfo<Value>& args) {
1834   Environment* env = Environment::GetCurrent(args);
1835 #ifdef _WIN32
1836   /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
1837   char buf[MAX_PATH * 4];
1838 #else
1839   char buf[PATH_MAX];
1840 #endif
1841
1842   size_t cwd_len = sizeof(buf);
1843   int err = uv_cwd(buf, &cwd_len);
1844   if (err) {
1845     return env->ThrowUVException(err, "uv_cwd");
1846   }
1847
1848   Local<String> cwd = String::NewFromUtf8(env->isolate(),
1849                                           buf,
1850                                           String::kNormalString,
1851                                           cwd_len);
1852   args.GetReturnValue().Set(cwd);
1853 }
1854
1855
1856 static void Umask(const FunctionCallbackInfo<Value>& args) {
1857   Environment* env = Environment::GetCurrent(args);
1858   uint32_t old;
1859
1860   if (args.Length() < 1 || args[0]->IsUndefined()) {
1861     old = umask(0);
1862     umask(static_cast<mode_t>(old));
1863   } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1864     return env->ThrowTypeError("argument must be an integer or octal string.");
1865   } else {
1866     int oct;
1867     if (args[0]->IsInt32()) {
1868       oct = args[0]->Uint32Value();
1869     } else {
1870       oct = 0;
1871       node::Utf8Value str(env->isolate(), args[0]);
1872
1873       // Parse the octal string.
1874       for (size_t i = 0; i < str.length(); i++) {
1875         char c = (*str)[i];
1876         if (c > '7' || c < '0') {
1877           return env->ThrowTypeError("invalid octal string");
1878         }
1879         oct *= 8;
1880         oct += c - '0';
1881       }
1882     }
1883     old = umask(static_cast<mode_t>(oct));
1884   }
1885
1886   args.GetReturnValue().Set(old);
1887 }
1888
1889
1890 #if defined(__POSIX__) && !defined(__ANDROID__)
1891
1892 static const uid_t uid_not_found = static_cast<uid_t>(-1);
1893 static const gid_t gid_not_found = static_cast<gid_t>(-1);
1894
1895
1896 static uid_t uid_by_name(const char* name) {
1897   struct passwd pwd;
1898   struct passwd* pp;
1899   char buf[8192];
1900
1901   errno = 0;
1902   pp = nullptr;
1903
1904   if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1905     return pp->pw_uid;
1906   }
1907
1908   return uid_not_found;
1909 }
1910
1911
1912 static char* name_by_uid(uid_t uid) {
1913   struct passwd pwd;
1914   struct passwd* pp;
1915   char buf[8192];
1916   int rc;
1917
1918   errno = 0;
1919   pp = nullptr;
1920
1921   if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1922       pp != nullptr) {
1923     return strdup(pp->pw_name);
1924   }
1925
1926   if (rc == 0) {
1927     errno = ENOENT;
1928   }
1929
1930   return nullptr;
1931 }
1932
1933
1934 static gid_t gid_by_name(const char* name) {
1935   struct group pwd;
1936   struct group* pp;
1937   char buf[8192];
1938
1939   errno = 0;
1940   pp = nullptr;
1941
1942   if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1943     return pp->gr_gid;
1944   }
1945
1946   return gid_not_found;
1947 }
1948
1949
1950 #if 0  // For future use.
1951 static const char* name_by_gid(gid_t gid) {
1952   struct group pwd;
1953   struct group* pp;
1954   char buf[8192];
1955   int rc;
1956
1957   errno = 0;
1958   pp = nullptr;
1959
1960   if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1961       pp != nullptr) {
1962     return strdup(pp->gr_name);
1963   }
1964
1965   if (rc == 0) {
1966     errno = ENOENT;
1967   }
1968
1969   return nullptr;
1970 }
1971 #endif
1972
1973
1974 static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
1975   if (value->IsUint32()) {
1976     return static_cast<uid_t>(value->Uint32Value());
1977   } else {
1978     node::Utf8Value name(isolate, value);
1979     return uid_by_name(*name);
1980   }
1981 }
1982
1983
1984 static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
1985   if (value->IsUint32()) {
1986     return static_cast<gid_t>(value->Uint32Value());
1987   } else {
1988     node::Utf8Value name(isolate, value);
1989     return gid_by_name(*name);
1990   }
1991 }
1992
1993 static void GetUid(const FunctionCallbackInfo<Value>& args) {
1994   // uid_t is an uint32_t on all supported platforms.
1995   args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
1996 }
1997
1998
1999 static void GetGid(const FunctionCallbackInfo<Value>& args) {
2000   // gid_t is an uint32_t on all supported platforms.
2001   args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
2002 }
2003
2004
2005 static void GetEUid(const FunctionCallbackInfo<Value>& args) {
2006   // uid_t is an uint32_t on all supported platforms.
2007   args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
2008 }
2009
2010
2011 static void GetEGid(const FunctionCallbackInfo<Value>& args) {
2012   // gid_t is an uint32_t on all supported platforms.
2013   args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
2014 }
2015
2016
2017 static void SetGid(const FunctionCallbackInfo<Value>& args) {
2018   Environment* env = Environment::GetCurrent(args);
2019
2020   if (!args[0]->IsUint32() && !args[0]->IsString()) {
2021     return env->ThrowTypeError("setgid argument must be a number or a string");
2022   }
2023
2024   gid_t gid = gid_by_name(env->isolate(), args[0]);
2025
2026   if (gid == gid_not_found) {
2027     return env->ThrowError("setgid group id does not exist");
2028   }
2029
2030   if (setgid(gid)) {
2031     return env->ThrowErrnoException(errno, "setgid");
2032   }
2033 }
2034
2035
2036 static void SetEGid(const FunctionCallbackInfo<Value>& args) {
2037   Environment* env = Environment::GetCurrent(args);
2038
2039   if (!args[0]->IsUint32() && !args[0]->IsString()) {
2040     return env->ThrowTypeError("setegid argument must be a number or string");
2041   }
2042
2043   gid_t gid = gid_by_name(env->isolate(), args[0]);
2044
2045   if (gid == gid_not_found) {
2046     return env->ThrowError("setegid group id does not exist");
2047   }
2048
2049   if (setegid(gid)) {
2050     return env->ThrowErrnoException(errno, "setegid");
2051   }
2052 }
2053
2054
2055 static void SetUid(const FunctionCallbackInfo<Value>& args) {
2056   Environment* env = Environment::GetCurrent(args);
2057
2058   if (!args[0]->IsUint32() && !args[0]->IsString()) {
2059     return env->ThrowTypeError("setuid argument must be a number or a string");
2060   }
2061
2062   uid_t uid = uid_by_name(env->isolate(), args[0]);
2063
2064   if (uid == uid_not_found) {
2065     return env->ThrowError("setuid user id does not exist");
2066   }
2067
2068   if (setuid(uid)) {
2069     return env->ThrowErrnoException(errno, "setuid");
2070   }
2071 }
2072
2073
2074 static void SetEUid(const FunctionCallbackInfo<Value>& args) {
2075   Environment* env = Environment::GetCurrent(args);
2076
2077   if (!args[0]->IsUint32() && !args[0]->IsString()) {
2078     return env->ThrowTypeError("seteuid argument must be a number or string");
2079   }
2080
2081   uid_t uid = uid_by_name(env->isolate(), args[0]);
2082
2083   if (uid == uid_not_found) {
2084     return env->ThrowError("seteuid user id does not exist");
2085   }
2086
2087   if (seteuid(uid)) {
2088     return env->ThrowErrnoException(errno, "seteuid");
2089   }
2090 }
2091
2092
2093 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
2094   Environment* env = Environment::GetCurrent(args);
2095
2096   int ngroups = getgroups(0, nullptr);
2097
2098   if (ngroups == -1) {
2099     return env->ThrowErrnoException(errno, "getgroups");
2100   }
2101
2102   gid_t* groups = new gid_t[ngroups];
2103
2104   ngroups = getgroups(ngroups, groups);
2105
2106   if (ngroups == -1) {
2107     delete[] groups;
2108     return env->ThrowErrnoException(errno, "getgroups");
2109   }
2110
2111   Local<Array> groups_list = Array::New(env->isolate(), ngroups);
2112   bool seen_egid = false;
2113   gid_t egid = getegid();
2114
2115   for (int i = 0; i < ngroups; i++) {
2116     groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
2117     if (groups[i] == egid)
2118       seen_egid = true;
2119   }
2120
2121   delete[] groups;
2122
2123   if (seen_egid == false) {
2124     groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
2125   }
2126
2127   args.GetReturnValue().Set(groups_list);
2128 }
2129
2130
2131 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
2132   Environment* env = Environment::GetCurrent(args);
2133
2134   if (!args[0]->IsArray()) {
2135     return env->ThrowTypeError("argument 1 must be an array");
2136   }
2137
2138   Local<Array> groups_list = args[0].As<Array>();
2139   size_t size = groups_list->Length();
2140   gid_t* groups = new gid_t[size];
2141
2142   for (size_t i = 0; i < size; i++) {
2143     gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
2144
2145     if (gid == gid_not_found) {
2146       delete[] groups;
2147       return env->ThrowError("group name not found");
2148     }
2149
2150     groups[i] = gid;
2151   }
2152
2153   int rc = setgroups(size, groups);
2154   delete[] groups;
2155
2156   if (rc == -1) {
2157     return env->ThrowErrnoException(errno, "setgroups");
2158   }
2159 }
2160
2161
2162 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
2163   Environment* env = Environment::GetCurrent(args);
2164
2165   if (!args[0]->IsUint32() && !args[0]->IsString()) {
2166     return env->ThrowTypeError("argument 1 must be a number or a string");
2167   }
2168
2169   if (!args[1]->IsUint32() && !args[1]->IsString()) {
2170     return env->ThrowTypeError("argument 2 must be a number or a string");
2171   }
2172
2173   node::Utf8Value arg0(env->isolate(), args[0]);
2174   gid_t extra_group;
2175   bool must_free;
2176   char* user;
2177
2178   if (args[0]->IsUint32()) {
2179     user = name_by_uid(args[0]->Uint32Value());
2180     must_free = true;
2181   } else {
2182     user = *arg0;
2183     must_free = false;
2184   }
2185
2186   if (user == nullptr) {
2187     return env->ThrowError("initgroups user not found");
2188   }
2189
2190   extra_group = gid_by_name(env->isolate(), args[1]);
2191
2192   if (extra_group == gid_not_found) {
2193     if (must_free)
2194       free(user);
2195     return env->ThrowError("initgroups extra group not found");
2196   }
2197
2198   int rc = initgroups(user, extra_group);
2199
2200   if (must_free) {
2201     free(user);
2202   }
2203
2204   if (rc) {
2205     return env->ThrowErrnoException(errno, "initgroups");
2206   }
2207 }
2208
2209 #endif  // __POSIX__ && !defined(__ANDROID__)
2210
2211
2212 static void WaitForInspectorDisconnect(Environment* env) {
2213 #if HAVE_INSPECTOR
2214   if (env->inspector_agent()->IsConnected()) {
2215     // Restore signal dispositions, the app is done and is no longer
2216     // capable of handling signals.
2217 #ifdef __POSIX__
2218     struct sigaction act;
2219     memset(&act, 0, sizeof(act));
2220     for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2221       if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2222         continue;
2223       act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2224       CHECK_EQ(0, sigaction(nr, &act, nullptr));
2225     }
2226 #endif
2227     env->inspector_agent()->WaitForDisconnect();
2228   }
2229 #endif
2230 }
2231
2232
2233 void Exit(const FunctionCallbackInfo<Value>& args) {
2234   WaitForInspectorDisconnect(Environment::GetCurrent(args));
2235   exit(args[0]->Int32Value());
2236 }
2237
2238
2239 static void Uptime(const FunctionCallbackInfo<Value>& args) {
2240   Environment* env = Environment::GetCurrent(args);
2241   double uptime;
2242
2243   uv_update_time(env->event_loop());
2244   uptime = uv_now(env->event_loop()) - prog_start_time;
2245
2246   args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
2247 }
2248
2249
2250 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
2251   Environment* env = Environment::GetCurrent(args);
2252
2253   size_t rss;
2254   int err = uv_resident_set_memory(&rss);
2255   if (err) {
2256     return env->ThrowUVException(err, "uv_resident_set_memory");
2257   }
2258
2259   // V8 memory usage
2260   HeapStatistics v8_heap_stats;
2261   env->isolate()->GetHeapStatistics(&v8_heap_stats);
2262
2263   Local<Number> heap_total =
2264       Number::New(env->isolate(), v8_heap_stats.total_heap_size());
2265   Local<Number> heap_used =
2266       Number::New(env->isolate(), v8_heap_stats.used_heap_size());
2267   Local<Number> external_mem =
2268       Number::New(env->isolate(),
2269                   env->isolate()->AdjustAmountOfExternalAllocatedMemory(0));
2270
2271   Local<Object> info = Object::New(env->isolate());
2272   info->Set(env->rss_string(), Number::New(env->isolate(), rss));
2273   info->Set(env->heap_total_string(), heap_total);
2274   info->Set(env->heap_used_string(), heap_used);
2275   info->Set(env->external_string(), external_mem);
2276
2277   args.GetReturnValue().Set(info);
2278 }
2279
2280
2281 void Kill(const FunctionCallbackInfo<Value>& args) {
2282   Environment* env = Environment::GetCurrent(args);
2283
2284   if (args.Length() != 2) {
2285     return env->ThrowError("Bad argument.");
2286   }
2287
2288   int pid = args[0]->Int32Value();
2289   int sig = args[1]->Int32Value();
2290   int err = uv_kill(pid, sig);
2291   args.GetReturnValue().Set(err);
2292 }
2293
2294 // used in Hrtime() below
2295 #define NANOS_PER_SEC 1000000000
2296
2297 // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2298 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
2299 // so this function instead returns an Array with 2 entries representing seconds
2300 // and nanoseconds, to avoid any integer overflow possibility.
2301 // Pass in an Array from a previous hrtime() call to instead get a time diff.
2302 void Hrtime(const FunctionCallbackInfo<Value>& args) {
2303   uint64_t t = uv_hrtime();
2304
2305   Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2306   uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
2307
2308   // These three indices will contain the values for the hrtime tuple. The
2309   // seconds value is broken into the upper/lower 32 bits and stored in two
2310   // uint32 fields to be converted back in JS.
2311   fields[0] = (t / NANOS_PER_SEC) >> 32;
2312   fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
2313   fields[2] = t % NANOS_PER_SEC;
2314 }
2315
2316 // Microseconds in a second, as a float, used in CPUUsage() below
2317 #define MICROS_PER_SEC 1e6
2318
2319 // CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
2320 // to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
2321 // which are uv_timeval_t structs (long tv_sec, long tv_usec).
2322 // Returns those values as Float64 microseconds in the elements of the array
2323 // passed to the function.
2324 void CPUUsage(const FunctionCallbackInfo<Value>& args) {
2325   uv_rusage_t rusage;
2326
2327   // Call libuv to get the values we'll return.
2328   int err = uv_getrusage(&rusage);
2329   if (err) {
2330     // On error, return the strerror version of the error code.
2331     Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2332     args.GetReturnValue().Set(errmsg);
2333     return;
2334   }
2335
2336   // Get the double array pointer from the Float64Array argument.
2337   CHECK(args[0]->IsFloat64Array());
2338   Local<Float64Array> array = args[0].As<Float64Array>();
2339   CHECK_EQ(array->Length(), 2);
2340   Local<ArrayBuffer> ab = array->Buffer();
2341   double* fields = static_cast<double*>(ab->GetContents().Data());
2342
2343   // Set the Float64Array elements to be user / system values in microseconds.
2344   fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2345   fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2346 }
2347
2348 extern "C" void node_module_register(void* m) {
2349   struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2350
2351   if (mp->nm_flags & NM_F_BUILTIN) {
2352     mp->nm_link = modlist_builtin;
2353     modlist_builtin = mp;
2354   } else if (!node_is_initialized) {
2355     // "Linked" modules are included as part of the node project.
2356     // Like builtins they are registered *before* node::Init runs.
2357     mp->nm_flags = NM_F_LINKED;
2358     mp->nm_link = modlist_linked;
2359     modlist_linked = mp;
2360   } else {
2361     modpending = mp;
2362   }
2363 }
2364
2365 struct node_module* get_builtin_module(const char* name) {
2366   struct node_module* mp;
2367
2368   for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) {
2369     if (strcmp(mp->nm_modname, name) == 0)
2370       break;
2371   }
2372
2373   CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0);
2374   return (mp);
2375 }
2376
2377 struct node_module* get_linked_module(const char* name) {
2378   struct node_module* mp;
2379
2380   for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) {
2381     if (strcmp(mp->nm_modname, name) == 0)
2382       break;
2383   }
2384
2385   CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0);
2386   return mp;
2387 }
2388
2389 typedef void (UV_DYNAMIC* extInit)(Local<Object> exports);
2390
2391 // DLOpen is process.dlopen(module, filename).
2392 // Used to load 'module.node' dynamically shared objects.
2393 //
2394 // FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2395 // when two contexts try to load the same shared object. Maybe have a shadow
2396 // cache that's a plain C list or hash table that's shared across contexts?
2397 void DLOpen(const FunctionCallbackInfo<Value>& args) {
2398   Environment* env = Environment::GetCurrent(args);
2399   uv_lib_t lib;
2400
2401   CHECK_EQ(modpending, nullptr);
2402
2403   if (args.Length() != 2) {
2404     env->ThrowError("process.dlopen takes exactly 2 arguments.");
2405     return;
2406   }
2407
2408   Local<Object> module = args[0]->ToObject(env->isolate());  // Cast
2409   node::Utf8Value filename(env->isolate(), args[1]);  // Cast
2410   const bool is_dlopen_error = uv_dlopen(*filename, &lib);
2411
2412   // Objects containing v14 or later modules will have registered themselves
2413   // on the pending list.  Activate all of them now.  At present, only one
2414   // module per object is supported.
2415   node_module* const mp = modpending;
2416   modpending = nullptr;
2417
2418   if (is_dlopen_error) {
2419     Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
2420     uv_dlclose(&lib);
2421 #ifdef _WIN32
2422     // Windows needs to add the filename into the error message
2423     errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
2424 #endif  // _WIN32
2425     env->isolate()->ThrowException(Exception::Error(errmsg));
2426     return;
2427   }
2428
2429   if (mp == nullptr) {
2430     uv_dlclose(&lib);
2431     env->ThrowError("Module did not self-register.");
2432     return;
2433   }
2434   if (mp->nm_version != NODE_MODULE_VERSION) {
2435     char errmsg[1024];
2436     snprintf(errmsg,
2437              sizeof(errmsg),
2438              "The module '%s'"
2439              "\nwas compiled against a different Node.js version using"
2440              "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
2441              "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
2442              "re-installing\nthe module (for instance, using `npm rebuild` or"
2443              "`npm install`).",
2444              *filename, mp->nm_version, NODE_MODULE_VERSION);
2445
2446     // NOTE: `mp` is allocated inside of the shared library's memory, calling
2447     // `uv_dlclose` will deallocate it
2448     uv_dlclose(&lib);
2449     env->ThrowError(errmsg);
2450     return;
2451   }
2452   if (mp->nm_flags & NM_F_BUILTIN) {
2453     uv_dlclose(&lib);
2454     env->ThrowError("Built-in module self-registered.");
2455     return;
2456   }
2457
2458   mp->nm_dso_handle = lib.handle;
2459   mp->nm_link = modlist_addon;
2460   modlist_addon = mp;
2461
2462   Local<String> exports_string = env->exports_string();
2463   Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2464
2465   if (mp->nm_context_register_func != nullptr) {
2466     mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2467   } else if (mp->nm_register_func != nullptr) {
2468     mp->nm_register_func(exports, module, mp->nm_priv);
2469   } else {
2470     uv_dlclose(&lib);
2471     env->ThrowError("Module has no declared entry point.");
2472     return;
2473   }
2474
2475   // Tell coverity that 'handle' should not be freed when we return.
2476   // coverity[leaked_storage]
2477 }
2478
2479
2480 static void OnFatalError(const char* location, const char* message) {
2481   if (location) {
2482     PrintErrorString("FATAL ERROR: %s %s\n", location, message);
2483   } else {
2484     PrintErrorString("FATAL ERROR: %s\n", message);
2485   }
2486   fflush(stderr);
2487   ABORT();
2488 }
2489
2490
2491 NO_RETURN void FatalError(const char* location, const char* message) {
2492   OnFatalError(location, message);
2493   // to suppress compiler warning
2494   ABORT();
2495 }
2496
2497
2498 void FatalException(Isolate* isolate,
2499                     Local<Value> error,
2500                     Local<Message> message) {
2501   HandleScope scope(isolate);
2502
2503   Environment* env = Environment::GetCurrent(isolate);
2504   Local<Object> process_object = env->process_object();
2505   Local<String> fatal_exception_string = env->fatal_exception_string();
2506   Local<Function> fatal_exception_function =
2507       process_object->Get(fatal_exception_string).As<Function>();
2508
2509   int exit_code = 0;
2510   if (!fatal_exception_function->IsFunction()) {
2511     // failed before the process._fatalException function was added!
2512     // this is probably pretty bad.  Nothing to do but report and exit.
2513     ReportException(env, error, message);
2514     exit_code = 6;
2515   }
2516
2517   if (exit_code == 0) {
2518     TryCatch fatal_try_catch(isolate);
2519
2520     // Do not call FatalException when _fatalException handler throws
2521     fatal_try_catch.SetVerbose(false);
2522
2523     // this will return true if the JS layer handled it, false otherwise
2524     Local<Value> caught =
2525         fatal_exception_function->Call(process_object, 1, &error);
2526
2527     if (fatal_try_catch.HasCaught()) {
2528       // the fatal exception function threw, so we must exit
2529       ReportException(env, fatal_try_catch);
2530       exit_code = 7;
2531     }
2532
2533     if (exit_code == 0 && false == caught->BooleanValue()) {
2534       ReportException(env, error, message);
2535       exit_code = 1;
2536     }
2537   }
2538
2539   if (exit_code) {
2540 #if HAVE_INSPECTOR
2541     if (use_inspector) {
2542       env->inspector_agent()->FatalException(error, message);
2543     }
2544 #endif
2545     exit(exit_code);
2546   }
2547 }
2548
2549
2550 void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2551   HandleScope scope(isolate);
2552   // TODO(bajtos) do not call FatalException if try_catch is verbose
2553   // (requires V8 API to expose getter for try_catch.is_verbose_)
2554   FatalException(isolate, try_catch.Exception(), try_catch.Message());
2555 }
2556
2557
2558 void OnMessage(Local<Message> message, Local<Value> error) {
2559   // The current version of V8 sends messages for errors only
2560   // (thus `error` is always set).
2561   FatalException(Isolate::GetCurrent(), error, message);
2562 }
2563
2564
2565 void ClearFatalExceptionHandlers(Environment* env) {
2566   Local<Object> process = env->process_object();
2567   Local<Value> events =
2568       process->Get(env->context(), env->events_string()).ToLocalChecked();
2569
2570   if (events->IsObject()) {
2571     events.As<Object>()->Set(
2572         env->context(),
2573         OneByteString(env->isolate(), "uncaughtException"),
2574         Undefined(env->isolate())).FromJust();
2575   }
2576
2577   process->Set(
2578       env->context(),
2579       env->domain_string(),
2580       Undefined(env->isolate())).FromJust();
2581 }
2582
2583 // Call process.emitWarning(str), fmt is a snprintf() format string
2584 void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
2585   char warning[1024];
2586   va_list ap;
2587
2588   va_start(ap, fmt);
2589   vsnprintf(warning, sizeof(warning), fmt, ap);
2590   va_end(ap);
2591
2592   HandleScope handle_scope(env->isolate());
2593   Context::Scope context_scope(env->context());
2594
2595   Local<Object> process = env->process_object();
2596   MaybeLocal<Value> emit_warning = process->Get(env->context(),
2597       FIXED_ONE_BYTE_STRING(env->isolate(), "emitWarning"));
2598   Local<Value> arg = node::OneByteString(env->isolate(), warning);
2599
2600   Local<Value> f;
2601
2602   if (!emit_warning.ToLocal(&f)) return;
2603   if (!f->IsFunction()) return;
2604
2605   // MakeCallback() unneeded, because emitWarning is internal code, it calls
2606   // process.emit('warning', ..), but does so on the nextTick.
2607   f.As<v8::Function>()->Call(process, 1, &arg);
2608 }
2609
2610
2611 static void Binding(const FunctionCallbackInfo<Value>& args) {
2612   Environment* env = Environment::GetCurrent(args);
2613
2614   Local<String> module = args[0]->ToString(env->isolate());
2615   node::Utf8Value module_v(env->isolate(), module);
2616
2617   Local<Object> cache = env->binding_cache_object();
2618   Local<Object> exports;
2619
2620   if (cache->Has(env->context(), module).FromJust()) {
2621     exports = cache->Get(module)->ToObject(env->isolate());
2622     args.GetReturnValue().Set(exports);
2623     return;
2624   }
2625
2626   // Append a string to process.moduleLoadList
2627   char buf[1024];
2628   snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2629
2630   Local<Array> modules = env->module_load_list_array();
2631   uint32_t l = modules->Length();
2632   modules->Set(l, OneByteString(env->isolate(), buf));
2633
2634   node_module* mod = get_builtin_module(*module_v);
2635   if (mod != nullptr) {
2636     exports = Object::New(env->isolate());
2637     // Internal bindings don't have a "module" object, only exports.
2638     CHECK_EQ(mod->nm_register_func, nullptr);
2639     CHECK_NE(mod->nm_context_register_func, nullptr);
2640     Local<Value> unused = Undefined(env->isolate());
2641     mod->nm_context_register_func(exports, unused,
2642       env->context(), mod->nm_priv);
2643     cache->Set(module, exports);
2644   } else if (!strcmp(*module_v, "constants")) {
2645     exports = Object::New(env->isolate());
2646     DefineConstants(env->isolate(), exports);
2647     cache->Set(module, exports);
2648   } else if (!strcmp(*module_v, "natives")) {
2649     exports = Object::New(env->isolate());
2650     DefineJavaScript(env, exports);
2651     cache->Set(module, exports);
2652   } else {
2653     char errmsg[1024];
2654     snprintf(errmsg,
2655              sizeof(errmsg),
2656              "No such module: %s",
2657              *module_v);
2658     return env->ThrowError(errmsg);
2659   }
2660
2661   args.GetReturnValue().Set(exports);
2662 }
2663
2664 static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2665   Environment* env = Environment::GetCurrent(args.GetIsolate());
2666
2667   Local<String> module_name = args[0]->ToString(env->isolate());
2668
2669   Local<Object> cache = env->binding_cache_object();
2670   Local<Value> exports_v = cache->Get(module_name);
2671
2672   if (exports_v->IsObject())
2673     return args.GetReturnValue().Set(exports_v.As<Object>());
2674
2675   node::Utf8Value module_name_v(env->isolate(), module_name);
2676   node_module* mod = get_linked_module(*module_name_v);
2677
2678   if (mod == nullptr) {
2679     char errmsg[1024];
2680     snprintf(errmsg,
2681              sizeof(errmsg),
2682              "No such module was linked: %s",
2683              *module_name_v);
2684     return env->ThrowError(errmsg);
2685   }
2686
2687   Local<Object> module = Object::New(env->isolate());
2688   Local<Object> exports = Object::New(env->isolate());
2689   Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
2690   module->Set(exports_prop, exports);
2691
2692   if (mod->nm_context_register_func != nullptr) {
2693     mod->nm_context_register_func(exports,
2694                                   module,
2695                                   env->context(),
2696                                   mod->nm_priv);
2697   } else if (mod->nm_register_func != nullptr) {
2698     mod->nm_register_func(exports, module, mod->nm_priv);
2699   } else {
2700     return env->ThrowError("Linked module has no declared entry point.");
2701   }
2702
2703   auto effective_exports = module->Get(exports_prop);
2704   cache->Set(module_name, effective_exports);
2705
2706   args.GetReturnValue().Set(effective_exports);
2707 }
2708
2709 static void ProcessTitleGetter(Local<Name> property,
2710                                const PropertyCallbackInfo<Value>& info) {
2711   char buffer[512];
2712   uv_get_process_title(buffer, sizeof(buffer));
2713   info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
2714 }
2715
2716
2717 static void ProcessTitleSetter(Local<Name> property,
2718                                Local<Value> value,
2719                                const PropertyCallbackInfo<void>& info) {
2720   node::Utf8Value title(info.GetIsolate(), value);
2721   // TODO(piscisaureus): protect with a lock
2722   uv_set_process_title(*title);
2723 }
2724
2725
2726 static void EnvGetter(Local<Name> property,
2727                       const PropertyCallbackInfo<Value>& info) {
2728   Isolate* isolate = info.GetIsolate();
2729 #ifdef __POSIX__
2730   node::Utf8Value key(isolate, property);
2731   const char* val = getenv(*key);
2732   if (val) {
2733     return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
2734   }
2735 #else  // _WIN32
2736   String::Value key(property);
2737   WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2738   DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2739                                          buffer,
2740                                          arraysize(buffer));
2741   // If result >= sizeof buffer the buffer was too small. That should never
2742   // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2743   // not found.
2744   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2745       result < arraysize(buffer)) {
2746     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2747     Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
2748     return info.GetReturnValue().Set(rc);
2749   }
2750 #endif
2751 }
2752
2753
2754 static void EnvSetter(Local<Name> property,
2755                       Local<Value> value,
2756                       const PropertyCallbackInfo<Value>& info) {
2757 #ifdef __POSIX__
2758   node::Utf8Value key(info.GetIsolate(), property);
2759   node::Utf8Value val(info.GetIsolate(), value);
2760   setenv(*key, *val, 1);
2761 #else  // _WIN32
2762   String::Value key(property);
2763   String::Value val(value);
2764   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2765   // Environment variables that start with '=' are read-only.
2766   if (key_ptr[0] != L'=') {
2767     SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2768   }
2769 #endif
2770   // Whether it worked or not, always return value.
2771   info.GetReturnValue().Set(value);
2772 }
2773
2774
2775 static void EnvQuery(Local<Name> property,
2776                      const PropertyCallbackInfo<Integer>& info) {
2777   int32_t rc = -1;  // Not found unless proven otherwise.
2778 #ifdef __POSIX__
2779   node::Utf8Value key(info.GetIsolate(), property);
2780   if (getenv(*key))
2781     rc = 0;
2782 #else  // _WIN32
2783   String::Value key(property);
2784   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2785   if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2786       GetLastError() == ERROR_SUCCESS) {
2787     rc = 0;
2788     if (key_ptr[0] == L'=') {
2789       // Environment variables that start with '=' are hidden and read-only.
2790       rc = static_cast<int32_t>(v8::ReadOnly) |
2791            static_cast<int32_t>(v8::DontDelete) |
2792            static_cast<int32_t>(v8::DontEnum);
2793     }
2794   }
2795 #endif
2796   if (rc != -1)
2797     info.GetReturnValue().Set(rc);
2798 }
2799
2800
2801 static void EnvDeleter(Local<Name> property,
2802                        const PropertyCallbackInfo<Boolean>& info) {
2803 #ifdef __POSIX__
2804   node::Utf8Value key(info.GetIsolate(), property);
2805   unsetenv(*key);
2806 #else
2807   String::Value key(property);
2808   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2809   SetEnvironmentVariableW(key_ptr, nullptr);
2810 #endif
2811
2812   // process.env never has non-configurable properties, so always
2813   // return true like the tc39 delete operator.
2814   info.GetReturnValue().Set(true);
2815 }
2816
2817
2818 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2819   Environment* env = Environment::GetCurrent(info);
2820   Isolate* isolate = env->isolate();
2821   Local<Context> ctx = env->context();
2822   Local<Function> fn = env->push_values_to_array_function();
2823   Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2824   size_t idx = 0;
2825
2826 #ifdef __POSIX__
2827   int size = 0;
2828   while (environ[size])
2829     size++;
2830
2831   Local<Array> envarr = Array::New(isolate);
2832
2833   for (int i = 0; i < size; ++i) {
2834     const char* var = environ[i];
2835     const char* s = strchr(var, '=');
2836     const int length = s ? s - var : strlen(var);
2837     argv[idx] = String::NewFromUtf8(isolate,
2838                                     var,
2839                                     String::kNormalString,
2840                                     length);
2841     if (++idx >= arraysize(argv)) {
2842       fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2843       idx = 0;
2844     }
2845   }
2846   if (idx > 0) {
2847     fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2848   }
2849 #else  // _WIN32
2850   WCHAR* environment = GetEnvironmentStringsW();
2851   if (environment == nullptr)
2852     return;  // This should not happen.
2853   Local<Array> envarr = Array::New(isolate);
2854   WCHAR* p = environment;
2855   while (*p) {
2856     WCHAR *s;
2857     if (*p == L'=') {
2858       // If the key starts with '=' it is a hidden environment variable.
2859       p += wcslen(p) + 1;
2860       continue;
2861     } else {
2862       s = wcschr(p, L'=');
2863     }
2864     if (!s) {
2865       s = p + wcslen(p);
2866     }
2867     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2868     const size_t two_byte_buffer_len = s - p;
2869     argv[idx] = String::NewFromTwoByte(isolate,
2870                                        two_byte_buffer,
2871                                        String::kNormalString,
2872                                        two_byte_buffer_len);
2873     if (++idx >= arraysize(argv)) {
2874       fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2875       idx = 0;
2876     }
2877     p = s + wcslen(s) + 1;
2878   }
2879   if (idx > 0) {
2880     fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2881   }
2882   FreeEnvironmentStringsW(environment);
2883 #endif
2884
2885   info.GetReturnValue().Set(envarr);
2886 }
2887
2888
2889 static Local<Object> GetFeatures(Environment* env) {
2890   EscapableHandleScope scope(env->isolate());
2891
2892   Local<Object> obj = Object::New(env->isolate());
2893 #if defined(DEBUG) && DEBUG
2894   Local<Value> debug = True(env->isolate());
2895 #else
2896   Local<Value> debug = False(env->isolate());
2897 #endif  // defined(DEBUG) && DEBUG
2898
2899   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
2900   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
2901   // TODO(bnoordhuis) ping libuv
2902   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
2903
2904 #ifdef OPENSSL_NPN_NEGOTIATED
2905   Local<Boolean> tls_npn = True(env->isolate());
2906 #else
2907   Local<Boolean> tls_npn = False(env->isolate());
2908 #endif
2909   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
2910
2911 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2912   Local<Boolean> tls_alpn = True(env->isolate());
2913 #else
2914   Local<Boolean> tls_alpn = False(env->isolate());
2915 #endif
2916   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn);
2917
2918 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2919   Local<Boolean> tls_sni = True(env->isolate());
2920 #else
2921   Local<Boolean> tls_sni = False(env->isolate());
2922 #endif
2923   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni);
2924
2925 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2926   Local<Boolean> tls_ocsp = True(env->isolate());
2927 #else
2928   Local<Boolean> tls_ocsp = False(env->isolate());
2929 #endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2930   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp);
2931
2932   obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"),
2933            Boolean::New(env->isolate(),
2934                         get_builtin_module("crypto") != nullptr));
2935
2936   return scope.Escape(obj);
2937 }
2938
2939
2940 static void DebugPortGetter(Local<Name> property,
2941                             const PropertyCallbackInfo<Value>& info) {
2942   int port = debug_port;
2943   if (port < 0)
2944     port = use_inspector ? default_inspector_port : default_debugger_port;
2945   info.GetReturnValue().Set(port);
2946 }
2947
2948
2949 static void DebugPortSetter(Local<Name> property,
2950                             Local<Value> value,
2951                             const PropertyCallbackInfo<void>& info) {
2952   debug_port = value->Int32Value();
2953 }
2954
2955
2956 static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2957 static void DebugPause(const FunctionCallbackInfo<Value>& args);
2958 static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2959
2960
2961 void NeedImmediateCallbackGetter(Local<Name> property,
2962                                  const PropertyCallbackInfo<Value>& info) {
2963   Environment* env = Environment::GetCurrent(info);
2964   const uv_check_t* immediate_check_handle = env->immediate_check_handle();
2965   bool active = uv_is_active(
2966       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2967   info.GetReturnValue().Set(active);
2968 }
2969
2970
2971 static void NeedImmediateCallbackSetter(
2972     Local<Name> property,
2973     Local<Value> value,
2974     const PropertyCallbackInfo<void>& info) {
2975   Environment* env = Environment::GetCurrent(info);
2976
2977   uv_check_t* immediate_check_handle = env->immediate_check_handle();
2978   bool active = uv_is_active(
2979       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2980
2981   if (active == value->BooleanValue())
2982     return;
2983
2984   uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
2985
2986   if (active) {
2987     uv_check_stop(immediate_check_handle);
2988     uv_idle_stop(immediate_idle_handle);
2989   } else {
2990     uv_check_start(immediate_check_handle, CheckImmediate);
2991     // Idle handle is needed only to stop the event loop from blocking in poll.
2992     uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
2993   }
2994 }
2995
2996
2997 void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2998   Environment* env = Environment::GetCurrent(args);
2999   env->StartProfilerIdleNotifier();
3000 }
3001
3002
3003 void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
3004   Environment* env = Environment::GetCurrent(args);
3005   env->StopProfilerIdleNotifier();
3006 }
3007
3008
3009 #define READONLY_PROPERTY(obj, str, var)                                      \
3010   do {                                                                        \
3011     obj->DefineOwnProperty(env->context(),                                    \
3012                            OneByteString(env->isolate(), str),                \
3013                            var,                                               \
3014                            v8::ReadOnly).FromJust();                          \
3015   } while (0)
3016
3017 #define READONLY_DONT_ENUM_PROPERTY(obj, str, var)                            \
3018   do {                                                                        \
3019     obj->DefineOwnProperty(env->context(),                                    \
3020                            OneByteString(env->isolate(), str),                \
3021                            var,                                               \
3022                            static_cast<v8::PropertyAttribute>(v8::ReadOnly |  \
3023                                                               v8::DontEnum))  \
3024         .FromJust();                                                          \
3025   } while (0)
3026
3027
3028 void SetupProcessObject(Environment* env,
3029                         int argc,
3030                         const char* const* argv,
3031                         int exec_argc,
3032                         const char* const* exec_argv) {
3033   HandleScope scope(env->isolate());
3034
3035   Local<Object> process = env->process_object();
3036
3037   auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
3038   CHECK(process->SetAccessor(env->context(),
3039                              title_string,
3040                              ProcessTitleGetter,
3041                              ProcessTitleSetter,
3042                              env->as_external()).FromJust());
3043
3044   // process.version
3045   READONLY_PROPERTY(process,
3046                     "version",
3047                     FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
3048
3049   // process.moduleLoadList
3050   READONLY_PROPERTY(process,
3051                     "moduleLoadList",
3052                     env->module_load_list_array());
3053
3054   // process.versions
3055   Local<Object> versions = Object::New(env->isolate());
3056   READONLY_PROPERTY(process, "versions", versions);
3057
3058   const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3059                                      "."
3060                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
3061                                      "."
3062                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
3063   READONLY_PROPERTY(versions,
3064                     "http_parser",
3065                     FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
3066
3067   // +1 to get rid of the leading 'v'
3068   READONLY_PROPERTY(versions,
3069                     "node",
3070                     OneByteString(env->isolate(), NODE_VERSION + 1));
3071   READONLY_PROPERTY(versions,
3072                     "v8",
3073                     OneByteString(env->isolate(), V8::GetVersion()));
3074   READONLY_PROPERTY(versions,
3075                     "uv",
3076                     OneByteString(env->isolate(), uv_version_string()));
3077   READONLY_PROPERTY(versions,
3078                     "zlib",
3079                     FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
3080   READONLY_PROPERTY(versions,
3081                     "ares",
3082                     FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
3083
3084 #if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
3085   // ICU-related versions are now handled on the js side, see bootstrap_node.js
3086
3087   if (icu_data_dir != nullptr) {
3088     // Did the user attempt (via env var or parameter) to set an ICU path?
3089     READONLY_PROPERTY(process,
3090                       "icu_data_dir",
3091                       OneByteString(env->isolate(), icu_data_dir));
3092   }
3093 #endif
3094
3095   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
3096   READONLY_PROPERTY(
3097       versions,
3098       "modules",
3099       FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
3100
3101   // process._promiseRejectEvent
3102   Local<Object> promiseRejectEvent = Object::New(env->isolate());
3103   READONLY_DONT_ENUM_PROPERTY(process,
3104                               "_promiseRejectEvent",
3105                               promiseRejectEvent);
3106   READONLY_PROPERTY(promiseRejectEvent,
3107                     "unhandled",
3108                     Integer::New(env->isolate(),
3109                                  v8::kPromiseRejectWithNoHandler));
3110   READONLY_PROPERTY(promiseRejectEvent,
3111                     "handled",
3112                     Integer::New(env->isolate(),
3113                                  v8::kPromiseHandlerAddedAfterReject));
3114
3115 #if HAVE_OPENSSL
3116   // Stupid code to slice out the version string.
3117   {  // NOLINT(whitespace/braces)
3118     size_t i, j, k;
3119     int c;
3120     for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3121       c = OPENSSL_VERSION_TEXT[i];
3122       if ('0' <= c && c <= '9') {
3123         for (j = i + 1; j < k; ++j) {
3124           c = OPENSSL_VERSION_TEXT[j];
3125           if (c == ' ')
3126             break;
3127         }
3128         break;
3129       }
3130     }
3131     READONLY_PROPERTY(
3132         versions,
3133         "openssl",
3134         OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
3135   }
3136 #endif
3137
3138   // process.arch
3139   READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
3140
3141   // process.platform
3142   READONLY_PROPERTY(process,
3143                     "platform",
3144                     OneByteString(env->isolate(), NODE_PLATFORM));
3145
3146   // process.release
3147   Local<Object> release = Object::New(env->isolate());
3148   READONLY_PROPERTY(process, "release", release);
3149   READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node"));
3150
3151 // if this is a release build and no explicit base has been set
3152 // substitute the standard release download URL
3153 #ifndef NODE_RELEASE_URLBASE
3154 # if NODE_VERSION_IS_RELEASE
3155 #  define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
3156 # endif
3157 #endif
3158
3159 #if defined(NODE_RELEASE_URLBASE)
3160 #  define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
3161 #  define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
3162
3163   READONLY_PROPERTY(release,
3164                     "sourceUrl",
3165                     OneByteString(env->isolate(),
3166                     NODE_RELEASE_URLFPFX ".tar.gz"));
3167   READONLY_PROPERTY(release,
3168                     "headersUrl",
3169                     OneByteString(env->isolate(),
3170                     NODE_RELEASE_URLFPFX "-headers.tar.gz"));
3171 #  ifdef _WIN32
3172   READONLY_PROPERTY(release,
3173                     "libUrl",
3174                     OneByteString(env->isolate(),
3175                     strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
3176                                                 NODE_ARCH "/node.lib"
3177                                               : NODE_RELEASE_URLPFX
3178                                                 "win-x86/node.lib"));
3179 #  endif
3180 #endif
3181
3182   // process.argv
3183   Local<Array> arguments = Array::New(env->isolate(), argc);
3184   for (int i = 0; i < argc; ++i) {
3185     arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
3186   }
3187   process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
3188
3189   // process.execArgv
3190   Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
3191   for (int i = 0; i < exec_argc; ++i) {
3192     exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
3193   }
3194   process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
3195                exec_arguments);
3196
3197   // create process.env
3198   Local<ObjectTemplate> process_env_template =
3199       ObjectTemplate::New(env->isolate());
3200   process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3201           EnvGetter,
3202           EnvSetter,
3203           EnvQuery,
3204           EnvDeleter,
3205           EnvEnumerator,
3206           env->as_external(),
3207           PropertyHandlerFlags::kOnlyInterceptStrings));
3208
3209   Local<Object> process_env =
3210       process_env_template->NewInstance(env->context()).ToLocalChecked();
3211   process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
3212
3213   READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
3214   READONLY_PROPERTY(process, "features", GetFeatures(env));
3215
3216   auto need_immediate_callback_string =
3217       FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback");
3218   CHECK(process->SetAccessor(env->context(), need_immediate_callback_string,
3219                              NeedImmediateCallbackGetter,
3220                              NeedImmediateCallbackSetter,
3221                              env->as_external()).FromJust());
3222
3223   // -e, --eval
3224   if (eval_string) {
3225     READONLY_PROPERTY(process,
3226                       "_eval",
3227                       String::NewFromUtf8(env->isolate(), eval_string));
3228   }
3229
3230   // -p, --print
3231   if (print_eval) {
3232     READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
3233   }
3234
3235   // -c, --check
3236   if (syntax_check_only) {
3237     READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
3238   }
3239
3240   // -i, --interactive
3241   if (force_repl) {
3242     READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
3243   }
3244
3245   if (preload_module_count) {
3246     CHECK(preload_modules);
3247     Local<Array> array = Array::New(env->isolate());
3248     for (unsigned int i = 0; i < preload_module_count; ++i) {
3249       Local<String> module = String::NewFromUtf8(env->isolate(),
3250                                                  preload_modules[i]);
3251       array->Set(i, module);
3252     }
3253     READONLY_PROPERTY(process,
3254                       "_preload_modules",
3255                       array);
3256
3257     delete[] preload_modules;
3258     preload_modules = nullptr;
3259     preload_module_count = 0;
3260   }
3261
3262   // --no-deprecation
3263   if (no_deprecation) {
3264     READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
3265   }
3266
3267   if (no_process_warnings) {
3268     READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
3269   }
3270
3271   if (trace_warnings) {
3272     READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate()));
3273   }
3274
3275   // --throw-deprecation
3276   if (throw_deprecation) {
3277     READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
3278   }
3279
3280 #ifdef NODE_NO_BROWSER_GLOBALS
3281   // configure --no-browser-globals
3282   READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate()));
3283 #endif  // NODE_NO_BROWSER_GLOBALS
3284
3285   // --prof-process
3286   if (prof_process) {
3287     READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
3288   }
3289
3290   // --trace-deprecation
3291   if (trace_deprecation) {
3292     READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
3293   }
3294
3295   // --debug-brk
3296   if (debug_wait_connect) {
3297     READONLY_PROPERTY(process, "_debugWaitConnect", True(env->isolate()));
3298   }
3299
3300   // --security-revert flags
3301 #define V(code, _, __)                                                        \
3302   do {                                                                        \
3303     if (IsReverted(REVERT_ ## code)) {                                        \
3304       READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate()));      \
3305     }                                                                         \
3306   } while (0);
3307   REVERSIONS(V)
3308 #undef V
3309
3310   size_t exec_path_len = 2 * PATH_MAX;
3311   char* exec_path = new char[exec_path_len];
3312   Local<String> exec_path_value;
3313   if (uv_exepath(exec_path, &exec_path_len) == 0) {
3314     exec_path_value = String::NewFromUtf8(env->isolate(),
3315                                           exec_path,
3316                                           String::kNormalString,
3317                                           exec_path_len);
3318   } else {
3319     exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
3320   }
3321   process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"),
3322                exec_path_value);
3323   delete[] exec_path;
3324
3325   auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort");
3326   CHECK(process->SetAccessor(env->context(),
3327                              debug_port_string,
3328                              DebugPortGetter,
3329                              DebugPortSetter,
3330                              env->as_external()).FromJust());
3331
3332   // define various internal methods
3333   env->SetMethod(process,
3334                  "_startProfilerIdleNotifier",
3335                  StartProfilerIdleNotifier);
3336   env->SetMethod(process,
3337                  "_stopProfilerIdleNotifier",
3338                  StopProfilerIdleNotifier);
3339   env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
3340   env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
3341   env->SetMethod(process, "reallyExit", Exit);
3342   env->SetMethod(process, "abort", Abort);
3343   env->SetMethod(process, "chdir", Chdir);
3344   env->SetMethod(process, "cwd", Cwd);
3345
3346   env->SetMethod(process, "umask", Umask);
3347
3348 #if defined(__POSIX__) && !defined(__ANDROID__)
3349   env->SetMethod(process, "getuid", GetUid);
3350   env->SetMethod(process, "geteuid", GetEUid);
3351   env->SetMethod(process, "setuid", SetUid);
3352   env->SetMethod(process, "seteuid", SetEUid);
3353
3354   env->SetMethod(process, "setgid", SetGid);
3355   env->SetMethod(process, "setegid", SetEGid);
3356   env->SetMethod(process, "getgid", GetGid);
3357   env->SetMethod(process, "getegid", GetEGid);
3358
3359   env->SetMethod(process, "getgroups", GetGroups);
3360   env->SetMethod(process, "setgroups", SetGroups);
3361   env->SetMethod(process, "initgroups", InitGroups);
3362 #endif  // __POSIX__ && !defined(__ANDROID__)
3363
3364   env->SetMethod(process, "_kill", Kill);
3365
3366   env->SetMethod(process, "_debugProcess", DebugProcess);
3367   env->SetMethod(process, "_debugPause", DebugPause);
3368   env->SetMethod(process, "_debugEnd", DebugEnd);
3369
3370   env->SetMethod(process, "hrtime", Hrtime);
3371
3372   env->SetMethod(process, "cpuUsage", CPUUsage);
3373
3374   env->SetMethod(process, "dlopen", DLOpen);
3375
3376   env->SetMethod(process, "uptime", Uptime);
3377   env->SetMethod(process, "memoryUsage", MemoryUsage);
3378
3379   env->SetMethod(process, "binding", Binding);
3380   env->SetMethod(process, "_linkedBinding", LinkedBinding);
3381
3382   env->SetMethod(process, "_setupProcessObject", SetupProcessObject);
3383   env->SetMethod(process, "_setupNextTick", SetupNextTick);
3384   env->SetMethod(process, "_setupPromises", SetupPromises);
3385   env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
3386
3387   // pre-set _events object for faster emit checks
3388   Local<Object> events_obj = Object::New(env->isolate());
3389   CHECK(events_obj->SetPrototype(env->context(),
3390                                  Null(env->isolate())).FromJust());
3391   process->Set(env->events_string(), events_obj);
3392 }
3393
3394
3395 #undef READONLY_PROPERTY
3396
3397
3398 void SignalExit(int signo) {
3399   uv_tty_reset_mode();
3400 #ifdef __FreeBSD__
3401   // FreeBSD has a nasty bug, see RegisterSignalHandler for details
3402   struct sigaction sa;
3403   memset(&sa, 0, sizeof(sa));
3404   sa.sa_handler = SIG_DFL;
3405   CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
3406 #endif
3407   raise(signo);
3408 }
3409
3410
3411 // Most of the time, it's best to use `console.error` to write
3412 // to the process.stderr stream.  However, in some cases, such as
3413 // when debugging the stream.Writable class or the process.nextTick
3414 // function, it is useful to bypass JavaScript entirely.
3415 static void RawDebug(const FunctionCallbackInfo<Value>& args) {
3416   CHECK(args.Length() == 1 && args[0]->IsString() &&
3417         "must be called with a single string");
3418   node::Utf8Value message(args.GetIsolate(), args[0]);
3419   PrintErrorString("%s\n", *message);
3420   fflush(stderr);
3421 }
3422
3423
3424 void LoadEnvironment(Environment* env) {
3425   if (g_standalone_mode) {
3426     env->isolate()->AddMessageListener(OnMessage);
3427   }
3428   if (g_upstream_node_mode) {
3429     env->isolate()->SetFatalErrorHandler(OnFatalError);
3430   }
3431
3432   HandleScope handle_scope(env->isolate());
3433
3434   TryCatch try_catch(env->isolate());
3435
3436   // Disable verbose mode to stop FatalException() handler from trying
3437   // to handle the exception. Errors this early in the start-up phase
3438   // are not safe to ignore.
3439   try_catch.SetVerbose(false);
3440
3441   // Execute the lib/internal/bootstrap_node.js file which was included as a
3442   // static C string in node_natives.h by node_js2c.
3443   // 'internal_bootstrap_node_native' is the string containing that source code.
3444   Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),
3445                                                     "bootstrap_node.js");
3446   Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
3447   if (try_catch.HasCaught())  {
3448     ReportException(env, try_catch);
3449     exit(10);
3450   }
3451   // The bootstrap_node.js file returns a function 'f'
3452   CHECK(f_value->IsFunction());
3453   Local<Function> f = Local<Function>::Cast(f_value);
3454
3455   // Add a reference to the global object
3456   Local<Object> global = env->context()->Global();
3457
3458 #if defined HAVE_DTRACE || defined HAVE_ETW
3459   InitDTrace(env, global);
3460 #endif
3461
3462 #if defined HAVE_LTTNG
3463   InitLTTNG(env, global);
3464 #endif
3465
3466 #if defined HAVE_PERFCTR
3467   InitPerfCounters(env, global);
3468 #endif
3469
3470   // Enable handling of uncaught exceptions
3471   // (FatalException(), break on uncaught exception in debugger)
3472   //
3473   // This is not strictly necessary since it's almost impossible
3474   // to attach the debugger fast enought to break on exception
3475   // thrown during process startup.
3476   try_catch.SetVerbose(true);
3477
3478   env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
3479
3480   // Expose the global object as a property on itself
3481   // (Allows you to set stuff on `global` from anywhere in JavaScript.)
3482   global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
3483
3484   // Now we call 'f' with the 'process' variable that we've built up with
3485   // all our bindings. Inside bootstrap_node.js and internal/process we'll
3486   // take care of assigning things to their places.
3487
3488   // We start the process this way in order to be more modular. Developers
3489   // who do not like how bootstrap_node.js sets up the module system but do
3490   // like Node's I/O bindings may want to replace 'f' with their own function.
3491   Local<Value> arg = env->process_object();
3492   f->Call(Null(env->isolate()), 1, &arg);
3493 }
3494
3495
3496 static void PrintHelp();
3497
3498 static bool ParseDebugOpt(const char* arg) {
3499   const char* port = nullptr;
3500
3501   if (!strcmp(arg, "--debug")) {
3502     use_debug_agent = true;
3503   } else if (!strncmp(arg, "--debug=", sizeof("--debug=") - 1)) {
3504     use_debug_agent = true;
3505     port = arg + sizeof("--debug=") - 1;
3506   } else if (!strcmp(arg, "--debug-brk")) {
3507     use_debug_agent = true;
3508     debug_wait_connect = true;
3509   } else if (!strncmp(arg, "--debug-brk=", sizeof("--debug-brk=") - 1)) {
3510     use_debug_agent = true;
3511     debug_wait_connect = true;
3512     port = arg + sizeof("--debug-brk=") - 1;
3513   } else if (!strncmp(arg, "--debug-port=", sizeof("--debug-port=") - 1)) {
3514     // XXX(bnoordhuis) Misnomer, configures port and listen address.
3515     port = arg + sizeof("--debug-port=") - 1;
3516 #if HAVE_INSPECTOR
3517   // Specifying both --inspect and --debug means debugging is on, using Chromium
3518   // inspector.
3519   } else if (!strcmp(arg, "--inspect")) {
3520     use_debug_agent = true;
3521     use_inspector = true;
3522   } else if (!strncmp(arg, "--inspect=", sizeof("--inspect=") - 1)) {
3523     use_debug_agent = true;
3524     use_inspector = true;
3525     port = arg + sizeof("--inspect=") - 1;
3526 #else
3527   } else if (!strncmp(arg, "--inspect", sizeof("--inspect") - 1)) {
3528     fprintf(stderr,
3529             "Inspector support is not available with this Node.js build\n");
3530     return false;
3531 #endif
3532   } else {
3533     return false;
3534   }
3535
3536   if (port == nullptr) {
3537     return true;
3538   }
3539
3540   // FIXME(bnoordhuis) Move IPv6 address parsing logic to lib/net.js.
3541   // It seems reasonable to support [address]:port notation
3542   // in net.Server#listen() and net.Socket#connect().
3543   const size_t port_len = strlen(port);
3544   if (port[0] == '[' && port[port_len - 1] == ']') {
3545     debug_host = new std::string(port + 1, port_len - 2);
3546     return true;
3547   }
3548
3549   const char* const colon = strrchr(port, ':');
3550   if (colon == nullptr) {
3551     // Either a port number or a host name.  Assume that
3552     // if it's not all decimal digits, it's a host name.
3553     for (size_t n = 0; port[n] != '\0'; n += 1) {
3554       if (port[n] < '0' || port[n] > '9') {
3555         debug_host = new std::string(port);
3556         return true;
3557       }
3558     }
3559   } else {
3560     const bool skip = (colon > port && port[0] == '[' && colon[-1] == ']');
3561     debug_host = new std::string(port + skip, colon - skip);
3562   }
3563
3564   char* endptr;
3565   errno = 0;
3566   const char* const digits = colon != nullptr ? colon + 1 : port;
3567   const long result = strtol(digits, &endptr, 10);  // NOLINT(runtime/int)
3568   if (errno != 0 || *endptr != '\0' || result < 1024 || result > 65535) {
3569     fprintf(stderr, "Debug port must be in range 1024 to 65535.\n");
3570     PrintHelp();
3571     exit(12);
3572   }
3573
3574   debug_port = static_cast<int>(result);
3575
3576   return true;
3577 }
3578
3579 static void PrintHelp() {
3580   // XXX: If you add an option here, please also add it to doc/node.1 and
3581   // doc/api/cli.md
3582   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
3583          "       node debug script.js [arguments] \n"
3584          "\n"
3585          "Options:\n"
3586          "  -v, --version         print Node.js version\n"
3587          "  -e, --eval script     evaluate script\n"
3588          "  -p, --print           evaluate script and print result\n"
3589          "  -c, --check           syntax check script without executing\n"
3590          "  -i, --interactive     always enter the REPL even if stdin\n"
3591          "                        does not appear to be a terminal\n"
3592          "  -r, --require         module to preload (option can be repeated)\n"
3593          "  --no-deprecation      silence deprecation warnings\n"
3594          "  --trace-deprecation   show stack traces on deprecations\n"
3595          "  --throw-deprecation   throw an exception anytime a deprecated "
3596          "function is used\n"
3597          "  --no-warnings         silence all process warnings\n"
3598          "  --trace-warnings      show stack traces on process warnings\n"
3599          "  --trace-sync-io       show stack trace when use of sync IO\n"
3600          "                        is detected after the first tick\n"
3601          "  --track-heap-objects  track heap object allocations for heap "
3602          "snapshots\n"
3603          "  --prof-process        process v8 profiler output generated\n"
3604          "                        using --prof\n"
3605          "  --zero-fill-buffers   automatically zero-fill all newly allocated\n"
3606          "                        Buffer and SlowBuffer instances\n"
3607          "  --v8-options          print v8 command line options\n"
3608          "  --v8-pool-size=num    set v8's thread pool size\n"
3609 #if HAVE_OPENSSL
3610          "  --tls-cipher-list=val use an alternative default TLS cipher list\n"
3611 #if NODE_FIPS_MODE
3612          "  --enable-fips         enable FIPS crypto at startup\n"
3613          "  --force-fips          force FIPS crypto (cannot be disabled)\n"
3614 #endif  /* NODE_FIPS_MODE */
3615          "  --openssl-config=path load OpenSSL configuration file from the\n"
3616          "                        specified path\n"
3617 #endif /* HAVE_OPENSSL */
3618 #if defined(NODE_HAVE_I18N_SUPPORT)
3619          "  --icu-data-dir=dir    set ICU data load path to dir\n"
3620          "                        (overrides NODE_ICU_DATA)\n"
3621 #if !defined(NODE_HAVE_SMALL_ICU)
3622          "                        note: linked-in ICU data is\n"
3623          "                        present.\n"
3624 #endif
3625          "  --preserve-symlinks   preserve symbolic links when resolving\n"
3626          "                        and caching modules.\n"
3627 #endif
3628          "\n"
3629          "Environment variables:\n"
3630 #ifdef _WIN32
3631          "NODE_PATH                ';'-separated list of directories\n"
3632 #else
3633          "NODE_PATH                ':'-separated list of directories\n"
3634 #endif
3635          "                         prefixed to the module search path.\n"
3636          "NODE_DISABLE_COLORS      set to 1 to disable colors in the REPL\n"
3637 #if defined(NODE_HAVE_I18N_SUPPORT)
3638          "NODE_ICU_DATA            data path for ICU (Intl object) data\n"
3639 #if !defined(NODE_HAVE_SMALL_ICU)
3640          "                         (will extend linked-in data)\n"
3641 #endif
3642 #endif
3643          "NODE_REPL_HISTORY        path to the persistent REPL history file\n"
3644          "\n"
3645          "Documentation can be found at https://nodejs.org/\n");
3646 }
3647
3648
3649 // Parse command line arguments.
3650 //
3651 // argv is modified in place. exec_argv and v8_argv are out arguments that
3652 // ParseArgs() allocates memory for and stores a pointer to the output
3653 // vector in.  The caller should free them with delete[].
3654 //
3655 // On exit:
3656 //
3657 //  * argv contains the arguments with node and V8 options filtered out.
3658 //  * exec_argv contains both node and V8 options and nothing else.
3659 //  * v8_argv contains argv[0] plus any V8 options
3660 static void ParseArgs(int* argc,
3661                       const char** argv,
3662                       int* exec_argc,
3663                       const char*** exec_argv,
3664                       int* v8_argc,
3665                       const char*** v8_argv) {
3666   const unsigned int nargs = static_cast<unsigned int>(*argc);
3667   const char** new_exec_argv = new const char*[nargs];
3668   const char** new_v8_argv = new const char*[nargs];
3669   const char** new_argv = new const char*[nargs];
3670   const char** local_preload_modules = new const char*[nargs];
3671
3672   for (unsigned int i = 0; i < nargs; ++i) {
3673     new_exec_argv[i] = nullptr;
3674     new_v8_argv[i] = nullptr;
3675     new_argv[i] = nullptr;
3676     local_preload_modules[i] = nullptr;
3677   }
3678
3679   // exec_argv starts with the first option, the other two start with argv[0].
3680   unsigned int new_exec_argc = 0;
3681   unsigned int new_v8_argc = 1;
3682   unsigned int new_argc = 1;
3683   new_v8_argv[0] = argv[0];
3684   new_argv[0] = argv[0];
3685
3686   unsigned int index = 1;
3687   bool short_circuit = false;
3688   while (index < nargs && argv[index][0] == '-' && !short_circuit) {
3689     const char* const arg = argv[index];
3690     unsigned int args_consumed = 1;
3691
3692     if (ParseDebugOpt(arg)) {
3693       // Done, consumed by ParseDebugOpt().
3694     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3695       printf("%s\n", NODE_VERSION);
3696       exit(0);
3697     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3698       PrintHelp();
3699       exit(0);
3700     } else if (strcmp(arg, "--eval") == 0 ||
3701                strcmp(arg, "-e") == 0 ||
3702                strcmp(arg, "--print") == 0 ||
3703                strcmp(arg, "-pe") == 0 ||
3704                strcmp(arg, "-p") == 0) {
3705       bool is_eval = strchr(arg, 'e') != nullptr;
3706       bool is_print = strchr(arg, 'p') != nullptr;
3707       print_eval = print_eval || is_print;
3708       // --eval, -e and -pe always require an argument.
3709       if (is_eval == true) {
3710         args_consumed += 1;
3711         eval_string = argv[index + 1];
3712         if (eval_string == nullptr) {
3713           fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3714           exit(9);
3715         }
3716       } else if ((index + 1 < nargs) &&
3717                  argv[index + 1] != nullptr &&
3718                  argv[index + 1][0] != '-') {
3719         args_consumed += 1;
3720         eval_string = argv[index + 1];
3721         if (strncmp(eval_string, "\\-", 2) == 0) {
3722           // Starts with "\\-": escaped expression, drop the backslash.
3723           eval_string += 1;
3724         }
3725       }
3726     } else if (strcmp(arg, "--require") == 0 ||
3727                strcmp(arg, "-r") == 0) {
3728       const char* module = argv[index + 1];
3729       if (module == nullptr) {
3730         fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3731         exit(9);
3732       }
3733       args_consumed += 1;
3734       local_preload_modules[preload_module_count++] = module;
3735     } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3736       syntax_check_only = true;
3737     } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3738       force_repl = true;
3739     } else if (strcmp(arg, "--no-deprecation") == 0) {
3740       no_deprecation = true;
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;
3745     } else if (strcmp(arg, "--trace-deprecation") == 0) {
3746       trace_deprecation = true;
3747     } else if (strcmp(arg, "--trace-sync-io") == 0) {
3748       trace_sync_io = true;
3749     } else if (strcmp(arg, "--track-heap-objects") == 0) {
3750       track_heap_objects = true;
3751     } else if (strcmp(arg, "--throw-deprecation") == 0) {
3752       throw_deprecation = true;
3753     } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3754       const char* cve = arg + 18;
3755       Revert(cve);
3756     } else if (strcmp(arg, "--preserve-symlinks") == 0) {
3757       config_preserve_symlinks = true;
3758     } else if (strcmp(arg, "--prof-process") == 0) {
3759       prof_process = true;
3760       short_circuit = true;
3761     } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
3762       zero_fill_all_buffers = true;
3763     } else if (strcmp(arg, "--v8-options") == 0) {
3764       new_v8_argv[new_v8_argc] = "--help";
3765       new_v8_argc += 1;
3766     } else if (strncmp(arg, "--v8-pool-size=", 15) == 0) {
3767       v8_thread_pool_size = atoi(arg + 15);
3768 #if HAVE_OPENSSL
3769     } else if (strncmp(arg, "--tls-cipher-list=", 18) == 0) {
3770       default_cipher_list = arg + 18;
3771 #if NODE_FIPS_MODE
3772     } else if (strcmp(arg, "--enable-fips") == 0) {
3773       enable_fips_crypto = true;
3774     } else if (strcmp(arg, "--force-fips") == 0) {
3775       force_fips_crypto = true;
3776 #endif /* NODE_FIPS_MODE */
3777     } else if (strncmp(arg, "--openssl-config=", 17) == 0) {
3778       openssl_config = arg + 17;
3779 #endif /* HAVE_OPENSSL */
3780 #if defined(NODE_HAVE_I18N_SUPPORT)
3781     } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
3782       icu_data_dir = arg + 15;
3783 #endif
3784     } else if (strcmp(arg, "--expose-internals") == 0 ||
3785                strcmp(arg, "--expose_internals") == 0) {
3786       // consumed in js
3787     } else {
3788       // V8 option.  Pass through as-is.
3789       new_v8_argv[new_v8_argc] = arg;
3790       new_v8_argc += 1;
3791     }
3792
3793     memcpy(new_exec_argv + new_exec_argc,
3794            argv + index,
3795            args_consumed * sizeof(*argv));
3796
3797     new_exec_argc += args_consumed;
3798     index += args_consumed;
3799   }
3800
3801   // Copy remaining arguments.
3802   const unsigned int args_left = nargs - index;
3803   memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3804   new_argc += args_left;
3805
3806   *exec_argc = new_exec_argc;
3807   *exec_argv = new_exec_argv;
3808   *v8_argc = new_v8_argc;
3809   *v8_argv = new_v8_argv;
3810
3811   // Copy new_argv over argv and update argc.
3812   memcpy(argv, new_argv, new_argc * sizeof(*argv));
3813   delete[] new_argv;
3814   *argc = static_cast<int>(new_argc);
3815
3816   // Copy the preload_modules from the local array to an appropriately sized
3817   // global array.
3818   if (preload_module_count > 0) {
3819     CHECK(!preload_modules);
3820     preload_modules = new const char*[preload_module_count];
3821     memcpy(preload_modules, local_preload_modules,
3822            preload_module_count * sizeof(*preload_modules));
3823   }
3824   delete[] local_preload_modules;
3825 }
3826
3827
3828 // Called from V8 Debug Agent TCP thread.
3829 static void DispatchMessagesDebugAgentCallback(Environment* env) {
3830   // TODO(indutny): move async handle to environment
3831   uv_async_send(&dispatch_debug_messages_async);
3832 }
3833
3834
3835 static void StartDebug(Environment* env, const char* path, bool wait) {
3836   CHECK(!debugger_running);
3837   if (use_inspector) {
3838     debugger_running = v8_platform.StartInspector(env, path,
3839         debug_port >= 0 ? debug_port : default_inspector_port, wait);
3840   } else {
3841     env->debugger_agent()->set_dispatch_handler(
3842           DispatchMessagesDebugAgentCallback);
3843     const char* host = debug_host ? debug_host->c_str() : "127.0.0.1";
3844     int port = debug_port >= 0 ? debug_port : default_debugger_port;
3845     debugger_running =
3846         env->debugger_agent()->Start(host, port, wait);
3847     if (debugger_running == false) {
3848       fprintf(stderr, "Starting debugger on %s:%d failed\n", host, port);
3849       fflush(stderr);
3850       return;
3851     }
3852   }
3853 }
3854
3855
3856 // Called from the main thread.
3857 static void EnableDebug(Environment* env) {
3858   CHECK(debugger_running);
3859
3860   if (use_inspector) {
3861     return;
3862   }
3863
3864   // Send message to enable debug in workers
3865   HandleScope handle_scope(env->isolate());
3866
3867   Local<Object> message = Object::New(env->isolate());
3868   message->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "cmd"),
3869                FIXED_ONE_BYTE_STRING(env->isolate(), "NODE_DEBUG_ENABLED"));
3870   Local<Value> argv[] = {
3871     FIXED_ONE_BYTE_STRING(env->isolate(), "internalMessage"),
3872     message
3873   };
3874   MakeCallback(env, env->process_object(), "emit", arraysize(argv), argv);
3875
3876   // Enabled debugger, possibly making it wait on a semaphore
3877   env->debugger_agent()->Enable();
3878 }
3879
3880
3881 // Called from an arbitrary thread.
3882 static void TryStartDebugger() {
3883   Mutex::ScopedLock scoped_lock(node_isolate_mutex);
3884   if (auto isolate = node_isolate) {
3885     v8::Debug::DebugBreak(isolate);
3886     uv_async_send(&dispatch_debug_messages_async);
3887   }
3888 }
3889
3890
3891 // Called from the main thread.
3892 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
3893   Mutex::ScopedLock scoped_lock(node_isolate_mutex);
3894   if (auto isolate = node_isolate) {
3895     if (debugger_running == false) {
3896       fprintf(stderr, "Starting debugger agent.\n");
3897
3898       HandleScope scope(isolate);
3899       Environment* env = Environment::GetCurrent(isolate);
3900       Context::Scope context_scope(env->context());
3901
3902       StartDebug(env, nullptr, false);
3903       EnableDebug(env);
3904     }
3905
3906     Isolate::Scope isolate_scope(isolate);
3907     v8::Debug::ProcessDebugMessages(isolate);
3908   }
3909 }
3910
3911
3912 #ifdef __POSIX__
3913 static void EnableDebugSignalHandler(int signo) {
3914   uv_sem_post(&debug_semaphore);
3915 }
3916
3917
3918 void RegisterSignalHandler(int signal,
3919                            void (*handler)(int signal),
3920                            bool reset_handler) {
3921   struct sigaction sa;
3922   memset(&sa, 0, sizeof(sa));
3923   sa.sa_handler = handler;
3924 #ifndef __FreeBSD__
3925   // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
3926   // in turn set for a libthr wrapper. This leads to a crash.
3927   // Work around the issue by manually setting SIG_DFL in the signal handler
3928   sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
3929 #endif
3930   sigfillset(&sa.sa_mask);
3931   CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
3932 }
3933
3934
3935 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
3936   Environment* env = Environment::GetCurrent(args);
3937
3938   if (args.Length() != 1) {
3939     return env->ThrowError("Invalid number of arguments.");
3940   }
3941
3942   pid_t pid;
3943   int r;
3944
3945   pid = args[0]->IntegerValue();
3946   r = kill(pid, SIGUSR1);
3947   if (r != 0) {
3948     return env->ThrowErrnoException(errno, "kill");
3949   }
3950 }
3951
3952
3953 inline void* DebugSignalThreadMain(void* unused) {
3954   for (;;) {
3955     uv_sem_wait(&debug_semaphore);
3956     TryStartDebugger();
3957   }
3958   return nullptr;
3959 }
3960
3961
3962 static int RegisterDebugSignalHandler() {
3963   // Start a watchdog thread for calling v8::Debug::DebugBreak() because
3964   // it's not safe to call directly from the signal handler, it can
3965   // deadlock with the thread it interrupts.
3966   CHECK_EQ(0, uv_sem_init(&debug_semaphore, 0));
3967   pthread_attr_t attr;
3968   CHECK_EQ(0, pthread_attr_init(&attr));
3969   // Don't shrink the thread's stack on FreeBSD.  Said platform decided to
3970   // follow the pthreads specification to the letter rather than in spirit:
3971   // https://lists.freebsd.org/pipermail/freebsd-current/2014-March/048885.html
3972 #ifndef __FreeBSD__
3973   CHECK_EQ(0, pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN));
3974 #endif  // __FreeBSD__
3975   CHECK_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
3976   sigset_t sigmask;
3977   sigfillset(&sigmask);
3978   CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &sigmask));
3979   pthread_t thread;
3980   const int err =
3981       pthread_create(&thread, &attr, DebugSignalThreadMain, nullptr);
3982   CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr));
3983   CHECK_EQ(0, pthread_attr_destroy(&attr));
3984   if (err != 0) {
3985     fprintf(stderr, "node[%d]: pthread_create: %s\n", getpid(), strerror(err));
3986     fflush(stderr);
3987     // Leave SIGUSR1 blocked.  We don't install a signal handler,
3988     // receiving the signal would terminate the process.
3989     return -err;
3990   }
3991   RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler);
3992   // Unblock SIGUSR1.  A pending SIGUSR1 signal will now be delivered.
3993   sigemptyset(&sigmask);
3994   sigaddset(&sigmask, SIGUSR1);
3995   CHECK_EQ(0, pthread_sigmask(SIG_UNBLOCK, &sigmask, nullptr));
3996   return 0;
3997 }
3998 #endif  // __POSIX__
3999
4000
4001 #ifdef _WIN32
4002 DWORD WINAPI EnableDebugThreadProc(void* arg) {
4003   TryStartDebugger();
4004   return 0;
4005 }
4006
4007
4008 static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
4009     size_t buf_len) {
4010   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
4011 }
4012
4013
4014 static int RegisterDebugSignalHandler() {
4015   wchar_t mapping_name[32];
4016   HANDLE mapping_handle;
4017   DWORD pid;
4018   LPTHREAD_START_ROUTINE* handler;
4019
4020   pid = GetCurrentProcessId();
4021
4022   if (GetDebugSignalHandlerMappingName(pid,
4023                                        mapping_name,
4024                                        arraysize(mapping_name)) < 0) {
4025     return -1;
4026   }
4027
4028   mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
4029                                       nullptr,
4030                                       PAGE_READWRITE,
4031                                       0,
4032                                       sizeof *handler,
4033                                       mapping_name);
4034   if (mapping_handle == nullptr) {
4035     return -1;
4036   }
4037
4038   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
4039       MapViewOfFile(mapping_handle,
4040                     FILE_MAP_ALL_ACCESS,
4041                     0,
4042                     0,
4043                     sizeof *handler));
4044   if (handler == nullptr) {
4045     CloseHandle(mapping_handle);
4046     return -1;
4047   }
4048
4049   *handler = EnableDebugThreadProc;
4050
4051   UnmapViewOfFile(static_cast<void*>(handler));
4052
4053   return 0;
4054 }
4055
4056
4057 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
4058   Environment* env = Environment::GetCurrent(args);
4059   Isolate* isolate = args.GetIsolate();
4060   DWORD pid;
4061   HANDLE process = nullptr;
4062   HANDLE thread = nullptr;
4063   HANDLE mapping = nullptr;
4064   wchar_t mapping_name[32];
4065   LPTHREAD_START_ROUTINE* handler = nullptr;
4066
4067   if (args.Length() != 1) {
4068     env->ThrowError("Invalid number of arguments.");
4069     goto out;
4070   }
4071
4072   pid = (DWORD) args[0]->IntegerValue();
4073
4074   process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
4075                             PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
4076                             PROCESS_VM_READ,
4077                         FALSE,
4078                         pid);
4079   if (process == nullptr) {
4080     isolate->ThrowException(
4081         WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
4082     goto out;
4083   }
4084
4085   if (GetDebugSignalHandlerMappingName(pid,
4086                                        mapping_name,
4087                                        arraysize(mapping_name)) < 0) {
4088     env->ThrowErrnoException(errno, "sprintf");
4089     goto out;
4090   }
4091
4092   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
4093   if (mapping == nullptr) {
4094     isolate->ThrowException(WinapiErrnoException(isolate,
4095                                              GetLastError(),
4096                                              "OpenFileMappingW"));
4097     goto out;
4098   }
4099
4100   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
4101       MapViewOfFile(mapping,
4102                     FILE_MAP_READ,
4103                     0,
4104                     0,
4105                     sizeof *handler));
4106   if (handler == nullptr || *handler == nullptr) {
4107     isolate->ThrowException(
4108         WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
4109     goto out;
4110   }
4111
4112   thread = CreateRemoteThread(process,
4113                               nullptr,
4114                               0,
4115                               *handler,
4116                               nullptr,
4117                               0,
4118                               nullptr);
4119   if (thread == nullptr) {
4120     isolate->ThrowException(WinapiErrnoException(isolate,
4121                                                  GetLastError(),
4122                                                  "CreateRemoteThread"));
4123     goto out;
4124   }
4125
4126   // Wait for the thread to terminate
4127   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
4128     isolate->ThrowException(WinapiErrnoException(isolate,
4129                                                  GetLastError(),
4130                                                  "WaitForSingleObject"));
4131     goto out;
4132   }
4133
4134  out:
4135   if (process != nullptr)
4136     CloseHandle(process);
4137   if (thread != nullptr)
4138     CloseHandle(thread);
4139   if (handler != nullptr)
4140     UnmapViewOfFile(handler);
4141   if (mapping != nullptr)
4142     CloseHandle(mapping);
4143 }
4144 #endif  // _WIN32
4145
4146
4147 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
4148   v8::Debug::DebugBreak(args.GetIsolate());
4149 }
4150
4151
4152 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
4153   if (debugger_running) {
4154     Environment* env = Environment::GetCurrent(args);
4155 #if HAVE_INSPECTOR
4156     if (use_inspector) {
4157       env->inspector_agent()->Stop();
4158     } else {
4159 #endif
4160       env->debugger_agent()->Stop();
4161 #if HAVE_INSPECTOR
4162     }
4163 #endif
4164     debugger_running = false;
4165   }
4166 }
4167
4168
4169 inline void PlatformInit() {
4170 #ifdef __POSIX__
4171   sigset_t sigmask;
4172   sigemptyset(&sigmask);
4173   sigaddset(&sigmask, SIGUSR1);
4174   const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
4175
4176   // Make sure file descriptors 0-2 are valid before we start logging anything.
4177   for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
4178     struct stat ignored;
4179     if (fstat(fd, &ignored) == 0)
4180       continue;
4181     // Anything but EBADF means something is seriously wrong.  We don't
4182     // have to special-case EINTR, fstat() is not interruptible.
4183     if (errno != EBADF)
4184       ABORT();
4185     if (fd != open("/dev/null", O_RDWR))
4186       ABORT();
4187   }
4188
4189   CHECK_EQ(err, 0);
4190
4191   // Restore signal dispositions, the parent process may have changed them.
4192   struct sigaction act;
4193   memset(&act, 0, sizeof(act));
4194
4195   // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
4196   // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
4197   // Counting up to SIGRTMIN doesn't work for the same reason.
4198   for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
4199     if (nr == SIGKILL || nr == SIGSTOP)
4200       continue;
4201     act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
4202     CHECK_EQ(0, sigaction(nr, &act, nullptr));
4203   }
4204
4205   RegisterSignalHandler(SIGINT, SignalExit, true);
4206   RegisterSignalHandler(SIGTERM, SignalExit, true);
4207
4208   // Raise the open file descriptor limit.
4209   struct rlimit lim;
4210   if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
4211     // Do a binary search for the limit.
4212     rlim_t min = lim.rlim_cur;
4213     rlim_t max = 1 << 20;
4214     // But if there's a defined upper bound, don't search, just set it.
4215     if (lim.rlim_max != RLIM_INFINITY) {
4216       min = lim.rlim_max;
4217       max = lim.rlim_max;
4218     }
4219     do {
4220       lim.rlim_cur = min + (max - min) / 2;
4221       if (setrlimit(RLIMIT_NOFILE, &lim)) {
4222         max = lim.rlim_cur;
4223       } else {
4224         min = lim.rlim_cur;
4225       }
4226     } while (min + 1 < max);
4227   }
4228 #endif  // __POSIX__
4229 }
4230
4231
4232 void Init(int* argc,
4233           const char** argv,
4234           int* exec_argc,
4235           const char*** exec_argv,
4236           uv_loop_t* uv_loop_) {
4237   // Initialize prog_start_time to get relative uptime.
4238   prog_start_time = static_cast<double>(uv_now(uv_loop_));
4239
4240   if (g_upstream_node_mode) {  // No indent to minimize diff.
4241   // Make inherited handles noninheritable.
4242   uv_disable_stdio_inheritance();
4243   }  // g_upstream_node_mode
4244
4245   // init async debug messages dispatching
4246   // Main thread uses uv_default_loop
4247   CHECK_EQ(0, uv_async_init(uv_loop_,
4248                             &dispatch_debug_messages_async,
4249                             DispatchDebugMessagesAsyncCallback));
4250   uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
4251
4252 #if defined(NODE_HAVE_I18N_SUPPORT)
4253   // Set the ICU casing flag early
4254   // so the user can disable a flag --foo at run-time by passing
4255   // --no_foo from the command line.
4256   const char icu_case_mapping[] = "--icu_case_mapping";
4257   V8::SetFlagsFromString(icu_case_mapping, sizeof(icu_case_mapping) - 1);
4258 #endif
4259
4260 #if defined(NODE_V8_OPTIONS)
4261   // Should come before the call to V8::SetFlagsFromCommandLine()
4262   // so the user can disable a flag --foo at run-time by passing
4263   // --no_foo from the command line.
4264   V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
4265 #endif
4266
4267   // Allow for environment set preserving symlinks.
4268   if (auto preserve_symlinks = secure_getenv("NODE_PRESERVE_SYMLINKS")) {
4269     config_preserve_symlinks = (*preserve_symlinks == '1');
4270   }
4271
4272   if (g_upstream_node_mode) {  // No indent to minimize diff.
4273   // Parse a few arguments which are specific to Node.
4274   int v8_argc;
4275   const char** v8_argv;
4276   ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv);
4277
4278   // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
4279   // manually?  That would give us a little more control over its runtime
4280   // behavior but it could also interfere with the user's intentions in ways
4281   // we fail to anticipate.  Dillema.
4282   for (int i = 1; i < v8_argc; ++i) {
4283     if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
4284       v8_is_profiling = true;
4285       break;
4286     }
4287   }
4288
4289 #ifdef __POSIX__
4290   // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc.  Avoids the
4291   // performance penalty of frequent EINTR wakeups when the profiler is running.
4292   // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
4293   if (v8_is_profiling) {
4294     uv_loop_configure(uv_loop_, UV_LOOP_BLOCK_SIGNAL, SIGPROF);
4295   }
4296 #endif
4297
4298 #if defined(NODE_HAVE_I18N_SUPPORT)
4299   if (icu_data_dir == nullptr) {
4300     // if the parameter isn't given, use the env variable.
4301     icu_data_dir = secure_getenv("NODE_ICU_DATA");
4302   }
4303   // Initialize ICU.
4304   // If icu_data_dir is nullptr here, it will load the 'minimal' data.
4305   if (!i18n::InitializeICUDirectory(icu_data_dir)) {
4306     FatalError(nullptr, "Could not initialize ICU "
4307                      "(check NODE_ICU_DATA or --icu-data-dir parameters)");
4308   }
4309 #endif
4310   // The const_cast doesn't violate conceptual const-ness.  V8 doesn't modify
4311   // the argv array or the elements it points to.
4312   if (v8_argc > 1)
4313     V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
4314
4315   // Anything that's still in v8_argv is not a V8 or a node option.
4316   for (int i = 1; i < v8_argc; i++) {
4317     fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
4318   }
4319   delete[] v8_argv;
4320   v8_argv = nullptr;
4321
4322   if (v8_argc > 1) {
4323     exit(9);
4324   }
4325   }  // g_upstream_node_mode
4326
4327   // Unconditionally force typed arrays to allocate outside the v8 heap. This
4328   // is to prevent memory pointers from being moved around that are returned by
4329   // Buffer::Data().
4330   const char no_typed_array_heap[] = "--typed_array_max_size_in_heap=0";
4331   V8::SetFlagsFromString(no_typed_array_heap, sizeof(no_typed_array_heap) - 1);
4332
4333   if (g_upstream_node_mode) {  // No indent to minimize diff.
4334   if (!use_debug_agent) {
4335     RegisterDebugSignalHandler();
4336   }
4337   }  // g_upstream_node_mode
4338
4339   // We should set node_is_initialized here instead of in node::Start,
4340   // otherwise embedders using node::Init to initialize everything will not be
4341   // able to set it and native modules will not load for them.
4342   node_is_initialized = true;
4343 }
4344
4345
4346 struct AtExitCallback {
4347   AtExitCallback* next_;
4348   void (*cb_)(void* arg);
4349   void* arg_;
4350 };
4351
4352 static AtExitCallback* at_exit_functions_;
4353
4354
4355 // TODO(bnoordhuis) Turn into per-context event.
4356 void RunAtExit(Environment* env) {
4357   AtExitCallback* p = at_exit_functions_;
4358   at_exit_functions_ = nullptr;
4359
4360   while (p) {
4361     AtExitCallback* q = p->next_;
4362     p->cb_(p->arg_);
4363     delete p;
4364     p = q;
4365   }
4366 }
4367
4368
4369 void AtExit(void (*cb)(void* arg), void* arg) {
4370   AtExitCallback* p = new AtExitCallback;
4371   p->cb_ = cb;
4372   p->arg_ = arg;
4373   p->next_ = at_exit_functions_;
4374   at_exit_functions_ = p;
4375 }
4376
4377
4378 void EmitBeforeExit(Environment* env) {
4379   HandleScope handle_scope(env->isolate());
4380   Context::Scope context_scope(env->context());
4381   Local<Object> process_object = env->process_object();
4382   Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(), "exitCode");
4383   Local<Value> args[] = {
4384     FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
4385     process_object->Get(exit_code)->ToInteger(env->isolate())
4386   };
4387   MakeCallback(env, process_object, "emit", arraysize(args), args);
4388 }
4389
4390
4391 int EmitExit(Environment* env) {
4392   // process.emit('exit')
4393   HandleScope handle_scope(env->isolate());
4394   Context::Scope context_scope(env->context());
4395   Local<Object> process_object = env->process_object();
4396   process_object->Set(env->exiting_string(), True(env->isolate()));
4397
4398   Local<String> exitCode = env->exit_code_string();
4399   int code = process_object->Get(exitCode)->Int32Value();
4400
4401   Local<Value> args[] = {
4402     env->exit_string(),
4403     Integer::New(env->isolate(), code)
4404   };
4405
4406   MakeCallback(env, process_object, "emit", arraysize(args), args);
4407
4408   // Reload exit code, it may be changed by `emit('exit')`
4409   return process_object->Get(exitCode)->Int32Value();
4410 }
4411
4412
4413 IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) {
4414   return new IsolateData(isolate, loop);
4415 }
4416
4417
4418 void FreeIsolateData(IsolateData* isolate_data) {
4419   delete isolate_data;
4420 }
4421
4422
4423 Environment* CreateEnvironment(IsolateData* isolate_data,
4424                                Local<Context> context,
4425                                int argc,
4426                                const char* const* argv,
4427                                int exec_argc,
4428                                const char* const* exec_argv) {
4429   Isolate* isolate = context->GetIsolate();
4430   HandleScope handle_scope(isolate);
4431   Context::Scope context_scope(context);
4432   auto env = new Environment(isolate_data, context);
4433   env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4434   return env;
4435 }
4436
4437
4438 void FreeEnvironment(Environment* env) {
4439   delete env;
4440 }
4441
4442
4443 inline int Start(Isolate* isolate, IsolateData* isolate_data, // not called
4444                  int argc, const char* const* argv,
4445                  int exec_argc, const char* const* exec_argv) {
4446   HandleScope handle_scope(isolate);
4447   Local<Context> context = Context::New(isolate);
4448   Context::Scope context_scope(context);
4449   Environment env(isolate_data, context);
4450   env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
4451
4452   // Start debug agent when argv has --debug
4453   if (use_debug_agent) {
4454     const char* path = argc > 1 ? argv[1] : nullptr;
4455     StartDebug(&env, path, debug_wait_connect);
4456     if (use_inspector && !debugger_running)
4457       return 12;  // Signal internal error.
4458   }
4459
4460   {
4461     Environment::AsyncCallbackScope callback_scope(&env);
4462     LoadEnvironment(&env);
4463   }
4464
4465   env.set_trace_sync_io(trace_sync_io);
4466
4467   // Enable debugger
4468   if (use_debug_agent)
4469     EnableDebug(&env);
4470
4471   {
4472     SealHandleScope seal(isolate);
4473     bool more;
4474     do {
4475       v8_platform.PumpMessageLoop(isolate);
4476       more = uv_run(env.event_loop(), UV_RUN_ONCE);
4477
4478       if (more == false) {
4479         v8_platform.PumpMessageLoop(isolate);
4480         EmitBeforeExit(&env);
4481
4482         // Emit `beforeExit` if the loop became alive either after emitting
4483         // event, or after running some callbacks.
4484         more = uv_loop_alive(env.event_loop());
4485         if (uv_run(env.event_loop(), UV_RUN_NOWAIT) != 0)
4486           more = true;
4487       }
4488     } while (more == true);
4489   }
4490
4491   env.set_trace_sync_io(false);
4492
4493   const int exit_code = EmitExit(&env);
4494   RunAtExit(&env);
4495
4496   WaitForInspectorDisconnect(&env);
4497 #if defined(LEAK_SANITIZER)
4498   __lsan_do_leak_check();
4499 #endif
4500
4501   return exit_code;
4502 }
4503
4504 inline int Start(uv_loop_t* event_loop, // not called
4505                  int argc, const char* const* argv,
4506                  int exec_argc, const char* const* exec_argv) {
4507   Isolate::CreateParams params;
4508   ArrayBufferAllocator allocator;
4509   params.array_buffer_allocator = &allocator;
4510 #ifdef NODE_ENABLE_VTUNE_PROFILING
4511   params.code_event_handler = vTune::GetVtuneCodeEventHandler();
4512 #endif
4513
4514   Isolate* const isolate = Isolate::New(params);
4515   if (isolate == nullptr)
4516     return 12;  // Signal internal error.
4517
4518   isolate->AddMessageListener(OnMessage);
4519   isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
4520   isolate->SetAutorunMicrotasks(false);
4521   isolate->SetFatalErrorHandler(OnFatalError);
4522
4523   if (track_heap_objects) {
4524     isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
4525   }
4526
4527   {
4528     Mutex::ScopedLock scoped_lock(node_isolate_mutex);
4529     CHECK_EQ(node_isolate, nullptr);
4530     node_isolate = isolate;
4531   }
4532
4533   int exit_code;
4534   {
4535     Locker locker(isolate);
4536     Isolate::Scope isolate_scope(isolate);
4537     HandleScope handle_scope(isolate);
4538     IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field());
4539     exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
4540   }
4541
4542   {
4543     Mutex::ScopedLock scoped_lock(node_isolate_mutex);
4544     CHECK_EQ(node_isolate, isolate);
4545     node_isolate = nullptr;
4546   }
4547
4548   isolate->Dispose();
4549
4550   return exit_code;
4551 }
4552
4553 int Start(int argc, char** argv) {
4554   atexit([] () { uv_tty_reset_mode(); });
4555   PlatformInit();
4556
4557   CHECK_GT(argc, 0);
4558
4559   // Hack around with the argv pointer. Used for process.title = "blah".
4560   argv = uv_setup_args(argc, argv);
4561
4562   // This needs to run *before* V8::Initialize().  The const_cast is not
4563   // optional, in case you're wondering.
4564   int exec_argc;
4565   const char** exec_argv;
4566   // Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
4567
4568 #if HAVE_OPENSSL
4569   if (const char* extra = secure_getenv("NODE_EXTRA_CA_CERTS"))
4570     crypto::UseExtraCaCerts(extra);
4571 #ifdef NODE_FIPS_MODE
4572   // In the case of FIPS builds we should make sure
4573   // the random source is properly initialized first.
4574   OPENSSL_init();
4575 #endif  // NODE_FIPS_MODE
4576   // V8 on Windows doesn't have a good source of entropy. Seed it from
4577   // OpenSSL's pool.
4578   V8::SetEntropySource(crypto::EntropySource);
4579 #endif
4580
4581   v8_platform.Initialize(v8_thread_pool_size);
4582   V8::Initialize();
4583   v8_initialized = true;
4584   const int exit_code =
4585       Start(uv_default_loop(), argc, argv, exec_argc, exec_argv);
4586   v8_initialized = false;
4587   V8::Dispose();
4588
4589   v8_platform.Dispose();
4590
4591   delete[] exec_argv;
4592   exec_argv = nullptr;
4593
4594   return exit_code;
4595 }
4596
4597
4598 }  // namespace node