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