process: reintroduce ares to versions
[platform/upstream/nodejs.git] / 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_v8_platform.h"
9
10 #if defined HAVE_PERFCTR
11 #include "node_counters.h"
12 #endif
13
14 #if HAVE_OPENSSL
15 #include "node_crypto.h"
16 #endif
17
18 #if defined(NODE_HAVE_I18N_SUPPORT)
19 #include "node_i18n.h"
20 #endif
21
22 #if defined HAVE_DTRACE || defined HAVE_ETW
23 #include "node_dtrace.h"
24 #endif
25
26 #include "ares.h"
27 #include "async-wrap.h"
28 #include "async-wrap-inl.h"
29 #include "env.h"
30 #include "env-inl.h"
31 #include "handle_wrap.h"
32 #include "req_wrap.h"
33 #include "string_bytes.h"
34 #include "util.h"
35 #include "uv.h"
36 #include "v8-debug.h"
37 #include "v8-profiler.h"
38 #include "zlib.h"
39
40 #include <errno.h>
41 #include <limits.h>  // PATH_MAX
42 #include <locale.h>
43 #include <signal.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/types.h>
48
49 #if defined(_MSC_VER)
50 #include <direct.h>
51 #include <io.h>
52 #include <process.h>
53 #define strcasecmp _stricmp
54 #define getpid _getpid
55 #define umask _umask
56 typedef int mode_t;
57 #else
58 #include <sys/resource.h>  // getrlimit, setrlimit
59 #include <unistd.h>  // setuid, getuid
60 #endif
61
62 #if defined(__POSIX__) && !defined(__ANDROID__)
63 #include <pwd.h>  // getpwnam()
64 #include <grp.h>  // getgrnam()
65 #endif
66
67 #ifdef __APPLE__
68 #include <crt_externs.h>
69 #define environ (*_NSGetEnviron())
70 #elif !defined(_MSC_VER)
71 extern char **environ;
72 #endif
73
74 namespace node {
75
76 using v8::Array;
77 using v8::ArrayBuffer;
78 using v8::Boolean;
79 using v8::Context;
80 using v8::EscapableHandleScope;
81 using v8::Exception;
82 using v8::Function;
83 using v8::FunctionCallbackInfo;
84 using v8::FunctionTemplate;
85 using v8::Handle;
86 using v8::HandleScope;
87 using v8::HeapStatistics;
88 using v8::Integer;
89 using v8::Isolate;
90 using v8::Local;
91 using v8::Locker;
92 using v8::Message;
93 using v8::Number;
94 using v8::Object;
95 using v8::ObjectTemplate;
96 using v8::PropertyCallbackInfo;
97 using v8::String;
98 using v8::TryCatch;
99 using v8::Uint32;
100 using v8::V8;
101 using v8::Value;
102 using v8::kExternalUint32Array;
103
104 static bool print_eval = false;
105 static bool force_repl = false;
106 static bool trace_deprecation = false;
107 static bool throw_deprecation = false;
108 static const char* eval_string = nullptr;
109 static bool use_debug_agent = false;
110 static bool debug_wait_connect = false;
111 static int debug_port = 5858;
112 static bool v8_is_profiling = false;
113 static bool node_is_initialized = false;
114 static node_module* modpending;
115 static node_module* modlist_builtin;
116 static node_module* modlist_linked;
117 static node_module* modlist_addon;
118
119 #if defined(NODE_HAVE_I18N_SUPPORT)
120 // Path to ICU data (for i18n / Intl)
121 static const char* icu_data_dir = nullptr;
122 #endif
123
124 // used by C++ modules as well
125 bool no_deprecation = false;
126
127 // process-relative uptime base, initialized at start-up
128 static double prog_start_time;
129 static bool debugger_running;
130 static uv_async_t dispatch_debug_messages_async;
131
132 static Isolate* node_isolate = nullptr;
133
134 int WRITE_UTF8_FLAGS = v8::String::HINT_MANY_WRITES_EXPECTED |
135                        v8::String::NO_NULL_TERMINATION;
136
137 class ArrayBufferAllocator : public ArrayBuffer::Allocator {
138  public:
139   // Impose an upper limit to avoid out of memory errors that bring down
140   // the process.
141   static const size_t kMaxLength = 0x3fffffff;
142   static ArrayBufferAllocator the_singleton;
143   virtual ~ArrayBufferAllocator() = default;
144   virtual void* Allocate(size_t length) override;
145   virtual void* AllocateUninitialized(size_t length) override;
146   virtual void Free(void* data, size_t length) override;
147  private:
148   ArrayBufferAllocator() = default;
149   DISALLOW_COPY_AND_ASSIGN(ArrayBufferAllocator);
150 };
151
152 ArrayBufferAllocator ArrayBufferAllocator::the_singleton;
153
154
155 void* ArrayBufferAllocator::Allocate(size_t length) {
156   if (length > kMaxLength)
157     return nullptr;
158   char* data = new char[length];
159   memset(data, 0, length);
160   return data;
161 }
162
163
164 void* ArrayBufferAllocator::AllocateUninitialized(size_t length) {
165   if (length > kMaxLength)
166     return nullptr;
167   return new char[length];
168 }
169
170
171 void ArrayBufferAllocator::Free(void* data, size_t length) {
172   delete[] static_cast<char*>(data);
173 }
174
175
176 static void CheckImmediate(uv_check_t* handle) {
177   Environment* env = Environment::from_immediate_check_handle(handle);
178   HandleScope scope(env->isolate());
179   Context::Scope context_scope(env->context());
180   MakeCallback(env, env->process_object(), env->immediate_callback_string());
181 }
182
183
184 static void IdleImmediateDummy(uv_idle_t* handle) {
185   // Do nothing. Only for maintaining event loop.
186   // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
187 }
188
189
190 static inline const char *errno_string(int errorno) {
191 #define ERRNO_CASE(e)  case e: return #e;
192   switch (errorno) {
193 #ifdef EACCES
194   ERRNO_CASE(EACCES);
195 #endif
196
197 #ifdef EADDRINUSE
198   ERRNO_CASE(EADDRINUSE);
199 #endif
200
201 #ifdef EADDRNOTAVAIL
202   ERRNO_CASE(EADDRNOTAVAIL);
203 #endif
204
205 #ifdef EAFNOSUPPORT
206   ERRNO_CASE(EAFNOSUPPORT);
207 #endif
208
209 #ifdef EAGAIN
210   ERRNO_CASE(EAGAIN);
211 #endif
212
213 #ifdef EWOULDBLOCK
214 # if EAGAIN != EWOULDBLOCK
215   ERRNO_CASE(EWOULDBLOCK);
216 # endif
217 #endif
218
219 #ifdef EALREADY
220   ERRNO_CASE(EALREADY);
221 #endif
222
223 #ifdef EBADF
224   ERRNO_CASE(EBADF);
225 #endif
226
227 #ifdef EBADMSG
228   ERRNO_CASE(EBADMSG);
229 #endif
230
231 #ifdef EBUSY
232   ERRNO_CASE(EBUSY);
233 #endif
234
235 #ifdef ECANCELED
236   ERRNO_CASE(ECANCELED);
237 #endif
238
239 #ifdef ECHILD
240   ERRNO_CASE(ECHILD);
241 #endif
242
243 #ifdef ECONNABORTED
244   ERRNO_CASE(ECONNABORTED);
245 #endif
246
247 #ifdef ECONNREFUSED
248   ERRNO_CASE(ECONNREFUSED);
249 #endif
250
251 #ifdef ECONNRESET
252   ERRNO_CASE(ECONNRESET);
253 #endif
254
255 #ifdef EDEADLK
256   ERRNO_CASE(EDEADLK);
257 #endif
258
259 #ifdef EDESTADDRREQ
260   ERRNO_CASE(EDESTADDRREQ);
261 #endif
262
263 #ifdef EDOM
264   ERRNO_CASE(EDOM);
265 #endif
266
267 #ifdef EDQUOT
268   ERRNO_CASE(EDQUOT);
269 #endif
270
271 #ifdef EEXIST
272   ERRNO_CASE(EEXIST);
273 #endif
274
275 #ifdef EFAULT
276   ERRNO_CASE(EFAULT);
277 #endif
278
279 #ifdef EFBIG
280   ERRNO_CASE(EFBIG);
281 #endif
282
283 #ifdef EHOSTUNREACH
284   ERRNO_CASE(EHOSTUNREACH);
285 #endif
286
287 #ifdef EIDRM
288   ERRNO_CASE(EIDRM);
289 #endif
290
291 #ifdef EILSEQ
292   ERRNO_CASE(EILSEQ);
293 #endif
294
295 #ifdef EINPROGRESS
296   ERRNO_CASE(EINPROGRESS);
297 #endif
298
299 #ifdef EINTR
300   ERRNO_CASE(EINTR);
301 #endif
302
303 #ifdef EINVAL
304   ERRNO_CASE(EINVAL);
305 #endif
306
307 #ifdef EIO
308   ERRNO_CASE(EIO);
309 #endif
310
311 #ifdef EISCONN
312   ERRNO_CASE(EISCONN);
313 #endif
314
315 #ifdef EISDIR
316   ERRNO_CASE(EISDIR);
317 #endif
318
319 #ifdef ELOOP
320   ERRNO_CASE(ELOOP);
321 #endif
322
323 #ifdef EMFILE
324   ERRNO_CASE(EMFILE);
325 #endif
326
327 #ifdef EMLINK
328   ERRNO_CASE(EMLINK);
329 #endif
330
331 #ifdef EMSGSIZE
332   ERRNO_CASE(EMSGSIZE);
333 #endif
334
335 #ifdef EMULTIHOP
336   ERRNO_CASE(EMULTIHOP);
337 #endif
338
339 #ifdef ENAMETOOLONG
340   ERRNO_CASE(ENAMETOOLONG);
341 #endif
342
343 #ifdef ENETDOWN
344   ERRNO_CASE(ENETDOWN);
345 #endif
346
347 #ifdef ENETRESET
348   ERRNO_CASE(ENETRESET);
349 #endif
350
351 #ifdef ENETUNREACH
352   ERRNO_CASE(ENETUNREACH);
353 #endif
354
355 #ifdef ENFILE
356   ERRNO_CASE(ENFILE);
357 #endif
358
359 #ifdef ENOBUFS
360   ERRNO_CASE(ENOBUFS);
361 #endif
362
363 #ifdef ENODATA
364   ERRNO_CASE(ENODATA);
365 #endif
366
367 #ifdef ENODEV
368   ERRNO_CASE(ENODEV);
369 #endif
370
371 #ifdef ENOENT
372   ERRNO_CASE(ENOENT);
373 #endif
374
375 #ifdef ENOEXEC
376   ERRNO_CASE(ENOEXEC);
377 #endif
378
379 #ifdef ENOLINK
380   ERRNO_CASE(ENOLINK);
381 #endif
382
383 #ifdef ENOLCK
384 # if ENOLINK != ENOLCK
385   ERRNO_CASE(ENOLCK);
386 # endif
387 #endif
388
389 #ifdef ENOMEM
390   ERRNO_CASE(ENOMEM);
391 #endif
392
393 #ifdef ENOMSG
394   ERRNO_CASE(ENOMSG);
395 #endif
396
397 #ifdef ENOPROTOOPT
398   ERRNO_CASE(ENOPROTOOPT);
399 #endif
400
401 #ifdef ENOSPC
402   ERRNO_CASE(ENOSPC);
403 #endif
404
405 #ifdef ENOSR
406   ERRNO_CASE(ENOSR);
407 #endif
408
409 #ifdef ENOSTR
410   ERRNO_CASE(ENOSTR);
411 #endif
412
413 #ifdef ENOSYS
414   ERRNO_CASE(ENOSYS);
415 #endif
416
417 #ifdef ENOTCONN
418   ERRNO_CASE(ENOTCONN);
419 #endif
420
421 #ifdef ENOTDIR
422   ERRNO_CASE(ENOTDIR);
423 #endif
424
425 #ifdef ENOTEMPTY
426   ERRNO_CASE(ENOTEMPTY);
427 #endif
428
429 #ifdef ENOTSOCK
430   ERRNO_CASE(ENOTSOCK);
431 #endif
432
433 #ifdef ENOTSUP
434   ERRNO_CASE(ENOTSUP);
435 #else
436 # ifdef EOPNOTSUPP
437   ERRNO_CASE(EOPNOTSUPP);
438 # endif
439 #endif
440
441 #ifdef ENOTTY
442   ERRNO_CASE(ENOTTY);
443 #endif
444
445 #ifdef ENXIO
446   ERRNO_CASE(ENXIO);
447 #endif
448
449
450 #ifdef EOVERFLOW
451   ERRNO_CASE(EOVERFLOW);
452 #endif
453
454 #ifdef EPERM
455   ERRNO_CASE(EPERM);
456 #endif
457
458 #ifdef EPIPE
459   ERRNO_CASE(EPIPE);
460 #endif
461
462 #ifdef EPROTO
463   ERRNO_CASE(EPROTO);
464 #endif
465
466 #ifdef EPROTONOSUPPORT
467   ERRNO_CASE(EPROTONOSUPPORT);
468 #endif
469
470 #ifdef EPROTOTYPE
471   ERRNO_CASE(EPROTOTYPE);
472 #endif
473
474 #ifdef ERANGE
475   ERRNO_CASE(ERANGE);
476 #endif
477
478 #ifdef EROFS
479   ERRNO_CASE(EROFS);
480 #endif
481
482 #ifdef ESPIPE
483   ERRNO_CASE(ESPIPE);
484 #endif
485
486 #ifdef ESRCH
487   ERRNO_CASE(ESRCH);
488 #endif
489
490 #ifdef ESTALE
491   ERRNO_CASE(ESTALE);
492 #endif
493
494 #ifdef ETIME
495   ERRNO_CASE(ETIME);
496 #endif
497
498 #ifdef ETIMEDOUT
499   ERRNO_CASE(ETIMEDOUT);
500 #endif
501
502 #ifdef ETXTBSY
503   ERRNO_CASE(ETXTBSY);
504 #endif
505
506 #ifdef EXDEV
507   ERRNO_CASE(EXDEV);
508 #endif
509
510   default: return "";
511   }
512 }
513
514 const char *signo_string(int signo) {
515 #define SIGNO_CASE(e)  case e: return #e;
516   switch (signo) {
517 #ifdef SIGHUP
518   SIGNO_CASE(SIGHUP);
519 #endif
520
521 #ifdef SIGINT
522   SIGNO_CASE(SIGINT);
523 #endif
524
525 #ifdef SIGQUIT
526   SIGNO_CASE(SIGQUIT);
527 #endif
528
529 #ifdef SIGILL
530   SIGNO_CASE(SIGILL);
531 #endif
532
533 #ifdef SIGTRAP
534   SIGNO_CASE(SIGTRAP);
535 #endif
536
537 #ifdef SIGABRT
538   SIGNO_CASE(SIGABRT);
539 #endif
540
541 #ifdef SIGIOT
542 # if SIGABRT != SIGIOT
543   SIGNO_CASE(SIGIOT);
544 # endif
545 #endif
546
547 #ifdef SIGBUS
548   SIGNO_CASE(SIGBUS);
549 #endif
550
551 #ifdef SIGFPE
552   SIGNO_CASE(SIGFPE);
553 #endif
554
555 #ifdef SIGKILL
556   SIGNO_CASE(SIGKILL);
557 #endif
558
559 #ifdef SIGUSR1
560   SIGNO_CASE(SIGUSR1);
561 #endif
562
563 #ifdef SIGSEGV
564   SIGNO_CASE(SIGSEGV);
565 #endif
566
567 #ifdef SIGUSR2
568   SIGNO_CASE(SIGUSR2);
569 #endif
570
571 #ifdef SIGPIPE
572   SIGNO_CASE(SIGPIPE);
573 #endif
574
575 #ifdef SIGALRM
576   SIGNO_CASE(SIGALRM);
577 #endif
578
579   SIGNO_CASE(SIGTERM);
580
581 #ifdef SIGCHLD
582   SIGNO_CASE(SIGCHLD);
583 #endif
584
585 #ifdef SIGSTKFLT
586   SIGNO_CASE(SIGSTKFLT);
587 #endif
588
589
590 #ifdef SIGCONT
591   SIGNO_CASE(SIGCONT);
592 #endif
593
594 #ifdef SIGSTOP
595   SIGNO_CASE(SIGSTOP);
596 #endif
597
598 #ifdef SIGTSTP
599   SIGNO_CASE(SIGTSTP);
600 #endif
601
602 #ifdef SIGBREAK
603   SIGNO_CASE(SIGBREAK);
604 #endif
605
606 #ifdef SIGTTIN
607   SIGNO_CASE(SIGTTIN);
608 #endif
609
610 #ifdef SIGTTOU
611   SIGNO_CASE(SIGTTOU);
612 #endif
613
614 #ifdef SIGURG
615   SIGNO_CASE(SIGURG);
616 #endif
617
618 #ifdef SIGXCPU
619   SIGNO_CASE(SIGXCPU);
620 #endif
621
622 #ifdef SIGXFSZ
623   SIGNO_CASE(SIGXFSZ);
624 #endif
625
626 #ifdef SIGVTALRM
627   SIGNO_CASE(SIGVTALRM);
628 #endif
629
630 #ifdef SIGPROF
631   SIGNO_CASE(SIGPROF);
632 #endif
633
634 #ifdef SIGWINCH
635   SIGNO_CASE(SIGWINCH);
636 #endif
637
638 #ifdef SIGIO
639   SIGNO_CASE(SIGIO);
640 #endif
641
642 #ifdef SIGPOLL
643 # if SIGPOLL != SIGIO
644   SIGNO_CASE(SIGPOLL);
645 # endif
646 #endif
647
648 #ifdef SIGLOST
649   SIGNO_CASE(SIGLOST);
650 #endif
651
652 #ifdef SIGPWR
653 # if SIGPWR != SIGLOST
654   SIGNO_CASE(SIGPWR);
655 # endif
656 #endif
657
658 #ifdef SIGSYS
659   SIGNO_CASE(SIGSYS);
660 #endif
661
662   default: return "";
663   }
664 }
665
666
667 // Convenience methods
668
669
670 void ThrowError(v8::Isolate* isolate, const char* errmsg) {
671   Environment::GetCurrent(isolate)->ThrowError(errmsg);
672 }
673
674
675 void ThrowTypeError(v8::Isolate* isolate, const char* errmsg) {
676   Environment::GetCurrent(isolate)->ThrowTypeError(errmsg);
677 }
678
679
680 void ThrowRangeError(v8::Isolate* isolate, const char* errmsg) {
681   Environment::GetCurrent(isolate)->ThrowRangeError(errmsg);
682 }
683
684
685 void ThrowErrnoException(v8::Isolate* isolate,
686                          int errorno,
687                          const char* syscall,
688                          const char* message,
689                          const char* path) {
690   Environment::GetCurrent(isolate)->ThrowErrnoException(errorno,
691                                                         syscall,
692                                                         message,
693                                                         path);
694 }
695
696
697 void ThrowUVException(v8::Isolate* isolate,
698                       int errorno,
699                       const char* syscall,
700                       const char* message,
701                       const char* path) {
702   Environment::GetCurrent(isolate)->ThrowErrnoException(errorno,
703                                                         syscall,
704                                                         message,
705                                                         path);
706 }
707
708
709 Local<Value> ErrnoException(Isolate* isolate,
710                             int errorno,
711                             const char *syscall,
712                             const char *msg,
713                             const char *path) {
714   Environment* env = Environment::GetCurrent(isolate);
715
716   Local<Value> e;
717   Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
718   if (msg == nullptr || msg[0] == '\0') {
719     msg = strerror(errorno);
720   }
721   Local<String> message = OneByteString(env->isolate(), msg);
722
723   Local<String> cons1 =
724       String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
725   Local<String> cons2 = String::Concat(cons1, message);
726
727   if (path) {
728     Local<String> cons3 =
729         String::Concat(cons2, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
730     Local<String> cons4 =
731         String::Concat(cons3, String::NewFromUtf8(env->isolate(), path));
732     Local<String> cons5 =
733         String::Concat(cons4, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
734     e = Exception::Error(cons5);
735   } else {
736     e = Exception::Error(cons2);
737   }
738
739   Local<Object> obj = e->ToObject(env->isolate());
740   obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
741   obj->Set(env->code_string(), estring);
742
743   if (path != nullptr) {
744     obj->Set(env->path_string(), String::NewFromUtf8(env->isolate(), path));
745   }
746
747   if (syscall != nullptr) {
748     obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
749   }
750
751   return e;
752 }
753
754
755 // hack alert! copy of ErrnoException, tuned for uv errors
756 Local<Value> UVException(Isolate* isolate,
757                          int errorno,
758                          const char *syscall,
759                          const char *msg,
760                          const char *path) {
761   Environment* env = Environment::GetCurrent(isolate);
762
763   if (!msg || !msg[0])
764     msg = uv_strerror(errorno);
765
766   Local<String> estring = OneByteString(env->isolate(), uv_err_name(errorno));
767   Local<String> message = OneByteString(env->isolate(), msg);
768   Local<String> cons1 =
769       String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
770   Local<String> cons2 = String::Concat(cons1, message);
771
772   Local<Value> e;
773
774   Local<String> path_str;
775
776   if (path) {
777 #ifdef _WIN32
778     if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
779       path_str = String::Concat(FIXED_ONE_BYTE_STRING(env->isolate(), "\\\\"),
780                                 String::NewFromUtf8(env->isolate(), path + 8));
781     } else if (strncmp(path, "\\\\?\\", 4) == 0) {
782       path_str = String::NewFromUtf8(env->isolate(), path + 4);
783     } else {
784       path_str = String::NewFromUtf8(env->isolate(), path);
785     }
786 #else
787     path_str = String::NewFromUtf8(env->isolate(), path);
788 #endif
789
790     Local<String> cons3 =
791         String::Concat(cons2, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
792     Local<String> cons4 =
793         String::Concat(cons3, path_str);
794     Local<String> cons5 =
795         String::Concat(cons4, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
796     e = Exception::Error(cons5);
797   } else {
798     e = Exception::Error(cons2);
799   }
800
801   Local<Object> obj = e->ToObject(env->isolate());
802   // TODO(piscisaureus) errno should probably go
803   obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
804   obj->Set(env->code_string(), estring);
805
806   if (path != nullptr) {
807     obj->Set(env->path_string(), path_str);
808   }
809
810   if (syscall != nullptr) {
811     obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
812   }
813
814   return e;
815 }
816
817
818 // Look up environment variable unless running as setuid root.
819 inline const char* secure_getenv(const char* key) {
820 #ifndef _WIN32
821   if (getuid() != geteuid() || getgid() != getegid())
822     return nullptr;
823 #endif
824   return getenv(key);
825 }
826
827
828 #ifdef _WIN32
829 // Does about the same as strerror(),
830 // but supports all windows error messages
831 static const char *winapi_strerror(const int errorno, bool* must_free) {
832   char *errmsg = nullptr;
833
834   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
835       FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
836       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
837
838   if (errmsg) {
839     *must_free = true;
840
841     // Remove trailing newlines
842     for (int i = strlen(errmsg) - 1;
843         i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
844       errmsg[i] = '\0';
845     }
846
847     return errmsg;
848   } else {
849     // FormatMessage failed
850     *must_free = false;
851     return "Unknown error";
852   }
853 }
854
855
856 Local<Value> WinapiErrnoException(Isolate* isolate,
857                                   int errorno,
858                                   const char* syscall,
859                                   const char* msg,
860                                   const char* path) {
861   Environment* env = Environment::GetCurrent(isolate);
862   Local<Value> e;
863   bool must_free = false;
864   if (!msg || !msg[0]) {
865     msg = winapi_strerror(errorno, &must_free);
866   }
867   Local<String> message = OneByteString(env->isolate(), msg);
868
869   if (path) {
870     Local<String> cons1 =
871         String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
872     Local<String> cons2 =
873         String::Concat(cons1, String::NewFromUtf8(isolate, path));
874     Local<String> cons3 =
875         String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
876     e = Exception::Error(cons3);
877   } else {
878     e = Exception::Error(message);
879   }
880
881   Local<Object> obj = e->ToObject(env->isolate());
882   obj->Set(env->errno_string(), Integer::New(isolate, errorno));
883
884   if (path != nullptr) {
885     obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
886   }
887
888   if (syscall != nullptr) {
889     obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
890   }
891
892   if (must_free)
893     LocalFree((HLOCAL)msg);
894
895   return e;
896 }
897 #endif
898
899
900 void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
901   Environment* env = Environment::GetCurrent(args);
902
903   if (env->using_domains())
904     return;
905   env->set_using_domains(true);
906
907   HandleScope scope(env->isolate());
908   Local<Object> process_object = env->process_object();
909
910   Local<String> tick_callback_function_key = env->tick_domain_cb_string();
911   Local<Function> tick_callback_function =
912       process_object->Get(tick_callback_function_key).As<Function>();
913
914   if (!tick_callback_function->IsFunction()) {
915     fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
916     abort();
917   }
918
919   process_object->Set(env->tick_callback_string(), tick_callback_function);
920   env->set_tick_callback_function(tick_callback_function);
921
922   CHECK(args[0]->IsArray());
923   CHECK(args[1]->IsObject());
924
925   env->set_domain_array(args[0].As<Array>());
926
927   Local<Object> domain_flag_obj = args[1].As<Object>();
928   Environment::DomainFlag* domain_flag = env->domain_flag();
929   domain_flag_obj->SetIndexedPropertiesToExternalArrayData(
930       domain_flag->fields(),
931       kExternalUint32Array,
932       domain_flag->fields_count());
933
934   // Do a little housekeeping.
935   env->process_object()->Delete(
936       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse"));
937 }
938
939 void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
940   args.GetIsolate()->RunMicrotasks();
941 }
942
943
944 void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
945   Environment* env = Environment::GetCurrent(args);
946
947   CHECK(args[0]->IsObject());
948   CHECK(args[1]->IsFunction());
949   CHECK(args[2]->IsObject());
950
951   // Values use to cross communicate with processNextTick.
952   Local<Object> tick_info_obj = args[0].As<Object>();
953   tick_info_obj->SetIndexedPropertiesToExternalArrayData(
954       env->tick_info()->fields(),
955       kExternalUint32Array,
956       env->tick_info()->fields_count());
957
958   env->set_tick_callback_function(args[1].As<Function>());
959
960   env->SetMethod(args[2].As<Object>(), "runMicrotasks", RunMicrotasks);
961
962   // Do a little housekeeping.
963   env->process_object()->Delete(
964       FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick"));
965 }
966
967
968 Handle<Value> MakeCallback(Environment* env,
969                            Handle<Value> recv,
970                            const Handle<Function> callback,
971                            int argc,
972                            Handle<Value> argv[]) {
973   // If you hit this assertion, you forgot to enter the v8::Context first.
974   CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
975
976   Local<Object> process = env->process_object();
977   Local<Object> object, domain;
978   bool has_async_queue = false;
979   bool has_domain = false;
980
981   if (recv->IsObject()) {
982     object = recv.As<Object>();
983     Local<Value> async_queue_v = object->Get(env->async_queue_string());
984     if (async_queue_v->IsObject())
985       has_async_queue = true;
986   }
987
988   if (env->using_domains()) {
989     CHECK(recv->IsObject());
990     Local<Value> domain_v = object->Get(env->domain_string());
991     has_domain = domain_v->IsObject();
992     if (has_domain) {
993       domain = domain_v.As<Object>();
994       if (domain->Get(env->disposed_string())->IsTrue())
995         return Undefined(env->isolate());
996     }
997   }
998
999   TryCatch try_catch;
1000   try_catch.SetVerbose(true);
1001
1002   if (has_domain) {
1003     Local<Value> enter_v = domain->Get(env->enter_string());
1004     if (enter_v->IsFunction()) {
1005         enter_v.As<Function>()->Call(domain, 0, nullptr);
1006       if (try_catch.HasCaught())
1007         return Undefined(env->isolate());
1008     }
1009   }
1010
1011   if (has_async_queue) {
1012     try_catch.SetVerbose(false);
1013     env->async_hooks_pre_function()->Call(object, 0, nullptr);
1014     if (try_catch.HasCaught())
1015       FatalError("node:;MakeCallback", "pre hook threw");
1016     try_catch.SetVerbose(true);
1017   }
1018
1019   Local<Value> ret = callback->Call(recv, argc, argv);
1020
1021   if (has_async_queue) {
1022     try_catch.SetVerbose(false);
1023     env->async_hooks_post_function()->Call(object, 0, nullptr);
1024     if (try_catch.HasCaught())
1025       FatalError("node::MakeCallback", "post hook threw");
1026     try_catch.SetVerbose(true);
1027   }
1028
1029   if (has_domain) {
1030     Local<Value> exit_v = domain->Get(env->exit_string());
1031     if (exit_v->IsFunction()) {
1032       exit_v.As<Function>()->Call(domain, 0, nullptr);
1033       if (try_catch.HasCaught())
1034         return Undefined(env->isolate());
1035     }
1036   }
1037   env->tick_callback_function()->Call(process, 0, nullptr);
1038   CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
1039
1040   if (try_catch.HasCaught()) {
1041     return Undefined(env->isolate());
1042   }
1043
1044   Environment::TickInfo* tick_info = env->tick_info();
1045
1046   if (tick_info->in_tick()) {
1047     return ret;
1048   }
1049
1050   if (tick_info->length() == 0) {
1051     env->isolate()->RunMicrotasks();
1052   }
1053
1054   if (tick_info->length() == 0) {
1055     tick_info->set_index(0);
1056     return ret;
1057   }
1058
1059   tick_info->set_in_tick(true);
1060
1061   // process nextTicks after call
1062   env->tick_callback_function()->Call(process, 0, nullptr);
1063
1064   tick_info->set_in_tick(false);
1065
1066   if (try_catch.HasCaught()) {
1067     tick_info->set_last_threw(true);
1068     return Undefined(env->isolate());
1069   }
1070
1071   return ret;
1072 }
1073
1074
1075 // Internal only.
1076 Handle<Value> MakeCallback(Environment* env,
1077                            Handle<Object> recv,
1078                            uint32_t index,
1079                            int argc,
1080                            Handle<Value> argv[]) {
1081   Local<Value> cb_v = recv->Get(index);
1082   CHECK(cb_v->IsFunction());
1083   return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1084 }
1085
1086
1087 Handle<Value> MakeCallback(Environment* env,
1088                            Handle<Object> recv,
1089                            Handle<String> symbol,
1090                            int argc,
1091                            Handle<Value> argv[]) {
1092   Local<Value> cb_v = recv->Get(symbol);
1093   CHECK(cb_v->IsFunction());
1094   return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1095 }
1096
1097
1098 Handle<Value> MakeCallback(Environment* env,
1099                            Handle<Object> recv,
1100                            const char* method,
1101                            int argc,
1102                            Handle<Value> argv[]) {
1103   Local<String> method_string = OneByteString(env->isolate(), method);
1104   return MakeCallback(env, recv, method_string, argc, argv);
1105 }
1106
1107
1108 Handle<Value> MakeCallback(Isolate* isolate,
1109                            Handle<Object> recv,
1110                            const char* method,
1111                            int argc,
1112                            Handle<Value> argv[]) {
1113   EscapableHandleScope handle_scope(isolate);
1114   Local<Context> context = recv->CreationContext();
1115   Environment* env = Environment::GetCurrent(context);
1116   Context::Scope context_scope(context);
1117   return handle_scope.Escape(
1118       Local<Value>::New(isolate, MakeCallback(env, recv, method, argc, argv)));
1119 }
1120
1121
1122 Handle<Value> MakeCallback(Isolate* isolate,
1123                            Handle<Object> recv,
1124                            Handle<String> symbol,
1125                            int argc,
1126                            Handle<Value> argv[]) {
1127   EscapableHandleScope handle_scope(isolate);
1128   Local<Context> context = recv->CreationContext();
1129   Environment* env = Environment::GetCurrent(context);
1130   Context::Scope context_scope(context);
1131   return handle_scope.Escape(
1132       Local<Value>::New(isolate, MakeCallback(env, recv, symbol, argc, argv)));
1133 }
1134
1135
1136 Handle<Value> MakeCallback(Isolate* isolate,
1137                            Handle<Object> recv,
1138                            Handle<Function> callback,
1139                            int argc,
1140                            Handle<Value> argv[]) {
1141   EscapableHandleScope handle_scope(isolate);
1142   Local<Context> context = recv->CreationContext();
1143   Environment* env = Environment::GetCurrent(context);
1144   Context::Scope context_scope(context);
1145   return handle_scope.Escape(Local<Value>::New(
1146         isolate,
1147         MakeCallback(env, recv.As<Value>(), callback, argc, argv)));
1148 }
1149
1150
1151 enum encoding ParseEncoding(Isolate* isolate,
1152                             Handle<Value> encoding_v,
1153                             enum encoding _default) {
1154   HandleScope scope(isolate);
1155
1156   if (!encoding_v->IsString())
1157     return _default;
1158
1159   node::Utf8Value encoding(isolate, encoding_v);
1160
1161   if (strcasecmp(*encoding, "utf8") == 0) {
1162     return UTF8;
1163   } else if (strcasecmp(*encoding, "utf-8") == 0) {
1164     return UTF8;
1165   } else if (strcasecmp(*encoding, "ascii") == 0) {
1166     return ASCII;
1167   } else if (strcasecmp(*encoding, "base64") == 0) {
1168     return BASE64;
1169   } else if (strcasecmp(*encoding, "ucs2") == 0) {
1170     return UCS2;
1171   } else if (strcasecmp(*encoding, "ucs-2") == 0) {
1172     return UCS2;
1173   } else if (strcasecmp(*encoding, "utf16le") == 0) {
1174     return UCS2;
1175   } else if (strcasecmp(*encoding, "utf-16le") == 0) {
1176     return UCS2;
1177   } else if (strcasecmp(*encoding, "binary") == 0) {
1178     return BINARY;
1179   } else if (strcasecmp(*encoding, "buffer") == 0) {
1180     return BUFFER;
1181   } else if (strcasecmp(*encoding, "hex") == 0) {
1182     return HEX;
1183   } else if (strcasecmp(*encoding, "raw") == 0) {
1184     if (!no_deprecation) {
1185       fprintf(stderr, "'raw' (array of integers) has been removed. "
1186                       "Use 'binary'.\n");
1187     }
1188     return BINARY;
1189   } else if (strcasecmp(*encoding, "raws") == 0) {
1190     if (!no_deprecation) {
1191       fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
1192                       "Please update your code.\n");
1193     }
1194     return BINARY;
1195   } else {
1196     return _default;
1197   }
1198 }
1199
1200 Local<Value> Encode(Isolate* isolate,
1201                     const char* buf,
1202                     size_t len,
1203                     enum encoding encoding) {
1204   CHECK_NE(encoding, UCS2);
1205   return StringBytes::Encode(isolate, buf, len, encoding);
1206 }
1207
1208 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1209   return StringBytes::Encode(isolate, buf, len);
1210 }
1211
1212 // Returns -1 if the handle was not valid for decoding
1213 ssize_t DecodeBytes(Isolate* isolate,
1214                     Handle<Value> val,
1215                     enum encoding encoding) {
1216   HandleScope scope(isolate);
1217
1218   if (val->IsArray()) {
1219     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
1220                     "Use 'binary'.\n");
1221     UNREACHABLE();
1222     return -1;
1223   }
1224
1225   return StringBytes::Size(isolate, val, encoding);
1226 }
1227
1228 // Returns number of bytes written.
1229 ssize_t DecodeWrite(Isolate* isolate,
1230                     char* buf,
1231                     size_t buflen,
1232                     Handle<Value> val,
1233                     enum encoding encoding) {
1234   return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
1235 }
1236
1237 void AppendExceptionLine(Environment* env,
1238                          Handle<Value> er,
1239                          Handle<Message> message) {
1240   if (message.IsEmpty())
1241     return;
1242
1243   HandleScope scope(env->isolate());
1244   Local<Object> err_obj;
1245   if (!er.IsEmpty() && er->IsObject()) {
1246     err_obj = er.As<Object>();
1247
1248     // Do it only once per message
1249     if (!err_obj->GetHiddenValue(env->processed_string()).IsEmpty())
1250       return;
1251     err_obj->SetHiddenValue(env->processed_string(), True(env->isolate()));
1252   }
1253
1254   char arrow[1024];
1255
1256   // Print (filename):(line number): (message).
1257   node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1258   const char* filename_string = *filename;
1259   int linenum = message->GetLineNumber();
1260   // Print line of source code.
1261   node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1262   const char* sourceline_string = *sourceline;
1263
1264   // Because of how node modules work, all scripts are wrapped with a
1265   // "function (module, exports, __filename, ...) {"
1266   // to provide script local variables.
1267   //
1268   // When reporting errors on the first line of a script, this wrapper
1269   // function is leaked to the user. There used to be a hack here to
1270   // truncate off the first 62 characters, but it caused numerous other
1271   // problems when vm.runIn*Context() methods were used for non-module
1272   // code.
1273   //
1274   // If we ever decide to re-instate such a hack, the following steps
1275   // must be taken:
1276   //
1277   // 1. Pass a flag around to say "this code was wrapped"
1278   // 2. Update the stack frame output so that it is also correct.
1279   //
1280   // It would probably be simpler to add a line rather than add some
1281   // number of characters to the first line, since V8 truncates the
1282   // sourceline to 78 characters, and we end up not providing very much
1283   // useful debugging info to the user if we remove 62 characters.
1284
1285   int start = message->GetStartColumn();
1286   int end = message->GetEndColumn();
1287
1288   int off = snprintf(arrow,
1289                      sizeof(arrow),
1290                      "%s:%i\n%s\n",
1291                      filename_string,
1292                      linenum,
1293                      sourceline_string);
1294   CHECK_GE(off, 0);
1295
1296   // Print wavy underline (GetUnderline is deprecated).
1297   for (int i = 0; i < start; i++) {
1298     if (sourceline_string[i] == '\0' ||
1299         static_cast<size_t>(off) >= sizeof(arrow)) {
1300       break;
1301     }
1302     CHECK_LT(static_cast<size_t>(off), sizeof(arrow));
1303     arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1304   }
1305   for (int i = start; i < end; i++) {
1306     if (sourceline_string[i] == '\0' ||
1307         static_cast<size_t>(off) >= sizeof(arrow)) {
1308       break;
1309     }
1310     CHECK_LT(static_cast<size_t>(off), sizeof(arrow));
1311     arrow[off++] = '^';
1312   }
1313   CHECK_LE(static_cast<size_t>(off - 1), sizeof(arrow) - 1);
1314   arrow[off++] = '\n';
1315   arrow[off] = '\0';
1316
1317   Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1318   Local<Value> msg;
1319   Local<Value> stack;
1320
1321   // Allocation failed, just print it out
1322   if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
1323     goto print;
1324
1325   msg = err_obj->Get(env->message_string());
1326   stack = err_obj->Get(env->stack_string());
1327
1328   if (msg.IsEmpty() || stack.IsEmpty())
1329     goto print;
1330
1331   err_obj->Set(env->message_string(),
1332                String::Concat(arrow_str, msg->ToString(env->isolate())));
1333   err_obj->Set(env->stack_string(),
1334                String::Concat(arrow_str, stack->ToString(env->isolate())));
1335   return;
1336
1337  print:
1338   if (env->printed_error())
1339     return;
1340   env->set_printed_error(true);
1341   uv_tty_reset_mode();
1342   fprintf(stderr, "\n%s", arrow);
1343 }
1344
1345
1346 static void ReportException(Environment* env,
1347                             Handle<Value> er,
1348                             Handle<Message> message) {
1349   HandleScope scope(env->isolate());
1350
1351   AppendExceptionLine(env, er, message);
1352
1353   Local<Value> trace_value;
1354
1355   if (er->IsUndefined() || er->IsNull())
1356     trace_value = Undefined(env->isolate());
1357   else
1358     trace_value = er->ToObject(env->isolate())->Get(env->stack_string());
1359
1360   node::Utf8Value trace(env->isolate(), trace_value);
1361
1362   // range errors have a trace member set to undefined
1363   if (trace.length() > 0 && !trace_value->IsUndefined()) {
1364     fprintf(stderr, "%s\n", *trace);
1365   } else {
1366     // this really only happens for RangeErrors, since they're the only
1367     // kind that won't have all this info in the trace, or when non-Error
1368     // objects are thrown manually.
1369     Local<Value> message;
1370     Local<Value> name;
1371
1372     if (er->IsObject()) {
1373       Local<Object> err_obj = er.As<Object>();
1374       message = err_obj->Get(env->message_string());
1375       name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
1376     }
1377
1378     if (message.IsEmpty() ||
1379         message->IsUndefined() ||
1380         name.IsEmpty() ||
1381         name->IsUndefined()) {
1382       // Not an error object. Just print as-is.
1383       node::Utf8Value message(env->isolate(), er);
1384       fprintf(stderr, "%s\n", *message);
1385     } else {
1386       node::Utf8Value name_string(env->isolate(), name);
1387       node::Utf8Value message_string(env->isolate(), message);
1388       fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1389     }
1390   }
1391
1392   fflush(stderr);
1393 }
1394
1395
1396 static void ReportException(Environment* env, const TryCatch& try_catch) {
1397   ReportException(env, try_catch.Exception(), try_catch.Message());
1398 }
1399
1400
1401 // Executes a str within the current v8 context.
1402 static Local<Value> ExecuteString(Environment* env,
1403                                   Handle<String> source,
1404                                   Handle<String> filename) {
1405   EscapableHandleScope scope(env->isolate());
1406   TryCatch try_catch;
1407
1408   // try_catch must be nonverbose to disable FatalException() handler,
1409   // we will handle exceptions ourself.
1410   try_catch.SetVerbose(false);
1411
1412   Local<v8::Script> script = v8::Script::Compile(source, filename);
1413   if (script.IsEmpty()) {
1414     ReportException(env, try_catch);
1415     exit(3);
1416   }
1417
1418   Local<Value> result = script->Run();
1419   if (result.IsEmpty()) {
1420     ReportException(env, try_catch);
1421     exit(4);
1422   }
1423
1424   return scope.Escape(result);
1425 }
1426
1427
1428 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1429   Environment* env = Environment::GetCurrent(args);
1430
1431   Local<Array> ary = Array::New(args.GetIsolate());
1432   QUEUE* q = nullptr;
1433   int i = 0;
1434
1435   QUEUE_FOREACH(q, env->req_wrap_queue()) {
1436     ReqWrap<uv_req_t>* w = ContainerOf(&ReqWrap<uv_req_t>::req_wrap_queue_, q);
1437     if (w->persistent().IsEmpty())
1438       continue;
1439     ary->Set(i++, w->object());
1440   }
1441
1442   args.GetReturnValue().Set(ary);
1443 }
1444
1445
1446 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1447 // implemented here for consistency with GetActiveRequests().
1448 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1449   Environment* env = Environment::GetCurrent(args);
1450
1451   Local<Array> ary = Array::New(env->isolate());
1452   QUEUE* q = nullptr;
1453   int i = 0;
1454
1455   Local<String> owner_sym = env->owner_string();
1456
1457   QUEUE_FOREACH(q, env->handle_wrap_queue()) {
1458     HandleWrap* w = ContainerOf(&HandleWrap::handle_wrap_queue_, q);
1459     if (w->persistent().IsEmpty() || (w->flags_ & HandleWrap::kUnref))
1460       continue;
1461     Local<Object> object = w->object();
1462     Local<Value> owner = object->Get(owner_sym);
1463     if (owner->IsUndefined())
1464       owner = object;
1465     ary->Set(i++, owner);
1466   }
1467
1468   args.GetReturnValue().Set(ary);
1469 }
1470
1471
1472 static void Abort(const FunctionCallbackInfo<Value>& args) {
1473   abort();
1474 }
1475
1476
1477 static void Chdir(const FunctionCallbackInfo<Value>& args) {
1478   Environment* env = Environment::GetCurrent(args);
1479
1480   if (args.Length() != 1 || !args[0]->IsString()) {
1481     return env->ThrowTypeError("Bad argument.");
1482   }
1483
1484   node::Utf8Value path(args.GetIsolate(), args[0]);
1485   int err = uv_chdir(*path);
1486   if (err) {
1487     return env->ThrowUVException(err, "uv_chdir");
1488   }
1489 }
1490
1491
1492 static void Cwd(const FunctionCallbackInfo<Value>& args) {
1493   Environment* env = Environment::GetCurrent(args);
1494 #ifdef _WIN32
1495   /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
1496   char buf[MAX_PATH * 4];
1497 #else
1498   char buf[PATH_MAX];
1499 #endif
1500
1501   size_t cwd_len = sizeof(buf);
1502   int err = uv_cwd(buf, &cwd_len);
1503   if (err) {
1504     return env->ThrowUVException(err, "uv_cwd");
1505   }
1506
1507   Local<String> cwd = String::NewFromUtf8(env->isolate(),
1508                                           buf,
1509                                           String::kNormalString,
1510                                           cwd_len);
1511   args.GetReturnValue().Set(cwd);
1512 }
1513
1514
1515 static void Umask(const FunctionCallbackInfo<Value>& args) {
1516   Environment* env = Environment::GetCurrent(args);
1517   uint32_t old;
1518
1519   if (args.Length() < 1 || args[0]->IsUndefined()) {
1520     old = umask(0);
1521     umask(static_cast<mode_t>(old));
1522   } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1523     return env->ThrowTypeError("argument must be an integer or octal string.");
1524   } else {
1525     int oct;
1526     if (args[0]->IsInt32()) {
1527       oct = args[0]->Uint32Value();
1528     } else {
1529       oct = 0;
1530       node::Utf8Value str(env->isolate(), args[0]);
1531
1532       // Parse the octal string.
1533       for (size_t i = 0; i < str.length(); i++) {
1534         char c = (*str)[i];
1535         if (c > '7' || c < '0') {
1536           return env->ThrowTypeError("invalid octal string");
1537         }
1538         oct *= 8;
1539         oct += c - '0';
1540       }
1541     }
1542     old = umask(static_cast<mode_t>(oct));
1543   }
1544
1545   args.GetReturnValue().Set(old);
1546 }
1547
1548
1549 #if defined(__POSIX__) && !defined(__ANDROID__)
1550
1551 static const uid_t uid_not_found = static_cast<uid_t>(-1);
1552 static const gid_t gid_not_found = static_cast<gid_t>(-1);
1553
1554
1555 static uid_t uid_by_name(const char* name) {
1556   struct passwd pwd;
1557   struct passwd* pp;
1558   char buf[8192];
1559
1560   errno = 0;
1561   pp = nullptr;
1562
1563   if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1564     return pp->pw_uid;
1565   }
1566
1567   return uid_not_found;
1568 }
1569
1570
1571 static char* name_by_uid(uid_t uid) {
1572   struct passwd pwd;
1573   struct passwd* pp;
1574   char buf[8192];
1575   int rc;
1576
1577   errno = 0;
1578   pp = nullptr;
1579
1580   if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1581       pp != nullptr) {
1582     return strdup(pp->pw_name);
1583   }
1584
1585   if (rc == 0) {
1586     errno = ENOENT;
1587   }
1588
1589   return nullptr;
1590 }
1591
1592
1593 static gid_t gid_by_name(const char* name) {
1594   struct group pwd;
1595   struct group* pp;
1596   char buf[8192];
1597
1598   errno = 0;
1599   pp = nullptr;
1600
1601   if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1602     return pp->gr_gid;
1603   }
1604
1605   return gid_not_found;
1606 }
1607
1608
1609 #if 0  // For future use.
1610 static const char* name_by_gid(gid_t gid) {
1611   struct group pwd;
1612   struct group* pp;
1613   char buf[8192];
1614   int rc;
1615
1616   errno = 0;
1617   pp = nullptr;
1618
1619   if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1620       pp != nullptr) {
1621     return strdup(pp->gr_name);
1622   }
1623
1624   if (rc == 0) {
1625     errno = ENOENT;
1626   }
1627
1628   return nullptr;
1629 }
1630 #endif
1631
1632
1633 static uid_t uid_by_name(Handle<Value> value) {
1634   if (value->IsUint32()) {
1635     return static_cast<uid_t>(value->Uint32Value());
1636   } else {
1637     // TODO(trevnorris): Fix to not use GetCurrent().
1638     node::Utf8Value name(Isolate::GetCurrent(), value);
1639     return uid_by_name(*name);
1640   }
1641 }
1642
1643
1644 static gid_t gid_by_name(Handle<Value> value) {
1645   if (value->IsUint32()) {
1646     return static_cast<gid_t>(value->Uint32Value());
1647   } else {
1648     // TODO(trevnorris): Fix to not use GetCurrent().
1649     node::Utf8Value name(Isolate::GetCurrent(), value);
1650     return gid_by_name(*name);
1651   }
1652 }
1653
1654
1655 static void GetUid(const FunctionCallbackInfo<Value>& args) {
1656   // uid_t is an uint32_t on all supported platforms.
1657   args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
1658 }
1659
1660
1661 static void GetGid(const FunctionCallbackInfo<Value>& args) {
1662   // gid_t is an uint32_t on all supported platforms.
1663   args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
1664 }
1665
1666
1667 static void SetGid(const FunctionCallbackInfo<Value>& args) {
1668   Environment* env = Environment::GetCurrent(args);
1669
1670   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1671     return env->ThrowTypeError("setgid argument must be a number or a string");
1672   }
1673
1674   gid_t gid = gid_by_name(args[0]);
1675
1676   if (gid == gid_not_found) {
1677     return env->ThrowError("setgid group id does not exist");
1678   }
1679
1680   if (setgid(gid)) {
1681     return env->ThrowErrnoException(errno, "setgid");
1682   }
1683 }
1684
1685
1686 static void SetUid(const FunctionCallbackInfo<Value>& args) {
1687   Environment* env = Environment::GetCurrent(args);
1688
1689   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1690     return env->ThrowTypeError("setuid argument must be a number or a string");
1691   }
1692
1693   uid_t uid = uid_by_name(args[0]);
1694
1695   if (uid == uid_not_found) {
1696     return env->ThrowError("setuid user id does not exist");
1697   }
1698
1699   if (setuid(uid)) {
1700     return env->ThrowErrnoException(errno, "setuid");
1701   }
1702 }
1703
1704
1705 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
1706   Environment* env = Environment::GetCurrent(args);
1707
1708   int ngroups = getgroups(0, nullptr);
1709
1710   if (ngroups == -1) {
1711     return env->ThrowErrnoException(errno, "getgroups");
1712   }
1713
1714   gid_t* groups = new gid_t[ngroups];
1715
1716   ngroups = getgroups(ngroups, groups);
1717
1718   if (ngroups == -1) {
1719     delete[] groups;
1720     return env->ThrowErrnoException(errno, "getgroups");
1721   }
1722
1723   Local<Array> groups_list = Array::New(env->isolate(), ngroups);
1724   bool seen_egid = false;
1725   gid_t egid = getegid();
1726
1727   for (int i = 0; i < ngroups; i++) {
1728     groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
1729     if (groups[i] == egid)
1730       seen_egid = true;
1731   }
1732
1733   delete[] groups;
1734
1735   if (seen_egid == false) {
1736     groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
1737   }
1738
1739   args.GetReturnValue().Set(groups_list);
1740 }
1741
1742
1743 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
1744   Environment* env = Environment::GetCurrent(args);
1745
1746   if (!args[0]->IsArray()) {
1747     return env->ThrowTypeError("argument 1 must be an array");
1748   }
1749
1750   Local<Array> groups_list = args[0].As<Array>();
1751   size_t size = groups_list->Length();
1752   gid_t* groups = new gid_t[size];
1753
1754   for (size_t i = 0; i < size; i++) {
1755     gid_t gid = gid_by_name(groups_list->Get(i));
1756
1757     if (gid == gid_not_found) {
1758       delete[] groups;
1759       return env->ThrowError("group name not found");
1760     }
1761
1762     groups[i] = gid;
1763   }
1764
1765   int rc = setgroups(size, groups);
1766   delete[] groups;
1767
1768   if (rc == -1) {
1769     return env->ThrowErrnoException(errno, "setgroups");
1770   }
1771 }
1772
1773
1774 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
1775   Environment* env = Environment::GetCurrent(args);
1776
1777   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1778     return env->ThrowTypeError("argument 1 must be a number or a string");
1779   }
1780
1781   if (!args[1]->IsUint32() && !args[1]->IsString()) {
1782     return env->ThrowTypeError("argument 2 must be a number or a string");
1783   }
1784
1785   node::Utf8Value arg0(env->isolate(), args[0]);
1786   gid_t extra_group;
1787   bool must_free;
1788   char* user;
1789
1790   if (args[0]->IsUint32()) {
1791     user = name_by_uid(args[0]->Uint32Value());
1792     must_free = true;
1793   } else {
1794     user = *arg0;
1795     must_free = false;
1796   }
1797
1798   if (user == nullptr) {
1799     return env->ThrowError("initgroups user not found");
1800   }
1801
1802   extra_group = gid_by_name(args[1]);
1803
1804   if (extra_group == gid_not_found) {
1805     if (must_free)
1806       free(user);
1807     return env->ThrowError("initgroups extra group not found");
1808   }
1809
1810   int rc = initgroups(user, extra_group);
1811
1812   if (must_free) {
1813     free(user);
1814   }
1815
1816   if (rc) {
1817     return env->ThrowErrnoException(errno, "initgroups");
1818   }
1819 }
1820
1821 #endif  // __POSIX__ && !defined(__ANDROID__)
1822
1823
1824 void Exit(const FunctionCallbackInfo<Value>& args) {
1825   exit(args[0]->Int32Value());
1826 }
1827
1828
1829 static void Uptime(const FunctionCallbackInfo<Value>& args) {
1830   Environment* env = Environment::GetCurrent(args);
1831   double uptime;
1832
1833   uv_update_time(env->event_loop());
1834   uptime = uv_now(env->event_loop()) - prog_start_time;
1835
1836   args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
1837 }
1838
1839
1840 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
1841   Environment* env = Environment::GetCurrent(args);
1842
1843   size_t rss;
1844   int err = uv_resident_set_memory(&rss);
1845   if (err) {
1846     return env->ThrowUVException(err, "uv_resident_set_memory");
1847   }
1848
1849   // V8 memory usage
1850   HeapStatistics v8_heap_stats;
1851   env->isolate()->GetHeapStatistics(&v8_heap_stats);
1852
1853   Local<Integer> heap_total =
1854       Integer::NewFromUnsigned(env->isolate(), v8_heap_stats.total_heap_size());
1855   Local<Integer> heap_used =
1856       Integer::NewFromUnsigned(env->isolate(), v8_heap_stats.used_heap_size());
1857
1858   Local<Object> info = Object::New(env->isolate());
1859   info->Set(env->rss_string(), Number::New(env->isolate(), rss));
1860   info->Set(env->heap_total_string(), heap_total);
1861   info->Set(env->heap_used_string(), heap_used);
1862
1863   args.GetReturnValue().Set(info);
1864 }
1865
1866
1867 void Kill(const FunctionCallbackInfo<Value>& args) {
1868   Environment* env = Environment::GetCurrent(args);
1869
1870   if (args.Length() != 2) {
1871     return env->ThrowError("Bad argument.");
1872   }
1873
1874   int pid = args[0]->Int32Value();
1875   int sig = args[1]->Int32Value();
1876   int err = uv_kill(pid, sig);
1877   args.GetReturnValue().Set(err);
1878 }
1879
1880 // used in Hrtime() below
1881 #define NANOS_PER_SEC 1000000000
1882
1883 // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
1884 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
1885 // so this function instead returns an Array with 2 entries representing seconds
1886 // and nanoseconds, to avoid any integer overflow possibility.
1887 // Pass in an Array from a previous hrtime() call to instead get a time diff.
1888 void Hrtime(const FunctionCallbackInfo<Value>& args) {
1889   Environment* env = Environment::GetCurrent(args);
1890
1891   uint64_t t = uv_hrtime();
1892
1893   if (args.Length() > 0) {
1894     // return a time diff tuple
1895     if (!args[0]->IsArray()) {
1896       return env->ThrowTypeError(
1897           "process.hrtime() only accepts an Array tuple.");
1898     }
1899     Local<Array> inArray = Local<Array>::Cast(args[0]);
1900     uint64_t seconds = inArray->Get(0)->Uint32Value();
1901     uint64_t nanos = inArray->Get(1)->Uint32Value();
1902     t -= (seconds * NANOS_PER_SEC) + nanos;
1903   }
1904
1905   Local<Array> tuple = Array::New(env->isolate(), 2);
1906   tuple->Set(0, Integer::NewFromUnsigned(env->isolate(), t / NANOS_PER_SEC));
1907   tuple->Set(1, Integer::NewFromUnsigned(env->isolate(), t % NANOS_PER_SEC));
1908   args.GetReturnValue().Set(tuple);
1909 }
1910
1911 extern "C" void node_module_register(void* m) {
1912   struct node_module* mp = reinterpret_cast<struct node_module*>(m);
1913
1914   if (mp->nm_flags & NM_F_BUILTIN) {
1915     mp->nm_link = modlist_builtin;
1916     modlist_builtin = mp;
1917   } else if (!node_is_initialized) {
1918     // "Linked" modules are included as part of the node project.
1919     // Like builtins they are registered *before* node::Init runs.
1920     mp->nm_flags = NM_F_LINKED;
1921     mp->nm_link = modlist_linked;
1922     modlist_linked = mp;
1923   } else {
1924     modpending = mp;
1925   }
1926 }
1927
1928 struct node_module* get_builtin_module(const char* name) {
1929   struct node_module* mp;
1930
1931   for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) {
1932     if (strcmp(mp->nm_modname, name) == 0)
1933       break;
1934   }
1935
1936   CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0);
1937   return (mp);
1938 }
1939
1940 struct node_module* get_linked_module(const char* name) {
1941   struct node_module* mp;
1942
1943   for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) {
1944     if (strcmp(mp->nm_modname, name) == 0)
1945       break;
1946   }
1947
1948   CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0);
1949   return mp;
1950 }
1951
1952 typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
1953
1954 // DLOpen is process.dlopen(module, filename).
1955 // Used to load 'module.node' dynamically shared objects.
1956 //
1957 // FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
1958 // when two contexts try to load the same shared object. Maybe have a shadow
1959 // cache that's a plain C list or hash table that's shared across contexts?
1960 void DLOpen(const FunctionCallbackInfo<Value>& args) {
1961   Environment* env = Environment::GetCurrent(args);
1962   uv_lib_t lib;
1963
1964   CHECK_EQ(modpending, nullptr);
1965
1966   if (args.Length() < 2) {
1967     env->ThrowError("process.dlopen takes exactly 2 arguments.");
1968     return;
1969   }
1970
1971   Local<Object> module = args[0]->ToObject(env->isolate());  // Cast
1972   node::Utf8Value filename(env->isolate(), args[1]);  // Cast
1973   const bool is_dlopen_error = uv_dlopen(*filename, &lib);
1974
1975   // Objects containing v14 or later modules will have registered themselves
1976   // on the pending list.  Activate all of them now.  At present, only one
1977   // module per object is supported.
1978   node_module* const mp = modpending;
1979   modpending = nullptr;
1980
1981   if (is_dlopen_error) {
1982     Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
1983 #ifdef _WIN32
1984     // Windows needs to add the filename into the error message
1985     errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
1986 #endif  // _WIN32
1987     env->isolate()->ThrowException(Exception::Error(errmsg));
1988     return;
1989   }
1990
1991   if (mp == nullptr) {
1992     env->ThrowError("Module did not self-register.");
1993     return;
1994   }
1995   if (mp->nm_version != NODE_MODULE_VERSION) {
1996     char errmsg[1024];
1997     snprintf(errmsg,
1998              sizeof(errmsg),
1999              "Module version mismatch. Expected %d, got %d.",
2000              NODE_MODULE_VERSION, mp->nm_version);
2001     env->ThrowError(errmsg);
2002     return;
2003   }
2004   if (mp->nm_flags & NM_F_BUILTIN) {
2005     env->ThrowError("Built-in module self-registered.");
2006     return;
2007   }
2008
2009   mp->nm_dso_handle = lib.handle;
2010   mp->nm_link = modlist_addon;
2011   modlist_addon = mp;
2012
2013   Local<String> exports_string = env->exports_string();
2014   Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2015
2016   if (mp->nm_context_register_func != nullptr) {
2017     mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2018   } else if (mp->nm_register_func != nullptr) {
2019     mp->nm_register_func(exports, module, mp->nm_priv);
2020   } else {
2021     env->ThrowError("Module has no declared entry point.");
2022     return;
2023   }
2024
2025   // Tell coverity that 'handle' should not be freed when we return.
2026   // coverity[leaked_storage]
2027 }
2028
2029
2030 static void OnFatalError(const char* location, const char* message) {
2031   if (location) {
2032     fprintf(stderr, "FATAL ERROR: %s %s\n", location, message);
2033   } else {
2034     fprintf(stderr, "FATAL ERROR: %s\n", message);
2035   }
2036   fflush(stderr);
2037   abort();
2038 }
2039
2040
2041 NO_RETURN void FatalError(const char* location, const char* message) {
2042   OnFatalError(location, message);
2043   // to supress compiler warning
2044   abort();
2045 }
2046
2047
2048 void FatalException(Isolate* isolate,
2049                     Handle<Value> error,
2050                     Handle<Message> message) {
2051   HandleScope scope(isolate);
2052
2053   Environment* env = Environment::GetCurrent(isolate);
2054   Local<Object> process_object = env->process_object();
2055   Local<String> fatal_exception_string = env->fatal_exception_string();
2056   Local<Function> fatal_exception_function =
2057       process_object->Get(fatal_exception_string).As<Function>();
2058
2059   if (!fatal_exception_function->IsFunction()) {
2060     // failed before the process._fatalException function was added!
2061     // this is probably pretty bad.  Nothing to do but report and exit.
2062     ReportException(env, error, message);
2063     exit(6);
2064   }
2065
2066   TryCatch fatal_try_catch;
2067
2068   // Do not call FatalException when _fatalException handler throws
2069   fatal_try_catch.SetVerbose(false);
2070
2071   // this will return true if the JS layer handled it, false otherwise
2072   Local<Value> caught =
2073       fatal_exception_function->Call(process_object, 1, &error);
2074
2075   if (fatal_try_catch.HasCaught()) {
2076     // the fatal exception function threw, so we must exit
2077     ReportException(env, fatal_try_catch);
2078     exit(7);
2079   }
2080
2081   if (false == caught->BooleanValue()) {
2082     ReportException(env, error, message);
2083     exit(1);
2084   }
2085 }
2086
2087
2088 void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2089   HandleScope scope(isolate);
2090   // TODO(bajtos) do not call FatalException if try_catch is verbose
2091   // (requires V8 API to expose getter for try_catch.is_verbose_)
2092   FatalException(isolate, try_catch.Exception(), try_catch.Message());
2093 }
2094
2095
2096 void OnMessage(Handle<Message> message, Handle<Value> error) {
2097   // The current version of V8 sends messages for errors only
2098   // (thus `error` is always set).
2099   FatalException(Isolate::GetCurrent(), error, message);
2100 }
2101
2102
2103 static void Binding(const FunctionCallbackInfo<Value>& args) {
2104   Environment* env = Environment::GetCurrent(args);
2105
2106   Local<String> module = args[0]->ToString(env->isolate());
2107   node::Utf8Value module_v(env->isolate(), module);
2108
2109   Local<Object> cache = env->binding_cache_object();
2110   Local<Object> exports;
2111
2112   if (cache->Has(module)) {
2113     exports = cache->Get(module)->ToObject(env->isolate());
2114     args.GetReturnValue().Set(exports);
2115     return;
2116   }
2117
2118   // Append a string to process.moduleLoadList
2119   char buf[1024];
2120   snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2121
2122   Local<Array> modules = env->module_load_list_array();
2123   uint32_t l = modules->Length();
2124   modules->Set(l, OneByteString(env->isolate(), buf));
2125
2126   node_module* mod = get_builtin_module(*module_v);
2127   if (mod != nullptr) {
2128     exports = Object::New(env->isolate());
2129     // Internal bindings don't have a "module" object, only exports.
2130     CHECK_EQ(mod->nm_register_func, nullptr);
2131     CHECK_NE(mod->nm_context_register_func, nullptr);
2132     Local<Value> unused = Undefined(env->isolate());
2133     mod->nm_context_register_func(exports, unused,
2134       env->context(), mod->nm_priv);
2135     cache->Set(module, exports);
2136   } else if (!strcmp(*module_v, "constants")) {
2137     exports = Object::New(env->isolate());
2138     DefineConstants(exports);
2139     cache->Set(module, exports);
2140   } else if (!strcmp(*module_v, "natives")) {
2141     exports = Object::New(env->isolate());
2142     DefineJavaScript(env, exports);
2143     cache->Set(module, exports);
2144   } else {
2145     char errmsg[1024];
2146     snprintf(errmsg,
2147              sizeof(errmsg),
2148              "No such module: %s",
2149              *module_v);
2150     return env->ThrowError(errmsg);
2151   }
2152
2153   args.GetReturnValue().Set(exports);
2154 }
2155
2156 static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2157   Environment* env = Environment::GetCurrent(args.GetIsolate());
2158
2159   Local<String> module = args[0]->ToString(env->isolate());
2160
2161   Local<Object> cache = env->binding_cache_object();
2162   Local<Value> exports_v = cache->Get(module);
2163
2164   if (exports_v->IsObject())
2165     return args.GetReturnValue().Set(exports_v.As<Object>());
2166
2167   node::Utf8Value module_v(env->isolate(), module);
2168   node_module* mod = get_linked_module(*module_v);
2169
2170   if (mod == nullptr) {
2171     char errmsg[1024];
2172     snprintf(errmsg,
2173              sizeof(errmsg),
2174              "No such module was linked: %s",
2175              *module_v);
2176     return env->ThrowError(errmsg);
2177   }
2178
2179   Local<Object> exports = Object::New(env->isolate());
2180
2181   if (mod->nm_context_register_func != nullptr) {
2182     mod->nm_context_register_func(exports,
2183                                   module,
2184                                   env->context(),
2185                                   mod->nm_priv);
2186   } else if (mod->nm_register_func != nullptr) {
2187     mod->nm_register_func(exports, module, mod->nm_priv);
2188   } else {
2189     return env->ThrowError("Linked module has no declared entry point.");
2190   }
2191
2192   cache->Set(module, exports);
2193
2194   args.GetReturnValue().Set(exports);
2195 }
2196
2197 static void ProcessTitleGetter(Local<String> property,
2198                                const PropertyCallbackInfo<Value>& info) {
2199   Environment* env = Environment::GetCurrent(info.GetIsolate());
2200   HandleScope scope(env->isolate());
2201   char buffer[512];
2202   uv_get_process_title(buffer, sizeof(buffer));
2203   info.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), buffer));
2204 }
2205
2206
2207 static void ProcessTitleSetter(Local<String> property,
2208                                Local<Value> value,
2209                                const PropertyCallbackInfo<void>& info) {
2210   Environment* env = Environment::GetCurrent(info.GetIsolate());
2211   HandleScope scope(env->isolate());
2212   node::Utf8Value title(env->isolate(), value);
2213   // TODO(piscisaureus): protect with a lock
2214   uv_set_process_title(*title);
2215 }
2216
2217
2218 static void EnvGetter(Local<String> property,
2219                       const PropertyCallbackInfo<Value>& info) {
2220   Environment* env = Environment::GetCurrent(info.GetIsolate());
2221   HandleScope scope(env->isolate());
2222 #ifdef __POSIX__
2223   node::Utf8Value key(env->isolate(), property);
2224   const char* val = getenv(*key);
2225   if (val) {
2226     return info.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), val));
2227   }
2228 #else  // _WIN32
2229   String::Value key(property);
2230   WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2231   DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2232                                          buffer,
2233                                          ARRAY_SIZE(buffer));
2234   // If result >= sizeof buffer the buffer was too small. That should never
2235   // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2236   // not found.
2237   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2238       result < ARRAY_SIZE(buffer)) {
2239     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2240     Local<String> rc = String::NewFromTwoByte(env->isolate(), two_byte_buffer);
2241     return info.GetReturnValue().Set(rc);
2242   }
2243 #endif
2244   // Not found.  Fetch from prototype.
2245   info.GetReturnValue().Set(
2246       info.Data().As<Object>()->Get(property));
2247 }
2248
2249
2250 static void EnvSetter(Local<String> property,
2251                       Local<Value> value,
2252                       const PropertyCallbackInfo<Value>& info) {
2253   Environment* env = Environment::GetCurrent(info.GetIsolate());
2254   HandleScope scope(env->isolate());
2255 #ifdef __POSIX__
2256   node::Utf8Value key(env->isolate(), property);
2257   node::Utf8Value val(env->isolate(), value);
2258   setenv(*key, *val, 1);
2259 #else  // _WIN32
2260   String::Value key(property);
2261   String::Value val(value);
2262   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2263   // Environment variables that start with '=' are read-only.
2264   if (key_ptr[0] != L'=') {
2265     SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2266   }
2267 #endif
2268   // Whether it worked or not, always return rval.
2269   info.GetReturnValue().Set(value);
2270 }
2271
2272
2273 static void EnvQuery(Local<String> property,
2274                      const PropertyCallbackInfo<Integer>& info) {
2275   Environment* env = Environment::GetCurrent(info.GetIsolate());
2276   HandleScope scope(env->isolate());
2277   int32_t rc = -1;  // Not found unless proven otherwise.
2278 #ifdef __POSIX__
2279   node::Utf8Value key(env->isolate(), property);
2280   if (getenv(*key))
2281     rc = 0;
2282 #else  // _WIN32
2283   String::Value key(property);
2284   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2285   if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2286       GetLastError() == ERROR_SUCCESS) {
2287     rc = 0;
2288     if (key_ptr[0] == L'=') {
2289       // Environment variables that start with '=' are hidden and read-only.
2290       rc = static_cast<int32_t>(v8::ReadOnly) |
2291            static_cast<int32_t>(v8::DontDelete) |
2292            static_cast<int32_t>(v8::DontEnum);
2293     }
2294   }
2295 #endif
2296   if (rc != -1)
2297     info.GetReturnValue().Set(rc);
2298 }
2299
2300
2301 static void EnvDeleter(Local<String> property,
2302                        const PropertyCallbackInfo<Boolean>& info) {
2303   Environment* env = Environment::GetCurrent(info.GetIsolate());
2304   HandleScope scope(env->isolate());
2305   bool rc = true;
2306 #ifdef __POSIX__
2307   node::Utf8Value key(env->isolate(), property);
2308   rc = getenv(*key) != nullptr;
2309   if (rc)
2310     unsetenv(*key);
2311 #else
2312   String::Value key(property);
2313   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2314   if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, nullptr)) {
2315     // Deletion failed. Return true if the key wasn't there in the first place,
2316     // false if it is still there.
2317     rc = GetEnvironmentVariableW(key_ptr, nullptr, 0) == 0 &&
2318          GetLastError() != ERROR_SUCCESS;
2319   }
2320 #endif
2321   info.GetReturnValue().Set(rc);
2322 }
2323
2324
2325 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2326   Environment* env = Environment::GetCurrent(info.GetIsolate());
2327   HandleScope scope(env->isolate());
2328 #ifdef __POSIX__
2329   int size = 0;
2330   while (environ[size])
2331     size++;
2332
2333   Local<Array> envarr = Array::New(env->isolate(), size);
2334
2335   for (int i = 0; i < size; ++i) {
2336     const char* var = environ[i];
2337     const char* s = strchr(var, '=');
2338     const int length = s ? s - var : strlen(var);
2339     Local<String> name = String::NewFromUtf8(env->isolate(),
2340                                              var,
2341                                              String::kNormalString,
2342                                              length);
2343     envarr->Set(i, name);
2344   }
2345 #else  // _WIN32
2346   WCHAR* environment = GetEnvironmentStringsW();
2347   if (environment == nullptr)
2348     return;  // This should not happen.
2349   Local<Array> envarr = Array::New(env->isolate());
2350   WCHAR* p = environment;
2351   int i = 0;
2352   while (*p) {
2353     WCHAR *s;
2354     if (*p == L'=') {
2355       // If the key starts with '=' it is a hidden environment variable.
2356       p += wcslen(p) + 1;
2357       continue;
2358     } else {
2359       s = wcschr(p, L'=');
2360     }
2361     if (!s) {
2362       s = p + wcslen(p);
2363     }
2364     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2365     const size_t two_byte_buffer_len = s - p;
2366     Local<String> value = String::NewFromTwoByte(env->isolate(),
2367                                                  two_byte_buffer,
2368                                                  String::kNormalString,
2369                                                  two_byte_buffer_len);
2370     envarr->Set(i++, value);
2371     p = s + wcslen(s) + 1;
2372   }
2373   FreeEnvironmentStringsW(environment);
2374 #endif
2375
2376   info.GetReturnValue().Set(envarr);
2377 }
2378
2379
2380 static Handle<Object> GetFeatures(Environment* env) {
2381   EscapableHandleScope scope(env->isolate());
2382
2383   Local<Object> obj = Object::New(env->isolate());
2384 #if defined(DEBUG) && DEBUG
2385   Local<Value> debug = True(env->isolate());
2386 #else
2387   Local<Value> debug = False(env->isolate());
2388 #endif  // defined(DEBUG) && DEBUG
2389
2390   obj->Set(env->debug_string(), debug);
2391
2392   obj->Set(env->uv_string(), True(env->isolate()));
2393   // TODO(bnoordhuis) ping libuv
2394   obj->Set(env->ipv6_lc_string(), True(env->isolate()));
2395
2396 #ifdef OPENSSL_NPN_NEGOTIATED
2397   Local<Boolean> tls_npn = True(env->isolate());
2398 #else
2399   Local<Boolean> tls_npn = False(env->isolate());
2400 #endif
2401   obj->Set(env->tls_npn_string(), tls_npn);
2402
2403 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2404   Local<Boolean> tls_sni = True(env->isolate());
2405 #else
2406   Local<Boolean> tls_sni = False(env->isolate());
2407 #endif
2408   obj->Set(env->tls_sni_string(), tls_sni);
2409
2410 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2411   Local<Boolean> tls_ocsp = True(env->isolate());
2412 #else
2413   Local<Boolean> tls_ocsp = False(env->isolate());
2414 #endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2415   obj->Set(env->tls_ocsp_string(), tls_ocsp);
2416
2417   obj->Set(env->tls_string(),
2418            Boolean::New(env->isolate(),
2419                         get_builtin_module("crypto") != nullptr));
2420
2421   return scope.Escape(obj);
2422 }
2423
2424
2425 static void DebugPortGetter(Local<String> property,
2426                             const PropertyCallbackInfo<Value>& info) {
2427   Environment* env = Environment::GetCurrent(info.GetIsolate());
2428   HandleScope scope(env->isolate());
2429   info.GetReturnValue().Set(debug_port);
2430 }
2431
2432
2433 static void DebugPortSetter(Local<String> property,
2434                             Local<Value> value,
2435                             const PropertyCallbackInfo<void>& info) {
2436   Environment* env = Environment::GetCurrent(info.GetIsolate());
2437   HandleScope scope(env->isolate());
2438   debug_port = value->Int32Value();
2439 }
2440
2441
2442 static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2443 static void DebugPause(const FunctionCallbackInfo<Value>& args);
2444 static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2445
2446
2447 void NeedImmediateCallbackGetter(Local<String> property,
2448                                  const PropertyCallbackInfo<Value>& info) {
2449   Environment* env = Environment::GetCurrent(info.GetIsolate());
2450   const uv_check_t* immediate_check_handle = env->immediate_check_handle();
2451   bool active = uv_is_active(
2452       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2453   info.GetReturnValue().Set(active);
2454 }
2455
2456
2457 static void NeedImmediateCallbackSetter(
2458     Local<String> property,
2459     Local<Value> value,
2460     const PropertyCallbackInfo<void>& info) {
2461   HandleScope handle_scope(info.GetIsolate());
2462   Environment* env = Environment::GetCurrent(info.GetIsolate());
2463
2464   uv_check_t* immediate_check_handle = env->immediate_check_handle();
2465   bool active = uv_is_active(
2466       reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2467
2468   if (active == value->BooleanValue())
2469     return;
2470
2471   uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
2472
2473   if (active) {
2474     uv_check_stop(immediate_check_handle);
2475     uv_idle_stop(immediate_idle_handle);
2476   } else {
2477     uv_check_start(immediate_check_handle, CheckImmediate);
2478     // Idle handle is needed only to stop the event loop from blocking in poll.
2479     uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
2480   }
2481 }
2482
2483
2484 void SetIdle(uv_prepare_t* handle) {
2485   Environment* env = Environment::from_idle_prepare_handle(handle);
2486   env->isolate()->GetCpuProfiler()->SetIdle(true);
2487 }
2488
2489
2490 void ClearIdle(uv_check_t* handle) {
2491   Environment* env = Environment::from_idle_check_handle(handle);
2492   env->isolate()->GetCpuProfiler()->SetIdle(false);
2493 }
2494
2495
2496 void StartProfilerIdleNotifier(Environment* env) {
2497   uv_prepare_start(env->idle_prepare_handle(), SetIdle);
2498   uv_check_start(env->idle_check_handle(), ClearIdle);
2499 }
2500
2501
2502 void StopProfilerIdleNotifier(Environment* env) {
2503   uv_prepare_stop(env->idle_prepare_handle());
2504   uv_check_stop(env->idle_check_handle());
2505 }
2506
2507
2508 void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2509   Environment* env = Environment::GetCurrent(args);
2510   StartProfilerIdleNotifier(env);
2511 }
2512
2513
2514 void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2515   Environment* env = Environment::GetCurrent(args);
2516   StopProfilerIdleNotifier(env);
2517 }
2518
2519
2520 #define READONLY_PROPERTY(obj, str, var)                                      \
2521   do {                                                                        \
2522     obj->ForceSet(OneByteString(env->isolate(), str), var, v8::ReadOnly);     \
2523   } while (0)
2524
2525
2526 void SetupProcessObject(Environment* env,
2527                         int argc,
2528                         const char* const* argv,
2529                         int exec_argc,
2530                         const char* const* exec_argv) {
2531   HandleScope scope(env->isolate());
2532
2533   Local<Object> process = env->process_object();
2534
2535   process->SetAccessor(env->title_string(),
2536                        ProcessTitleGetter,
2537                        ProcessTitleSetter);
2538
2539   // process.version
2540   READONLY_PROPERTY(process,
2541                     "version",
2542                     FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
2543
2544   // process.moduleLoadList
2545   READONLY_PROPERTY(process,
2546                     "moduleLoadList",
2547                     env->module_load_list_array());
2548
2549   // process.versions
2550   Local<Object> versions = Object::New(env->isolate());
2551   READONLY_PROPERTY(process, "versions", versions);
2552
2553   const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
2554                                      "."
2555                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR);
2556   READONLY_PROPERTY(versions,
2557                     "http_parser",
2558                     FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
2559
2560   // +1 to get rid of the leading 'v'
2561   READONLY_PROPERTY(versions,
2562                     "node",
2563                     OneByteString(env->isolate(), NODE_VERSION + 1));
2564   READONLY_PROPERTY(versions,
2565                     "v8",
2566                     OneByteString(env->isolate(), V8::GetVersion()));
2567   READONLY_PROPERTY(versions,
2568                     "uv",
2569                     OneByteString(env->isolate(), uv_version_string()));
2570   READONLY_PROPERTY(versions,
2571                     "zlib",
2572                     FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
2573   READONLY_PROPERTY(versions,
2574                     "ares",
2575                     FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
2576
2577   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
2578   READONLY_PROPERTY(
2579       versions,
2580       "modules",
2581       FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
2582
2583 #if HAVE_OPENSSL
2584   // Stupid code to slice out the version string.
2585   {  // NOLINT(whitespace/braces)
2586     size_t i, j, k;
2587     int c;
2588     for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
2589       c = OPENSSL_VERSION_TEXT[i];
2590       if ('0' <= c && c <= '9') {
2591         for (j = i + 1; j < k; ++j) {
2592           c = OPENSSL_VERSION_TEXT[j];
2593           if (c == ' ')
2594             break;
2595         }
2596         break;
2597       }
2598     }
2599     READONLY_PROPERTY(
2600         versions,
2601         "openssl",
2602         OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
2603   }
2604 #endif
2605
2606   // process.arch
2607   READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
2608
2609   // process.platform
2610   READONLY_PROPERTY(process,
2611                     "platform",
2612                     OneByteString(env->isolate(), NODE_PLATFORM));
2613
2614   // process.argv
2615   Local<Array> arguments = Array::New(env->isolate(), argc);
2616   for (int i = 0; i < argc; ++i) {
2617     arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
2618   }
2619   process->Set(env->argv_string(), arguments);
2620
2621   // process.execArgv
2622   Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
2623   for (int i = 0; i < exec_argc; ++i) {
2624     exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
2625   }
2626   process->Set(env->exec_argv_string(), exec_arguments);
2627
2628   // create process.env
2629   Local<ObjectTemplate> process_env_template =
2630       ObjectTemplate::New(env->isolate());
2631   process_env_template->SetNamedPropertyHandler(EnvGetter,
2632                                                 EnvSetter,
2633                                                 EnvQuery,
2634                                                 EnvDeleter,
2635                                                 EnvEnumerator,
2636                                                 Object::New(env->isolate()));
2637   Local<Object> process_env = process_env_template->NewInstance();
2638   process->Set(env->env_string(), process_env);
2639
2640   READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
2641   READONLY_PROPERTY(process, "features", GetFeatures(env));
2642   process->SetAccessor(env->need_imm_cb_string(),
2643       NeedImmediateCallbackGetter,
2644       NeedImmediateCallbackSetter);
2645
2646   // -e, --eval
2647   if (eval_string) {
2648     READONLY_PROPERTY(process,
2649                       "_eval",
2650                       String::NewFromUtf8(env->isolate(), eval_string));
2651   }
2652
2653   // -p, --print
2654   if (print_eval) {
2655     READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
2656   }
2657
2658   // -i, --interactive
2659   if (force_repl) {
2660     READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
2661   }
2662
2663   // --no-deprecation
2664   if (no_deprecation) {
2665     READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
2666   }
2667
2668   // --throw-deprecation
2669   if (throw_deprecation) {
2670     READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
2671   }
2672
2673   // --trace-deprecation
2674   if (trace_deprecation) {
2675     READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
2676   }
2677
2678   size_t exec_path_len = 2 * PATH_MAX;
2679   char* exec_path = new char[exec_path_len];
2680   Local<String> exec_path_value;
2681   if (uv_exepath(exec_path, &exec_path_len) == 0) {
2682     exec_path_value = String::NewFromUtf8(env->isolate(),
2683                                           exec_path,
2684                                           String::kNormalString,
2685                                           exec_path_len);
2686   } else {
2687     exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
2688   }
2689   process->Set(env->exec_path_string(), exec_path_value);
2690   delete[] exec_path;
2691
2692   process->SetAccessor(env->debug_port_string(),
2693                        DebugPortGetter,
2694                        DebugPortSetter);
2695
2696   // define various internal methods
2697   env->SetMethod(process,
2698                  "_startProfilerIdleNotifier",
2699                  StartProfilerIdleNotifier);
2700   env->SetMethod(process,
2701                  "_stopProfilerIdleNotifier",
2702                  StopProfilerIdleNotifier);
2703   env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
2704   env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
2705   env->SetMethod(process, "reallyExit", Exit);
2706   env->SetMethod(process, "abort", Abort);
2707   env->SetMethod(process, "chdir", Chdir);
2708   env->SetMethod(process, "cwd", Cwd);
2709
2710   env->SetMethod(process, "umask", Umask);
2711
2712 #if defined(__POSIX__) && !defined(__ANDROID__)
2713   env->SetMethod(process, "getuid", GetUid);
2714   env->SetMethod(process, "setuid", SetUid);
2715
2716   env->SetMethod(process, "setgid", SetGid);
2717   env->SetMethod(process, "getgid", GetGid);
2718
2719   env->SetMethod(process, "getgroups", GetGroups);
2720   env->SetMethod(process, "setgroups", SetGroups);
2721   env->SetMethod(process, "initgroups", InitGroups);
2722 #endif  // __POSIX__ && !defined(__ANDROID__)
2723
2724   env->SetMethod(process, "_kill", Kill);
2725
2726   env->SetMethod(process, "_debugProcess", DebugProcess);
2727   env->SetMethod(process, "_debugPause", DebugPause);
2728   env->SetMethod(process, "_debugEnd", DebugEnd);
2729
2730   env->SetMethod(process, "hrtime", Hrtime);
2731
2732   env->SetMethod(process, "dlopen", DLOpen);
2733
2734   env->SetMethod(process, "uptime", Uptime);
2735   env->SetMethod(process, "memoryUsage", MemoryUsage);
2736
2737   env->SetMethod(process, "binding", Binding);
2738   env->SetMethod(process, "_linkedBinding", LinkedBinding);
2739
2740   env->SetMethod(process, "_setupNextTick", SetupNextTick);
2741   env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
2742
2743   // pre-set _events object for faster emit checks
2744   process->Set(env->events_string(), Object::New(env->isolate()));
2745 }
2746
2747
2748 #undef READONLY_PROPERTY
2749
2750
2751 static void AtExit() {
2752   uv_tty_reset_mode();
2753 }
2754
2755
2756 static void SignalExit(int signo) {
2757   uv_tty_reset_mode();
2758   raise(signo);
2759 }
2760
2761
2762 // Most of the time, it's best to use `console.error` to write
2763 // to the process.stderr stream.  However, in some cases, such as
2764 // when debugging the stream.Writable class or the process.nextTick
2765 // function, it is useful to bypass JavaScript entirely.
2766 static void RawDebug(const FunctionCallbackInfo<Value>& args) {
2767   CHECK(args.Length() == 1 && args[0]->IsString() &&
2768         "must be called with a single string");
2769   node::Utf8Value message(args.GetIsolate(), args[0]);
2770   fprintf(stderr, "%s\n", *message);
2771   fflush(stderr);
2772 }
2773
2774
2775 void LoadEnvironment(Environment* env) {
2776   HandleScope handle_scope(env->isolate());
2777
2778   env->isolate()->SetFatalErrorHandler(node::OnFatalError);
2779   env->isolate()->AddMessageListener(OnMessage);
2780
2781   // Compile, execute the src/node.js file. (Which was included as static C
2782   // string in node_natives.h. 'natve_node' is the string containing that
2783   // source code.)
2784
2785   // The node.js file returns a function 'f'
2786   atexit(AtExit);
2787
2788   TryCatch try_catch;
2789
2790   // Disable verbose mode to stop FatalException() handler from trying
2791   // to handle the exception. Errors this early in the start-up phase
2792   // are not safe to ignore.
2793   try_catch.SetVerbose(false);
2794
2795   Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(), "node.js");
2796   Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
2797   if (try_catch.HasCaught())  {
2798     ReportException(env, try_catch);
2799     exit(10);
2800   }
2801   CHECK(f_value->IsFunction());
2802   Local<Function> f = Local<Function>::Cast(f_value);
2803
2804   // Now we call 'f' with the 'process' variable that we've built up with
2805   // all our bindings. Inside node.js we'll take care of assigning things to
2806   // their places.
2807
2808   // We start the process this way in order to be more modular. Developers
2809   // who do not like how 'src/node.js' setups the module system but do like
2810   // Node's I/O bindings may want to replace 'f' with their own function.
2811
2812   // Add a reference to the global object
2813   Local<Object> global = env->context()->Global();
2814
2815 #if defined HAVE_DTRACE || defined HAVE_ETW
2816   InitDTrace(env, global);
2817 #endif
2818
2819 #if defined HAVE_PERFCTR
2820   InitPerfCounters(env, global);
2821 #endif
2822
2823   // Enable handling of uncaught exceptions
2824   // (FatalException(), break on uncaught exception in debugger)
2825   //
2826   // This is not strictly necessary since it's almost impossible
2827   // to attach the debugger fast enought to break on exception
2828   // thrown during process startup.
2829   try_catch.SetVerbose(true);
2830
2831   env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
2832
2833   Local<Value> arg = env->process_object();
2834   f->Call(global, 1, &arg);
2835 }
2836
2837 static void PrintHelp();
2838
2839 static bool ParseDebugOpt(const char* arg) {
2840   const char* port = nullptr;
2841
2842   if (!strcmp(arg, "--debug")) {
2843     use_debug_agent = true;
2844   } else if (!strncmp(arg, "--debug=", sizeof("--debug=") - 1)) {
2845     use_debug_agent = true;
2846     port = arg + sizeof("--debug=") - 1;
2847   } else if (!strcmp(arg, "--debug-brk")) {
2848     use_debug_agent = true;
2849     debug_wait_connect = true;
2850   } else if (!strncmp(arg, "--debug-brk=", sizeof("--debug-brk=") - 1)) {
2851     use_debug_agent = true;
2852     debug_wait_connect = true;
2853     port = arg + sizeof("--debug-brk=") - 1;
2854   } else if (!strncmp(arg, "--debug-port=", sizeof("--debug-port=") - 1)) {
2855     port = arg + sizeof("--debug-port=") - 1;
2856   } else {
2857     return false;
2858   }
2859
2860   if (port != nullptr) {
2861     debug_port = atoi(port);
2862     if (debug_port < 1024 || debug_port > 65535) {
2863       fprintf(stderr, "Debug port must be in range 1024 to 65535.\n");
2864       PrintHelp();
2865       exit(12);
2866     }
2867   }
2868
2869   return true;
2870 }
2871
2872 static void PrintHelp() {
2873   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
2874          "       node debug script.js [arguments] \n"
2875          "\n"
2876          "Options:\n"
2877          "  -v, --version        print node's version\n"
2878          "  -e, --eval script    evaluate script\n"
2879          "  -p, --print          evaluate script and print result\n"
2880          "  -i, --interactive    always enter the REPL even if stdin\n"
2881          "                       does not appear to be a terminal\n"
2882          "  --no-deprecation     silence deprecation warnings\n"
2883          "  --throw-deprecation  throw an exception anytime a deprecated "
2884          "function is used\n"
2885          "  --trace-deprecation  show stack traces on deprecations\n"
2886          "  --v8-options         print v8 command line options\n"
2887          "  --max-stack-size=val set max v8 stack size (bytes)\n"
2888 #if defined(NODE_HAVE_I18N_SUPPORT)
2889          "  --icu-data-dir=dir   set ICU data load path to dir\n"
2890          "                         (overrides NODE_ICU_DATA)\n"
2891 #if !defined(NODE_HAVE_SMALL_ICU)
2892          "                       Note: linked-in ICU data is\n"
2893          "                       present.\n"
2894 #endif
2895 #endif
2896          "\n"
2897          "Environment variables:\n"
2898 #ifdef _WIN32
2899          "NODE_PATH              ';'-separated list of directories\n"
2900 #else
2901          "NODE_PATH              ':'-separated list of directories\n"
2902 #endif
2903          "                       prefixed to the module search path.\n"
2904          "NODE_MODULE_CONTEXTS   Set to 1 to load modules in their own\n"
2905          "                       global contexts.\n"
2906          "NODE_DISABLE_COLORS    Set to 1 to disable colors in the REPL\n"
2907 #if defined(NODE_HAVE_I18N_SUPPORT)
2908          "NODE_ICU_DATA          Data path for ICU (Intl object) data\n"
2909 #if !defined(NODE_HAVE_SMALL_ICU)
2910          "                       (will extend linked-in data)\n"
2911 #endif
2912 #endif
2913          "\n"
2914          "Documentation can be found at http://nodejs.org/\n");
2915 }
2916
2917
2918 // Parse command line arguments.
2919 //
2920 // argv is modified in place. exec_argv and v8_argv are out arguments that
2921 // ParseArgs() allocates memory for and stores a pointer to the output
2922 // vector in.  The caller should free them with delete[].
2923 //
2924 // On exit:
2925 //
2926 //  * argv contains the arguments with node and V8 options filtered out.
2927 //  * exec_argv contains both node and V8 options and nothing else.
2928 //  * v8_argv contains argv[0] plus any V8 options
2929 static void ParseArgs(int* argc,
2930                       const char** argv,
2931                       int* exec_argc,
2932                       const char*** exec_argv,
2933                       int* v8_argc,
2934                       const char*** v8_argv) {
2935   const unsigned int nargs = static_cast<unsigned int>(*argc);
2936   const char** new_exec_argv = new const char*[nargs];
2937   const char** new_v8_argv = new const char*[nargs];
2938   const char** new_argv = new const char*[nargs];
2939
2940   for (unsigned int i = 0; i < nargs; ++i) {
2941     new_exec_argv[i] = nullptr;
2942     new_v8_argv[i] = nullptr;
2943     new_argv[i] = nullptr;
2944   }
2945
2946   // exec_argv starts with the first option, the other two start with argv[0].
2947   unsigned int new_exec_argc = 0;
2948   unsigned int new_v8_argc = 1;
2949   unsigned int new_argc = 1;
2950   new_v8_argv[0] = argv[0];
2951   new_argv[0] = argv[0];
2952
2953   unsigned int index = 1;
2954   while (index < nargs && argv[index][0] == '-') {
2955     const char* const arg = argv[index];
2956     unsigned int args_consumed = 1;
2957
2958     if (ParseDebugOpt(arg)) {
2959       // Done, consumed by ParseDebugOpt().
2960     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
2961       printf("%s\n", NODE_VERSION);
2962       exit(0);
2963     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
2964       PrintHelp();
2965       exit(0);
2966     } else if (strcmp(arg, "--eval") == 0 ||
2967                strcmp(arg, "-e") == 0 ||
2968                strcmp(arg, "--print") == 0 ||
2969                strcmp(arg, "-pe") == 0 ||
2970                strcmp(arg, "-p") == 0) {
2971       bool is_eval = strchr(arg, 'e') != nullptr;
2972       bool is_print = strchr(arg, 'p') != nullptr;
2973       print_eval = print_eval || is_print;
2974       // --eval, -e and -pe always require an argument.
2975       if (is_eval == true) {
2976         args_consumed += 1;
2977         eval_string = argv[index + 1];
2978         if (eval_string == nullptr) {
2979           fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
2980           exit(9);
2981         }
2982       } else if ((index + 1 < nargs) &&
2983                  argv[index + 1] != nullptr &&
2984                  argv[index + 1][0] != '-') {
2985         args_consumed += 1;
2986         eval_string = argv[index + 1];
2987         if (strncmp(eval_string, "\\-", 2) == 0) {
2988           // Starts with "\\-": escaped expression, drop the backslash.
2989           eval_string += 1;
2990         }
2991       }
2992     } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
2993       force_repl = true;
2994     } else if (strcmp(arg, "--no-deprecation") == 0) {
2995       no_deprecation = true;
2996     } else if (strcmp(arg, "--trace-deprecation") == 0) {
2997       trace_deprecation = true;
2998     } else if (strcmp(arg, "--throw-deprecation") == 0) {
2999       throw_deprecation = true;
3000     } else if (strcmp(arg, "--v8-options") == 0) {
3001       new_v8_argv[new_v8_argc] = "--help";
3002       new_v8_argc += 1;
3003 #if defined(NODE_HAVE_I18N_SUPPORT)
3004     } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
3005       icu_data_dir = arg + 15;
3006 #endif
3007     } else {
3008       // V8 option.  Pass through as-is.
3009       new_v8_argv[new_v8_argc] = arg;
3010       new_v8_argc += 1;
3011     }
3012
3013     memcpy(new_exec_argv + new_exec_argc,
3014            argv + index,
3015            args_consumed * sizeof(*argv));
3016
3017     new_exec_argc += args_consumed;
3018     index += args_consumed;
3019   }
3020
3021   // Copy remaining arguments.
3022   const unsigned int args_left = nargs - index;
3023   memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
3024   new_argc += args_left;
3025
3026   *exec_argc = new_exec_argc;
3027   *exec_argv = new_exec_argv;
3028   *v8_argc = new_v8_argc;
3029   *v8_argv = new_v8_argv;
3030
3031   // Copy new_argv over argv and update argc.
3032   memcpy(argv, new_argv, new_argc * sizeof(*argv));
3033   delete[] new_argv;
3034   *argc = static_cast<int>(new_argc);
3035 }
3036
3037
3038 // Called from V8 Debug Agent TCP thread.
3039 static void DispatchMessagesDebugAgentCallback(Environment* env) {
3040   // TODO(indutny): move async handle to environment
3041   uv_async_send(&dispatch_debug_messages_async);
3042 }
3043
3044
3045 static void StartDebug(Environment* env, bool wait) {
3046   CHECK(!debugger_running);
3047
3048   env->debugger_agent()->set_dispatch_handler(
3049         DispatchMessagesDebugAgentCallback);
3050   debugger_running = env->debugger_agent()->Start(debug_port, wait);
3051   if (debugger_running == false) {
3052     fprintf(stderr, "Starting debugger on port %d failed\n", debug_port);
3053     fflush(stderr);
3054     return;
3055   }
3056 }
3057
3058
3059 // Called from the main thread.
3060 static void EnableDebug(Environment* env) {
3061   CHECK(debugger_running);
3062
3063   // Send message to enable debug in workers
3064   HandleScope handle_scope(env->isolate());
3065
3066   Local<Object> message = Object::New(env->isolate());
3067   message->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "cmd"),
3068                FIXED_ONE_BYTE_STRING(env->isolate(), "NODE_DEBUG_ENABLED"));
3069   Local<Value> argv[] = {
3070     FIXED_ONE_BYTE_STRING(env->isolate(), "internalMessage"),
3071     message
3072   };
3073   MakeCallback(env, env->process_object(), "emit", ARRAY_SIZE(argv), argv);
3074
3075   // Enabled debugger, possibly making it wait on a semaphore
3076   env->debugger_agent()->Enable();
3077 }
3078
3079
3080 // Called from the main thread.
3081 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
3082   if (debugger_running == false) {
3083     fprintf(stderr, "Starting debugger agent.\n");
3084
3085     Environment* env = Environment::GetCurrent(node_isolate);
3086     Context::Scope context_scope(env->context());
3087
3088     StartDebug(env, false);
3089     EnableDebug(env);
3090   }
3091   Isolate::Scope isolate_scope(node_isolate);
3092   v8::Debug::ProcessDebugMessages();
3093 }
3094
3095
3096 #ifdef __POSIX__
3097 static volatile sig_atomic_t caught_early_debug_signal;
3098
3099
3100 static void EarlyDebugSignalHandler(int signo) {
3101   caught_early_debug_signal = 1;
3102 }
3103
3104
3105 static void InstallEarlyDebugSignalHandler() {
3106   struct sigaction sa;
3107   memset(&sa, 0, sizeof(sa));
3108   sa.sa_handler = EarlyDebugSignalHandler;
3109   sigaction(SIGUSR1, &sa, nullptr);
3110 }
3111
3112
3113 static void EnableDebugSignalHandler(int signo) {
3114   // Call only async signal-safe functions here!
3115   v8::Debug::DebugBreak(*static_cast<Isolate* volatile*>(&node_isolate));
3116   uv_async_send(&dispatch_debug_messages_async);
3117 }
3118
3119
3120 static void RegisterSignalHandler(int signal,
3121                                   void (*handler)(int signal),
3122                                   bool reset_handler = false) {
3123   struct sigaction sa;
3124   memset(&sa, 0, sizeof(sa));
3125   sa.sa_handler = handler;
3126   sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
3127   sigfillset(&sa.sa_mask);
3128   CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
3129 }
3130
3131
3132 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
3133   Environment* env = Environment::GetCurrent(args);
3134
3135   if (args.Length() != 1) {
3136     return env->ThrowError("Invalid number of arguments.");
3137   }
3138
3139   pid_t pid;
3140   int r;
3141
3142   pid = args[0]->IntegerValue();
3143   r = kill(pid, SIGUSR1);
3144   if (r != 0) {
3145     return env->ThrowErrnoException(errno, "kill");
3146   }
3147 }
3148
3149
3150 static int RegisterDebugSignalHandler() {
3151   // FIXME(bnoordhuis) Should be per-isolate or per-context, not global.
3152   RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler);
3153   // If we caught a SIGUSR1 during the bootstrap process, re-raise it
3154   // now that the debugger infrastructure is in place.
3155   if (caught_early_debug_signal)
3156     raise(SIGUSR1);
3157   return 0;
3158 }
3159 #endif  // __POSIX__
3160
3161
3162 #ifdef _WIN32
3163 DWORD WINAPI EnableDebugThreadProc(void* arg) {
3164   v8::Debug::DebugBreak(*static_cast<Isolate* volatile*>(&node_isolate));
3165   uv_async_send(&dispatch_debug_messages_async);
3166   return 0;
3167 }
3168
3169
3170 static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
3171     size_t buf_len) {
3172   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
3173 }
3174
3175
3176 static int RegisterDebugSignalHandler() {
3177   wchar_t mapping_name[32];
3178   HANDLE mapping_handle;
3179   DWORD pid;
3180   LPTHREAD_START_ROUTINE* handler;
3181
3182   pid = GetCurrentProcessId();
3183
3184   if (GetDebugSignalHandlerMappingName(pid,
3185                                        mapping_name,
3186                                        ARRAY_SIZE(mapping_name)) < 0) {
3187     return -1;
3188   }
3189
3190   mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
3191                                       nullptr,
3192                                       PAGE_READWRITE,
3193                                       0,
3194                                       sizeof *handler,
3195                                       mapping_name);
3196   if (mapping_handle == nullptr) {
3197     return -1;
3198   }
3199
3200   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
3201       MapViewOfFile(mapping_handle,
3202                     FILE_MAP_ALL_ACCESS,
3203                     0,
3204                     0,
3205                     sizeof *handler));
3206   if (handler == nullptr) {
3207     CloseHandle(mapping_handle);
3208     return -1;
3209   }
3210
3211   *handler = EnableDebugThreadProc;
3212
3213   UnmapViewOfFile(static_cast<void*>(handler));
3214
3215   return 0;
3216 }
3217
3218
3219 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
3220   Environment* env = Environment::GetCurrent(args);
3221   Isolate* isolate = args.GetIsolate();
3222   DWORD pid;
3223   HANDLE process = nullptr;
3224   HANDLE thread = nullptr;
3225   HANDLE mapping = nullptr;
3226   wchar_t mapping_name[32];
3227   LPTHREAD_START_ROUTINE* handler = nullptr;
3228
3229   if (args.Length() != 1) {
3230     env->ThrowError("Invalid number of arguments.");
3231     goto out;
3232   }
3233
3234   pid = (DWORD) args[0]->IntegerValue();
3235
3236   process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
3237                             PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
3238                             PROCESS_VM_READ,
3239                         FALSE,
3240                         pid);
3241   if (process == nullptr) {
3242     isolate->ThrowException(
3243         WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
3244     goto out;
3245   }
3246
3247   if (GetDebugSignalHandlerMappingName(pid,
3248                                        mapping_name,
3249                                        ARRAY_SIZE(mapping_name)) < 0) {
3250     env->ThrowErrnoException(errno, "sprintf");
3251     goto out;
3252   }
3253
3254   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
3255   if (mapping == nullptr) {
3256     isolate->ThrowException(WinapiErrnoException(isolate,
3257                                              GetLastError(),
3258                                              "OpenFileMappingW"));
3259     goto out;
3260   }
3261
3262   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
3263       MapViewOfFile(mapping,
3264                     FILE_MAP_READ,
3265                     0,
3266                     0,
3267                     sizeof *handler));
3268   if (handler == nullptr || *handler == nullptr) {
3269     isolate->ThrowException(
3270         WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
3271     goto out;
3272   }
3273
3274   thread = CreateRemoteThread(process,
3275                               nullptr,
3276                               0,
3277                               *handler,
3278                               nullptr,
3279                               0,
3280                               nullptr);
3281   if (thread == nullptr) {
3282     isolate->ThrowException(WinapiErrnoException(isolate,
3283                                                  GetLastError(),
3284                                                  "CreateRemoteThread"));
3285     goto out;
3286   }
3287
3288   // Wait for the thread to terminate
3289   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
3290     isolate->ThrowException(WinapiErrnoException(isolate,
3291                                                  GetLastError(),
3292                                                  "WaitForSingleObject"));
3293     goto out;
3294   }
3295
3296  out:
3297   if (process != nullptr)
3298     CloseHandle(process);
3299   if (thread != nullptr)
3300     CloseHandle(thread);
3301   if (handler != nullptr)
3302     UnmapViewOfFile(handler);
3303   if (mapping != nullptr)
3304     CloseHandle(mapping);
3305 }
3306 #endif  // _WIN32
3307
3308
3309 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
3310   v8::Debug::DebugBreak(args.GetIsolate());
3311 }
3312
3313
3314 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
3315   if (debugger_running) {
3316     Environment* env = Environment::GetCurrent(args);
3317     env->debugger_agent()->Stop();
3318     debugger_running = false;
3319   }
3320 }
3321
3322
3323 void Init(int* argc,
3324           const char** argv,
3325           int* exec_argc,
3326           const char*** exec_argv) {
3327   // Initialize prog_start_time to get relative uptime.
3328   prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
3329
3330   // Make inherited handles noninheritable.
3331   uv_disable_stdio_inheritance();
3332
3333   // init async debug messages dispatching
3334   // FIXME(bnoordhuis) Should be per-isolate or per-context, not global.
3335   uv_async_init(uv_default_loop(),
3336                 &dispatch_debug_messages_async,
3337                 DispatchDebugMessagesAsyncCallback);
3338   uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
3339
3340   // TODO(bnoordhuis) V8 3.32 is unshipping Harmony classes for the moment.
3341   // We're currently at 3.31, disable classes for feature parity.  Remove
3342   // again when we upgrade.
3343   V8::SetFlagsFromString("--noharmony_classes",
3344                          sizeof("--noharmony_classes") - 1);
3345   V8::SetFlagsFromString("--noharmony_object_literals",
3346                          sizeof("--noharmony_object_literals") - 1);
3347
3348 #if defined(NODE_V8_OPTIONS)
3349   // Should come before the call to V8::SetFlagsFromCommandLine()
3350   // so the user can disable a flag --foo at run-time by passing
3351   // --no_foo from the command line.
3352   V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
3353 #endif
3354
3355   // Parse a few arguments which are specific to Node.
3356   int v8_argc;
3357   const char** v8_argv;
3358   ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv);
3359
3360   // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
3361   // manually?  That would give us a little more control over its runtime
3362   // behavior but it could also interfere with the user's intentions in ways
3363   // we fail to anticipate.  Dillema.
3364   for (int i = 1; i < v8_argc; ++i) {
3365     if (strncmp(v8_argv[i], "--prof", sizeof("--prof") - 1) == 0) {
3366       v8_is_profiling = true;
3367       break;
3368     }
3369   }
3370
3371 #if defined(NODE_HAVE_I18N_SUPPORT)
3372   if (icu_data_dir == nullptr) {
3373     // if the parameter isn't given, use the env variable.
3374     icu_data_dir = secure_getenv("NODE_ICU_DATA");
3375   }
3376   // Initialize ICU.
3377   // If icu_data_dir is nullptr here, it will load the 'minimal' data.
3378   if (!i18n::InitializeICUDirectory(icu_data_dir)) {
3379     FatalError(nullptr, "Could not initialize ICU "
3380                      "(check NODE_ICU_DATA or --icu-data-dir parameters)");
3381   }
3382 #endif
3383   // The const_cast doesn't violate conceptual const-ness.  V8 doesn't modify
3384   // the argv array or the elements it points to.
3385   V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
3386
3387   // Anything that's still in v8_argv is not a V8 or a node option.
3388   for (int i = 1; i < v8_argc; i++) {
3389     fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
3390   }
3391   delete[] v8_argv;
3392   v8_argv = nullptr;
3393
3394   if (v8_argc > 1) {
3395     exit(9);
3396   }
3397
3398   if (debug_wait_connect) {
3399     const char expose_debug_as[] = "--expose_debug_as=v8debug";
3400     V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
3401   }
3402
3403   V8::SetArrayBufferAllocator(&ArrayBufferAllocator::the_singleton);
3404
3405 #ifdef __POSIX__
3406   // Raise the open file descriptor limit.
3407   {  // NOLINT (whitespace/braces)
3408     struct rlimit lim;
3409     if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
3410       // Do a binary search for the limit.
3411       rlim_t min = lim.rlim_cur;
3412       rlim_t max = 1 << 20;
3413       // But if there's a defined upper bound, don't search, just set it.
3414       if (lim.rlim_max != RLIM_INFINITY) {
3415         min = lim.rlim_max;
3416         max = lim.rlim_max;
3417       }
3418       do {
3419         lim.rlim_cur = min + (max - min) / 2;
3420         if (setrlimit(RLIMIT_NOFILE, &lim)) {
3421           max = lim.rlim_cur;
3422         } else {
3423           min = lim.rlim_cur;
3424         }
3425       } while (min + 1 < max);
3426     }
3427   }
3428   // Ignore SIGPIPE
3429   RegisterSignalHandler(SIGPIPE, SIG_IGN);
3430   RegisterSignalHandler(SIGINT, SignalExit, true);
3431   RegisterSignalHandler(SIGTERM, SignalExit, true);
3432 #endif  // __POSIX__
3433
3434   if (!use_debug_agent) {
3435     RegisterDebugSignalHandler();
3436   }
3437 }
3438
3439
3440 struct AtExitCallback {
3441   AtExitCallback* next_;
3442   void (*cb_)(void* arg);
3443   void* arg_;
3444 };
3445
3446 static AtExitCallback* at_exit_functions_;
3447
3448
3449 // TODO(bnoordhuis) Turn into per-context event.
3450 void RunAtExit(Environment* env) {
3451   AtExitCallback* p = at_exit_functions_;
3452   at_exit_functions_ = nullptr;
3453
3454   while (p) {
3455     AtExitCallback* q = p->next_;
3456     p->cb_(p->arg_);
3457     delete p;
3458     p = q;
3459   }
3460 }
3461
3462
3463 void AtExit(void (*cb)(void* arg), void* arg) {
3464   AtExitCallback* p = new AtExitCallback;
3465   p->cb_ = cb;
3466   p->arg_ = arg;
3467   p->next_ = at_exit_functions_;
3468   at_exit_functions_ = p;
3469 }
3470
3471
3472 void EmitBeforeExit(Environment* env) {
3473   Context::Scope context_scope(env->context());
3474   HandleScope handle_scope(env->isolate());
3475   Local<Object> process_object = env->process_object();
3476   Local<String> exit_code = FIXED_ONE_BYTE_STRING(env->isolate(), "exitCode");
3477   Local<Value> args[] = {
3478     FIXED_ONE_BYTE_STRING(env->isolate(), "beforeExit"),
3479     process_object->Get(exit_code)->ToInteger(env->isolate())
3480   };
3481   MakeCallback(env, process_object, "emit", ARRAY_SIZE(args), args);
3482 }
3483
3484
3485 int EmitExit(Environment* env) {
3486   // process.emit('exit')
3487   HandleScope handle_scope(env->isolate());
3488   Context::Scope context_scope(env->context());
3489   Local<Object> process_object = env->process_object();
3490   process_object->Set(env->exiting_string(), True(env->isolate()));
3491
3492   Handle<String> exitCode = env->exit_code_string();
3493   int code = process_object->Get(exitCode)->Int32Value();
3494
3495   Local<Value> args[] = {
3496     env->exit_string(),
3497     Integer::New(env->isolate(), code)
3498   };
3499
3500   MakeCallback(env, process_object, "emit", ARRAY_SIZE(args), args);
3501
3502   // Reload exit code, it may be changed by `emit('exit')`
3503   return process_object->Get(exitCode)->Int32Value();
3504 }
3505
3506
3507 // Just a convenience method
3508 Environment* CreateEnvironment(Isolate* isolate,
3509                                Handle<Context> context,
3510                                int argc,
3511                                const char* const* argv,
3512                                int exec_argc,
3513                                const char* const* exec_argv) {
3514   Environment* env;
3515   Context::Scope context_scope(context);
3516
3517   env = CreateEnvironment(isolate,
3518                           uv_default_loop(),
3519                           context,
3520                           argc,
3521                           argv,
3522                           exec_argc,
3523                           exec_argv);
3524
3525   LoadEnvironment(env);
3526
3527   return env;
3528 }
3529
3530
3531 static void HandleCloseCb(uv_handle_t* handle) {
3532   Environment* env = reinterpret_cast<Environment*>(handle->data);
3533   env->FinishHandleCleanup(handle);
3534 }
3535
3536
3537 static void HandleCleanup(Environment* env,
3538                           uv_handle_t* handle,
3539                           void* arg) {
3540   handle->data = env;
3541   uv_close(handle, HandleCloseCb);
3542 }
3543
3544
3545 Environment* CreateEnvironment(Isolate* isolate,
3546                                uv_loop_t* loop,
3547                                Handle<Context> context,
3548                                int argc,
3549                                const char* const* argv,
3550                                int exec_argc,
3551                                const char* const* exec_argv) {
3552   HandleScope handle_scope(isolate);
3553
3554   Context::Scope context_scope(context);
3555   Environment* env = Environment::New(context, loop);
3556
3557   isolate->SetAutorunMicrotasks(false);
3558
3559   uv_check_init(env->event_loop(), env->immediate_check_handle());
3560   uv_unref(
3561       reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()));
3562
3563   uv_idle_init(env->event_loop(), env->immediate_idle_handle());
3564
3565   // Inform V8's CPU profiler when we're idle.  The profiler is sampling-based
3566   // but not all samples are created equal; mark the wall clock time spent in
3567   // epoll_wait() and friends so profiling tools can filter it out.  The samples
3568   // still end up in v8.log but with state=IDLE rather than state=EXTERNAL.
3569   // TODO(bnoordhuis) Depends on a libuv implementation detail that we should
3570   // probably fortify in the API contract, namely that the last started prepare
3571   // or check watcher runs first.  It's not 100% foolproof; if an add-on starts
3572   // a prepare or check watcher after us, any samples attributed to its callback
3573   // will be recorded with state=IDLE.
3574   uv_prepare_init(env->event_loop(), env->idle_prepare_handle());
3575   uv_check_init(env->event_loop(), env->idle_check_handle());
3576   uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle()));
3577   uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle()));
3578
3579   // Register handle cleanups
3580   env->RegisterHandleCleanup(
3581       reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()),
3582       HandleCleanup,
3583       nullptr);
3584   env->RegisterHandleCleanup(
3585       reinterpret_cast<uv_handle_t*>(env->immediate_idle_handle()),
3586       HandleCleanup,
3587       nullptr);
3588   env->RegisterHandleCleanup(
3589       reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle()),
3590       HandleCleanup,
3591       nullptr);
3592   env->RegisterHandleCleanup(
3593       reinterpret_cast<uv_handle_t*>(env->idle_check_handle()),
3594       HandleCleanup,
3595       nullptr);
3596
3597   if (v8_is_profiling) {
3598     StartProfilerIdleNotifier(env);
3599   }
3600
3601   Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate);
3602   process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "process"));
3603
3604   Local<Object> process_object = process_template->GetFunction()->NewInstance();
3605   env->set_process_object(process_object);
3606
3607   SetupProcessObject(env, argc, argv, exec_argc, exec_argv);
3608
3609   return env;
3610 }
3611
3612
3613 int Start(int argc, char** argv) {
3614   const char* replaceInvalid = secure_getenv("NODE_INVALID_UTF8");
3615
3616   if (replaceInvalid == nullptr)
3617     WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8;
3618
3619 #if !defined(_WIN32)
3620   // Try hard not to lose SIGUSR1 signals during the bootstrap process.
3621   InstallEarlyDebugSignalHandler();
3622 #endif
3623
3624   CHECK_GT(argc, 0);
3625
3626   // Hack around with the argv pointer. Used for process.title = "blah".
3627   argv = uv_setup_args(argc, argv);
3628
3629   // This needs to run *before* V8::Initialize().  The const_cast is not
3630   // optional, in case you're wondering.
3631   int exec_argc;
3632   const char** exec_argv;
3633   Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
3634
3635 #if HAVE_OPENSSL
3636   // V8 on Windows doesn't have a good source of entropy. Seed it from
3637   // OpenSSL's pool.
3638   V8::SetEntropySource(crypto::EntropySource);
3639 #endif
3640
3641   V8::InitializePlatform(new Platform(4));
3642
3643   int code;
3644   V8::Initialize();
3645   node_is_initialized = true;
3646
3647   // Fetch a reference to the main isolate, so we have a reference to it
3648   // even when we need it to access it from another (debugger) thread.
3649   node_isolate = Isolate::New();
3650   {
3651     Locker locker(node_isolate);
3652     Isolate::Scope isolate_scope(node_isolate);
3653     HandleScope handle_scope(node_isolate);
3654     Local<Context> context = Context::New(node_isolate);
3655     Environment* env = CreateEnvironment(
3656         node_isolate,
3657         uv_default_loop(),
3658         context,
3659         argc,
3660         argv,
3661         exec_argc,
3662         exec_argv);
3663     Context::Scope context_scope(context);
3664
3665     // Start debug agent when argv has --debug
3666     if (use_debug_agent)
3667       StartDebug(env, debug_wait_connect);
3668
3669     LoadEnvironment(env);
3670
3671     // Enable debugger
3672     if (use_debug_agent)
3673       EnableDebug(env);
3674
3675     bool more;
3676     do {
3677       more = uv_run(env->event_loop(), UV_RUN_ONCE);
3678       if (more == false) {
3679         EmitBeforeExit(env);
3680
3681         // Emit `beforeExit` if the loop became alive either after emitting
3682         // event, or after running some callbacks.
3683         more = uv_loop_alive(env->event_loop());
3684         if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
3685           more = true;
3686       }
3687     } while (more == true);
3688     code = EmitExit(env);
3689     RunAtExit(env);
3690
3691     env->Dispose();
3692     env = nullptr;
3693   }
3694
3695   CHECK_NE(node_isolate, nullptr);
3696   node_isolate->Dispose();
3697   node_isolate = nullptr;
3698   V8::Dispose();
3699
3700   delete[] exec_argv;
3701   exec_argv = nullptr;
3702
3703   return code;
3704 }
3705
3706
3707 }  // namespace node