src: close libuv handles on exit
[platform/upstream/nodejs.git] / src / node.cc
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #include "node.h"
23 #include "node_buffer.h"
24 #include "node_constants.h"
25 #include "node_file.h"
26 #include "node_http_parser.h"
27 #include "node_javascript.h"
28 #include "node_version.h"
29
30 #if defined HAVE_PERFCTR
31 #include "node_counters.h"
32 #endif
33
34 #if HAVE_OPENSSL
35 #include "node_crypto.h"
36 #endif
37
38 #if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
39 #include "node_dtrace.h"
40 #endif
41
42 #if HAVE_SYSTEMTAP
43 #include "node_provider.h"
44 #endif
45
46 #include "ares.h"
47 #include "handle_wrap.h"
48 #include "req_wrap.h"
49 #include "string_bytes.h"
50 #include "uv.h"
51 #include "v8-debug.h"
52 #include "zlib.h"
53
54 #include <assert.h>
55 #include <errno.h>
56 #include <limits.h>  // PATH_MAX
57 #include <locale.h>
58 #include <signal.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <sys/types.h>
63
64 #if defined(_MSC_VER)
65 #include <direct.h>
66 #include <io.h>
67 #include <process.h>
68 #define strcasecmp _stricmp
69 #define getpid _getpid
70 #define umask _umask
71 typedef int mode_t;
72 #else
73 #include <unistd.h>  // setuid, getuid
74 #endif
75
76 #if defined(__POSIX__) && !defined(__ANDROID__)
77 #include <pwd.h>  // getpwnam()
78 #include <grp.h>  // getgrnam()
79 #endif
80
81 #ifdef __APPLE__
82 #include <crt_externs.h>
83 #define environ (*_NSGetEnviron())
84 #elif !defined(_MSC_VER)
85 extern char **environ;
86 #endif
87
88 namespace node {
89
90 using v8::Array;
91 using v8::ArrayBuffer;
92 using v8::Boolean;
93 using v8::Context;
94 using v8::Exception;
95 using v8::Function;
96 using v8::FunctionCallbackInfo;
97 using v8::FunctionTemplate;
98 using v8::Handle;
99 using v8::HandleScope;
100 using v8::HeapStatistics;
101 using v8::Integer;
102 using v8::Isolate;
103 using v8::Local;
104 using v8::Locker;
105 using v8::Message;
106 using v8::Number;
107 using v8::Object;
108 using v8::ObjectTemplate;
109 using v8::Persistent;
110 using v8::PropertyCallbackInfo;
111 using v8::ResourceConstraints;
112 using v8::SetResourceConstraints;
113 using v8::String;
114 using v8::ThrowException;
115 using v8::TryCatch;
116 using v8::Uint32;
117 using v8::V8;
118 using v8::Value;
119 using v8::kExternalUnsignedIntArray;
120
121 QUEUE handle_wrap_queue = { &handle_wrap_queue, &handle_wrap_queue };
122 QUEUE req_wrap_queue = { &req_wrap_queue, &req_wrap_queue };
123
124 // declared in req_wrap.h
125 Cached<String> process_symbol;
126 Cached<String> domain_symbol;
127
128 // declared in node_internals.h
129 Persistent<Object> process_p;
130
131 static Persistent<Function> process_tickCallback;
132 static Persistent<Object> binding_cache;
133 static Persistent<Array> module_load_list;
134 static Persistent<Array> p_domain_box;
135
136 static Cached<String> exports_symbol;
137
138 static Cached<String> errno_symbol;
139 static Cached<String> syscall_symbol;
140 static Cached<String> errpath_symbol;
141 static Cached<String> code_symbol;
142
143 static Cached<String> rss_symbol;
144 static Cached<String> heap_total_symbol;
145 static Cached<String> heap_used_symbol;
146
147 static Cached<String> fatal_exception_symbol;
148
149 static Cached<String> enter_symbol;
150 static Cached<String> exit_symbol;
151 static Cached<String> disposed_symbol;
152
153 // Essential for node_wrap.h
154 Persistent<FunctionTemplate> pipeConstructorTmpl;
155 Persistent<FunctionTemplate> tcpConstructorTmpl;
156 Persistent<FunctionTemplate> ttyConstructorTmpl;
157
158 static bool print_eval = false;
159 static bool force_repl = false;
160 static bool trace_deprecation = false;
161 static bool throw_deprecation = false;
162 static char *eval_string = NULL;
163 static int option_end_index = 0;
164 static bool use_debug_agent = false;
165 static bool debug_wait_connect = false;
166 static int debug_port = 5858;
167 bool using_domains = false;
168
169 // used by C++ modules as well
170 bool no_deprecation = false;
171
172 static uv_check_t check_immediate_watcher;
173 static uv_idle_t idle_immediate_dummy;
174 static bool need_immediate_cb;
175 static Cached<String> immediate_callback_sym;
176
177 // for quick ref to tickCallback values
178 static struct {
179   uint32_t length;
180   uint32_t index;
181   uint32_t in_tick;
182   uint32_t last_threw;
183 } tick_infobox;
184
185 // easily communicate domain depth
186 static struct {
187   uint32_t count;
188 } domain_flag;
189
190 // process-relative uptime base, initialized at start-up
191 static double prog_start_time;
192
193 static volatile bool debugger_running = false;
194 static uv_async_t dispatch_debug_messages_async;
195 static uv_async_t emit_debug_enabled_async;
196
197 // Declared in node_internals.h
198 Isolate* node_isolate = NULL;
199
200 enum ProcessState {
201   INITIALIZING,
202   RUNNING,
203   SHUTTING_DOWN
204 };
205
206 static ProcessState process_state = INITIALIZING;
207
208
209 class ArrayBufferAllocator : public ArrayBuffer::Allocator {
210  public:
211   // Impose an upper limit to avoid out of memory errors that bring down
212   // the process.
213   static const size_t kMaxLength = 0x3fffffff;
214   static ArrayBufferAllocator the_singleton;
215   virtual ~ArrayBufferAllocator() {}
216   virtual void* Allocate(size_t length);
217   virtual void Free(void* data);
218  private:
219   ArrayBufferAllocator() {}
220   ArrayBufferAllocator(const ArrayBufferAllocator&);
221   void operator=(const ArrayBufferAllocator&);
222 };
223
224 ArrayBufferAllocator ArrayBufferAllocator::the_singleton;
225
226
227 void* ArrayBufferAllocator::Allocate(size_t length) {
228   if (length > kMaxLength) return NULL;
229   return new char[length];
230 }
231
232
233 void ArrayBufferAllocator::Free(void* data) {
234   delete[] static_cast<char*>(data);
235 }
236
237
238 static void CheckImmediate(uv_check_t* handle, int status) {
239   assert(handle == &check_immediate_watcher);
240   assert(status == 0);
241
242   HandleScope scope(node_isolate);
243
244   if (immediate_callback_sym.IsEmpty()) {
245     immediate_callback_sym =
246         FIXED_ONE_BYTE_STRING(node_isolate, "_immediateCallback");
247   }
248
249   MakeCallback(process_p, immediate_callback_sym, 0, NULL);
250 }
251
252
253 static void IdleImmediateDummy(uv_idle_t* handle, int status) {
254   // Do nothing. Only for maintaining event loop
255   assert(handle == &idle_immediate_dummy);
256   assert(status == 0);
257 }
258
259
260 static inline const char *errno_string(int errorno) {
261 #define ERRNO_CASE(e)  case e: return #e;
262   switch (errorno) {
263 #ifdef EACCES
264   ERRNO_CASE(EACCES);
265 #endif
266
267 #ifdef EADDRINUSE
268   ERRNO_CASE(EADDRINUSE);
269 #endif
270
271 #ifdef EADDRNOTAVAIL
272   ERRNO_CASE(EADDRNOTAVAIL);
273 #endif
274
275 #ifdef EAFNOSUPPORT
276   ERRNO_CASE(EAFNOSUPPORT);
277 #endif
278
279 #ifdef EAGAIN
280   ERRNO_CASE(EAGAIN);
281 #endif
282
283 #ifdef EWOULDBLOCK
284 # if EAGAIN != EWOULDBLOCK
285   ERRNO_CASE(EWOULDBLOCK);
286 # endif
287 #endif
288
289 #ifdef EALREADY
290   ERRNO_CASE(EALREADY);
291 #endif
292
293 #ifdef EBADF
294   ERRNO_CASE(EBADF);
295 #endif
296
297 #ifdef EBADMSG
298   ERRNO_CASE(EBADMSG);
299 #endif
300
301 #ifdef EBUSY
302   ERRNO_CASE(EBUSY);
303 #endif
304
305 #ifdef ECANCELED
306   ERRNO_CASE(ECANCELED);
307 #endif
308
309 #ifdef ECHILD
310   ERRNO_CASE(ECHILD);
311 #endif
312
313 #ifdef ECONNABORTED
314   ERRNO_CASE(ECONNABORTED);
315 #endif
316
317 #ifdef ECONNREFUSED
318   ERRNO_CASE(ECONNREFUSED);
319 #endif
320
321 #ifdef ECONNRESET
322   ERRNO_CASE(ECONNRESET);
323 #endif
324
325 #ifdef EDEADLK
326   ERRNO_CASE(EDEADLK);
327 #endif
328
329 #ifdef EDESTADDRREQ
330   ERRNO_CASE(EDESTADDRREQ);
331 #endif
332
333 #ifdef EDOM
334   ERRNO_CASE(EDOM);
335 #endif
336
337 #ifdef EDQUOT
338   ERRNO_CASE(EDQUOT);
339 #endif
340
341 #ifdef EEXIST
342   ERRNO_CASE(EEXIST);
343 #endif
344
345 #ifdef EFAULT
346   ERRNO_CASE(EFAULT);
347 #endif
348
349 #ifdef EFBIG
350   ERRNO_CASE(EFBIG);
351 #endif
352
353 #ifdef EHOSTUNREACH
354   ERRNO_CASE(EHOSTUNREACH);
355 #endif
356
357 #ifdef EIDRM
358   ERRNO_CASE(EIDRM);
359 #endif
360
361 #ifdef EILSEQ
362   ERRNO_CASE(EILSEQ);
363 #endif
364
365 #ifdef EINPROGRESS
366   ERRNO_CASE(EINPROGRESS);
367 #endif
368
369 #ifdef EINTR
370   ERRNO_CASE(EINTR);
371 #endif
372
373 #ifdef EINVAL
374   ERRNO_CASE(EINVAL);
375 #endif
376
377 #ifdef EIO
378   ERRNO_CASE(EIO);
379 #endif
380
381 #ifdef EISCONN
382   ERRNO_CASE(EISCONN);
383 #endif
384
385 #ifdef EISDIR
386   ERRNO_CASE(EISDIR);
387 #endif
388
389 #ifdef ELOOP
390   ERRNO_CASE(ELOOP);
391 #endif
392
393 #ifdef EMFILE
394   ERRNO_CASE(EMFILE);
395 #endif
396
397 #ifdef EMLINK
398   ERRNO_CASE(EMLINK);
399 #endif
400
401 #ifdef EMSGSIZE
402   ERRNO_CASE(EMSGSIZE);
403 #endif
404
405 #ifdef EMULTIHOP
406   ERRNO_CASE(EMULTIHOP);
407 #endif
408
409 #ifdef ENAMETOOLONG
410   ERRNO_CASE(ENAMETOOLONG);
411 #endif
412
413 #ifdef ENETDOWN
414   ERRNO_CASE(ENETDOWN);
415 #endif
416
417 #ifdef ENETRESET
418   ERRNO_CASE(ENETRESET);
419 #endif
420
421 #ifdef ENETUNREACH
422   ERRNO_CASE(ENETUNREACH);
423 #endif
424
425 #ifdef ENFILE
426   ERRNO_CASE(ENFILE);
427 #endif
428
429 #ifdef ENOBUFS
430   ERRNO_CASE(ENOBUFS);
431 #endif
432
433 #ifdef ENODATA
434   ERRNO_CASE(ENODATA);
435 #endif
436
437 #ifdef ENODEV
438   ERRNO_CASE(ENODEV);
439 #endif
440
441 #ifdef ENOENT
442   ERRNO_CASE(ENOENT);
443 #endif
444
445 #ifdef ENOEXEC
446   ERRNO_CASE(ENOEXEC);
447 #endif
448
449 #ifdef ENOLINK
450   ERRNO_CASE(ENOLINK);
451 #endif
452
453 #ifdef ENOLCK
454 # if ENOLINK != ENOLCK
455   ERRNO_CASE(ENOLCK);
456 # endif
457 #endif
458
459 #ifdef ENOMEM
460   ERRNO_CASE(ENOMEM);
461 #endif
462
463 #ifdef ENOMSG
464   ERRNO_CASE(ENOMSG);
465 #endif
466
467 #ifdef ENOPROTOOPT
468   ERRNO_CASE(ENOPROTOOPT);
469 #endif
470
471 #ifdef ENOSPC
472   ERRNO_CASE(ENOSPC);
473 #endif
474
475 #ifdef ENOSR
476   ERRNO_CASE(ENOSR);
477 #endif
478
479 #ifdef ENOSTR
480   ERRNO_CASE(ENOSTR);
481 #endif
482
483 #ifdef ENOSYS
484   ERRNO_CASE(ENOSYS);
485 #endif
486
487 #ifdef ENOTCONN
488   ERRNO_CASE(ENOTCONN);
489 #endif
490
491 #ifdef ENOTDIR
492   ERRNO_CASE(ENOTDIR);
493 #endif
494
495 #ifdef ENOTEMPTY
496   ERRNO_CASE(ENOTEMPTY);
497 #endif
498
499 #ifdef ENOTSOCK
500   ERRNO_CASE(ENOTSOCK);
501 #endif
502
503 #ifdef ENOTSUP
504   ERRNO_CASE(ENOTSUP);
505 #else
506 # ifdef EOPNOTSUPP
507   ERRNO_CASE(EOPNOTSUPP);
508 # endif
509 #endif
510
511 #ifdef ENOTTY
512   ERRNO_CASE(ENOTTY);
513 #endif
514
515 #ifdef ENXIO
516   ERRNO_CASE(ENXIO);
517 #endif
518
519
520 #ifdef EOVERFLOW
521   ERRNO_CASE(EOVERFLOW);
522 #endif
523
524 #ifdef EPERM
525   ERRNO_CASE(EPERM);
526 #endif
527
528 #ifdef EPIPE
529   ERRNO_CASE(EPIPE);
530 #endif
531
532 #ifdef EPROTO
533   ERRNO_CASE(EPROTO);
534 #endif
535
536 #ifdef EPROTONOSUPPORT
537   ERRNO_CASE(EPROTONOSUPPORT);
538 #endif
539
540 #ifdef EPROTOTYPE
541   ERRNO_CASE(EPROTOTYPE);
542 #endif
543
544 #ifdef ERANGE
545   ERRNO_CASE(ERANGE);
546 #endif
547
548 #ifdef EROFS
549   ERRNO_CASE(EROFS);
550 #endif
551
552 #ifdef ESPIPE
553   ERRNO_CASE(ESPIPE);
554 #endif
555
556 #ifdef ESRCH
557   ERRNO_CASE(ESRCH);
558 #endif
559
560 #ifdef ESTALE
561   ERRNO_CASE(ESTALE);
562 #endif
563
564 #ifdef ETIME
565   ERRNO_CASE(ETIME);
566 #endif
567
568 #ifdef ETIMEDOUT
569   ERRNO_CASE(ETIMEDOUT);
570 #endif
571
572 #ifdef ETXTBSY
573   ERRNO_CASE(ETXTBSY);
574 #endif
575
576 #ifdef EXDEV
577   ERRNO_CASE(EXDEV);
578 #endif
579
580   default: return "";
581   }
582 }
583
584 const char *signo_string(int signo) {
585 #define SIGNO_CASE(e)  case e: return #e;
586   switch (signo) {
587 #ifdef SIGHUP
588   SIGNO_CASE(SIGHUP);
589 #endif
590
591 #ifdef SIGINT
592   SIGNO_CASE(SIGINT);
593 #endif
594
595 #ifdef SIGQUIT
596   SIGNO_CASE(SIGQUIT);
597 #endif
598
599 #ifdef SIGILL
600   SIGNO_CASE(SIGILL);
601 #endif
602
603 #ifdef SIGTRAP
604   SIGNO_CASE(SIGTRAP);
605 #endif
606
607 #ifdef SIGABRT
608   SIGNO_CASE(SIGABRT);
609 #endif
610
611 #ifdef SIGIOT
612 # if SIGABRT != SIGIOT
613   SIGNO_CASE(SIGIOT);
614 # endif
615 #endif
616
617 #ifdef SIGBUS
618   SIGNO_CASE(SIGBUS);
619 #endif
620
621 #ifdef SIGFPE
622   SIGNO_CASE(SIGFPE);
623 #endif
624
625 #ifdef SIGKILL
626   SIGNO_CASE(SIGKILL);
627 #endif
628
629 #ifdef SIGUSR1
630   SIGNO_CASE(SIGUSR1);
631 #endif
632
633 #ifdef SIGSEGV
634   SIGNO_CASE(SIGSEGV);
635 #endif
636
637 #ifdef SIGUSR2
638   SIGNO_CASE(SIGUSR2);
639 #endif
640
641 #ifdef SIGPIPE
642   SIGNO_CASE(SIGPIPE);
643 #endif
644
645 #ifdef SIGALRM
646   SIGNO_CASE(SIGALRM);
647 #endif
648
649   SIGNO_CASE(SIGTERM);
650
651 #ifdef SIGCHLD
652   SIGNO_CASE(SIGCHLD);
653 #endif
654
655 #ifdef SIGSTKFLT
656   SIGNO_CASE(SIGSTKFLT);
657 #endif
658
659
660 #ifdef SIGCONT
661   SIGNO_CASE(SIGCONT);
662 #endif
663
664 #ifdef SIGSTOP
665   SIGNO_CASE(SIGSTOP);
666 #endif
667
668 #ifdef SIGTSTP
669   SIGNO_CASE(SIGTSTP);
670 #endif
671
672 #ifdef SIGBREAK
673   SIGNO_CASE(SIGBREAK);
674 #endif
675
676 #ifdef SIGTTIN
677   SIGNO_CASE(SIGTTIN);
678 #endif
679
680 #ifdef SIGTTOU
681   SIGNO_CASE(SIGTTOU);
682 #endif
683
684 #ifdef SIGURG
685   SIGNO_CASE(SIGURG);
686 #endif
687
688 #ifdef SIGXCPU
689   SIGNO_CASE(SIGXCPU);
690 #endif
691
692 #ifdef SIGXFSZ
693   SIGNO_CASE(SIGXFSZ);
694 #endif
695
696 #ifdef SIGVTALRM
697   SIGNO_CASE(SIGVTALRM);
698 #endif
699
700 #ifdef SIGPROF
701   SIGNO_CASE(SIGPROF);
702 #endif
703
704 #ifdef SIGWINCH
705   SIGNO_CASE(SIGWINCH);
706 #endif
707
708 #ifdef SIGIO
709   SIGNO_CASE(SIGIO);
710 #endif
711
712 #ifdef SIGPOLL
713 # if SIGPOLL != SIGIO
714   SIGNO_CASE(SIGPOLL);
715 # endif
716 #endif
717
718 #ifdef SIGLOST
719   SIGNO_CASE(SIGLOST);
720 #endif
721
722 #ifdef SIGPWR
723 # if SIGPWR != SIGLOST
724   SIGNO_CASE(SIGPWR);
725 # endif
726 #endif
727
728 #ifdef SIGSYS
729   SIGNO_CASE(SIGSYS);
730 #endif
731
732   default: return "";
733   }
734 }
735
736
737 Local<Value> ErrnoException(int errorno,
738                             const char *syscall,
739                             const char *msg,
740                             const char *path) {
741   Local<Value> e;
742   Local<String> estring = OneByteString(node_isolate, errno_string(errorno));
743   if (msg == NULL || msg[0] == '\0') {
744     msg = strerror(errorno);
745   }
746   Local<String> message = OneByteString(node_isolate, msg);
747
748   Local<String> cons1 =
749       String::Concat(estring, FIXED_ONE_BYTE_STRING(node_isolate, ", "));
750   Local<String> cons2 = String::Concat(cons1, message);
751
752   if (syscall_symbol.IsEmpty()) {
753     syscall_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "syscall");
754     errno_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "errno");
755     errpath_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "path");
756     code_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "code");
757   }
758
759   if (path) {
760     Local<String> cons3 =
761         String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
762     Local<String> cons4 =
763         String::Concat(cons3, String::NewFromUtf8(node_isolate, path));
764     Local<String> cons5 =
765         String::Concat(cons4, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
766     e = Exception::Error(cons5);
767   } else {
768     e = Exception::Error(cons2);
769   }
770
771   Local<Object> obj = e->ToObject();
772
773   obj->Set(errno_symbol, Integer::New(errorno, node_isolate));
774   obj->Set(code_symbol, estring);
775   if (path) obj->Set(errpath_symbol, String::NewFromUtf8(node_isolate, path));
776   if (syscall) obj->Set(syscall_symbol, OneByteString(node_isolate, syscall));
777   return e;
778 }
779
780
781 // hack alert! copy of ErrnoException, tuned for uv errors
782 Local<Value> UVException(int errorno,
783                          const char *syscall,
784                          const char *msg,
785                          const char *path) {
786   if (syscall_symbol.IsEmpty()) {
787     syscall_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "syscall");
788     errno_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "errno");
789     errpath_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "path");
790     code_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "code");
791   }
792
793   if (!msg || !msg[0])
794     msg = uv_strerror(errorno);
795
796   Local<String> estring = OneByteString(node_isolate, uv_err_name(errorno));
797   Local<String> message = OneByteString(node_isolate, msg);
798   Local<String> cons1 =
799       String::Concat(estring, FIXED_ONE_BYTE_STRING(node_isolate, ", "));
800   Local<String> cons2 = String::Concat(cons1, message);
801
802   Local<Value> e;
803
804   Local<String> path_str;
805
806   if (path) {
807 #ifdef _WIN32
808     if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
809       path_str = String::Concat(FIXED_ONE_BYTE_STRING(node_isolate, "\\\\"),
810                                 String::NewFromUtf8(node_isolate, path + 8));
811     } else if (strncmp(path, "\\\\?\\", 4) == 0) {
812       path_str = String::NewFromUtf8(node_isolate, path + 4);
813     } else {
814       path_str = String::NewFromUtf8(node_isolate, path);
815     }
816 #else
817     path_str = String::NewFromUtf8(node_isolate, path);
818 #endif
819
820     Local<String> cons3 =
821         String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
822     Local<String> cons4 =
823         String::Concat(cons3, path_str);
824     Local<String> cons5 =
825         String::Concat(cons4, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
826     e = Exception::Error(cons5);
827   } else {
828     e = Exception::Error(cons2);
829   }
830
831   Local<Object> obj = e->ToObject();
832
833   // TODO(piscisaureus) errno should probably go
834   obj->Set(errno_symbol, Integer::New(errorno, node_isolate));
835   obj->Set(code_symbol, estring);
836   if (path) obj->Set(errpath_symbol, path_str);
837   if (syscall) obj->Set(syscall_symbol, OneByteString(node_isolate, syscall));
838   return e;
839 }
840
841
842 #ifdef _WIN32
843 // Does about the same as strerror(),
844 // but supports all windows error messages
845 static const char *winapi_strerror(const int errorno) {
846   char *errmsg = NULL;
847
848   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
849       FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
850       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL);
851
852   if (errmsg) {
853     // Remove trailing newlines
854     for (int i = strlen(errmsg) - 1;
855         i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
856       errmsg[i] = '\0';
857     }
858
859     return errmsg;
860   } else {
861     // FormatMessage failed
862     return "Unknown error";
863   }
864 }
865
866
867 Local<Value> WinapiErrnoException(int errorno,
868                                   const char* syscall,
869                                   const char* msg,
870                                   const char* path) {
871   Local<Value> e;
872   if (!msg || !msg[0]) {
873     msg = winapi_strerror(errorno);
874   }
875   Local<String> message = OneByteString(node_isolate, msg);
876
877   if (syscall_symbol.IsEmpty()) {
878     syscall_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "syscall");
879     errno_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "errno");
880     errpath_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "path");
881     code_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "code");
882   }
883
884   if (path) {
885     Local<String> cons1 =
886         String::Concat(message, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
887     Local<String> cons2 =
888         String::Concat(cons1, String::NewFromUtf8(node_isolate, path));
889     Local<String> cons3 =
890         String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
891     e = Exception::Error(cons3);
892   } else {
893     e = Exception::Error(message);
894   }
895
896   Local<Object> obj = e->ToObject();
897
898   obj->Set(errno_symbol, Integer::New(errorno, node_isolate));
899   if (path) obj->Set(errpath_symbol, String::NewFromUtf8(node_isolate, path));
900   if (syscall) obj->Set(syscall_symbol, OneByteString(node_isolate, syscall));
901   return e;
902 }
903 #endif
904
905
906 void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
907   if (using_domains) return;
908   HandleScope scope(node_isolate);
909   using_domains = true;
910   Local<Object> process = PersistentToLocal(node_isolate, process_p);
911   Local<Value> tdc_v =
912       process->Get(FIXED_ONE_BYTE_STRING(node_isolate, "_tickDomainCallback"));
913   if (!tdc_v->IsFunction()) {
914     fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
915     abort();
916   }
917   Local<Function> tdc = tdc_v.As<Function>();
918   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickCallback"), tdc);
919   process_tickCallback.Reset(node_isolate, tdc);
920   if (!args[0]->IsArray()) {
921     fprintf(stderr, "_setupDomainUse first argument must be an array\n");
922     abort();
923   }
924   p_domain_box.Reset(node_isolate, args[0].As<Array>());
925   if (!args[1]->IsObject()) {
926     fprintf(stderr, "_setupDomainUse second argument must be an object\n");
927     abort();
928   }
929   Local<Object> flag = args[1].As<Object>();
930   flag->SetIndexedPropertiesToExternalArrayData(&domain_flag,
931                                                 kExternalUnsignedIntArray,
932                                                 1);
933 }
934
935
936 bool InDomain() {
937   return using_domains && domain_flag.count > 0;
938 }
939
940
941 Handle<Value> GetDomain() {
942   // no domain can exist if no domain module has been loaded
943   if (!InDomain() || p_domain_box.IsEmpty())
944     return Null(node_isolate);
945
946   return PersistentToLocal(node_isolate, p_domain_box)->Get(0);
947 }
948
949
950 Handle<Value>
951 MakeDomainCallback(const Handle<Object> object,
952                    const Handle<Function> callback,
953                    int argc,
954                    Handle<Value> argv[]) {
955   // TODO(trevnorris) Hook for long stack traces to be made here.
956
957   // lazy load domain specific symbols
958   if (enter_symbol.IsEmpty()) {
959     enter_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "enter");
960     exit_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "exit");
961     disposed_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "_disposed");
962   }
963
964   Local<Value> domain_v = object->Get(domain_symbol);
965   Local<Object> domain;
966   Local<Function> enter;
967   Local<Function> exit;
968
969   TryCatch try_catch;
970   try_catch.SetVerbose(true);
971
972   bool has_domain = domain_v->IsObject();
973   if (has_domain) {
974     domain = domain_v->ToObject();
975     assert(!domain.IsEmpty());
976     if (domain->Get(disposed_symbol)->IsTrue()) {
977       // domain has been disposed of.
978       return Undefined(node_isolate);
979     }
980     enter = Local<Function>::Cast(domain->Get(enter_symbol));
981     assert(!enter.IsEmpty());
982     enter->Call(domain, 0, NULL);
983
984     if (try_catch.HasCaught()) {
985       return Undefined(node_isolate);
986     }
987   }
988
989   Local<Value> ret = callback->Call(object, argc, argv);
990
991   if (try_catch.HasCaught()) {
992     return Undefined(node_isolate);
993   }
994
995   if (has_domain) {
996     exit = Local<Function>::Cast(domain->Get(exit_symbol));
997     assert(!exit.IsEmpty());
998     exit->Call(domain, 0, NULL);
999
1000     if (try_catch.HasCaught()) {
1001       return Undefined(node_isolate);
1002     }
1003   }
1004
1005   if (tick_infobox.last_threw == 1) {
1006     tick_infobox.last_threw = 0;
1007     return ret;
1008   }
1009
1010   if (tick_infobox.in_tick == 1) {
1011     return ret;
1012   }
1013
1014   if (tick_infobox.length == 0) {
1015     tick_infobox.index = 0;
1016     return ret;
1017   }
1018
1019   // process nextTicks after call
1020   Local<Object> process = PersistentToLocal(node_isolate, process_p);
1021   Local<Function> fn = PersistentToLocal(node_isolate, process_tickCallback);
1022   fn->Call(process, 0, NULL);
1023
1024   if (try_catch.HasCaught()) {
1025     return Undefined(node_isolate);
1026   }
1027
1028   return ret;
1029 }
1030
1031
1032 Handle<Value>
1033 MakeCallback(const Handle<Object> object,
1034              const Handle<Function> callback,
1035              int argc,
1036              Handle<Value> argv[]) {
1037   if (process_state == SHUTTING_DOWN)
1038     return Undefined(node_isolate);
1039
1040   // TODO(trevnorris) Hook for long stack traces to be made here.
1041   Local<Object> process = PersistentToLocal(node_isolate, process_p);
1042
1043   if (using_domains)
1044     return MakeDomainCallback(object, callback, argc, argv);
1045
1046   // lazy load no domain next tick callbacks
1047   if (process_tickCallback.IsEmpty()) {
1048     Local<Value> cb_v =
1049         process->Get(FIXED_ONE_BYTE_STRING(node_isolate, "_tickCallback"));
1050     if (!cb_v->IsFunction()) {
1051       fprintf(stderr, "process._tickCallback assigned to non-function\n");
1052       abort();
1053     }
1054     process_tickCallback.Reset(node_isolate, cb_v.As<Function>());
1055   }
1056
1057   TryCatch try_catch;
1058   try_catch.SetVerbose(true);
1059
1060   Local<Value> ret = callback->Call(object, argc, argv);
1061
1062   if (try_catch.HasCaught()) {
1063     return Undefined(node_isolate);
1064   }
1065
1066   if (tick_infobox.in_tick == 1) {
1067     return ret;
1068   }
1069
1070   if (tick_infobox.length == 0) {
1071     tick_infobox.index = 0;
1072     return ret;
1073   }
1074
1075   // process nextTicks after call
1076   Local<Function> fn = PersistentToLocal(node_isolate, process_tickCallback);
1077   fn->Call(process, 0, NULL);
1078
1079   if (try_catch.HasCaught()) {
1080     return Undefined(node_isolate);
1081   }
1082
1083   return ret;
1084 }
1085
1086
1087 // Internal only.
1088 Handle<Value>
1089 MakeCallback(const Handle<Object> object,
1090              uint32_t index,
1091              int argc,
1092              Handle<Value> argv[]) {
1093   HandleScope scope(node_isolate);
1094
1095   Local<Function> callback = object->Get(index).As<Function>();
1096   assert(callback->IsFunction());
1097
1098   if (using_domains)
1099     return scope.Close(MakeDomainCallback(object, callback, argc, argv));
1100   return scope.Close(MakeCallback(object, callback, argc, argv));
1101 }
1102
1103
1104 Handle<Value>
1105 MakeCallback(const Handle<Object> object,
1106              const Handle<String> symbol,
1107              int argc,
1108              Handle<Value> argv[]) {
1109   HandleScope scope(node_isolate);
1110
1111   Local<Function> callback = object->Get(symbol).As<Function>();
1112   assert(callback->IsFunction());
1113
1114   if (using_domains)
1115     return scope.Close(MakeDomainCallback(object, callback, argc, argv));
1116   return scope.Close(MakeCallback(object, callback, argc, argv));
1117 }
1118
1119
1120 Handle<Value>
1121 MakeCallback(const Handle<Object> object,
1122              const char* method,
1123              int argc,
1124              Handle<Value> argv[]) {
1125   HandleScope scope(node_isolate);
1126
1127   Local<String> method_string = OneByteString(node_isolate, method);
1128   Handle<Value> ret = MakeCallback(object, method_string, argc, argv);
1129
1130   return scope.Close(ret);
1131 }
1132
1133
1134 enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
1135   HandleScope scope(node_isolate);
1136
1137   if (!encoding_v->IsString()) return _default;
1138
1139   String::Utf8Value encoding(encoding_v);
1140
1141   if (strcasecmp(*encoding, "utf8") == 0) {
1142     return UTF8;
1143   } else if (strcasecmp(*encoding, "utf-8") == 0) {
1144     return UTF8;
1145   } else if (strcasecmp(*encoding, "ascii") == 0) {
1146     return ASCII;
1147   } else if (strcasecmp(*encoding, "base64") == 0) {
1148     return BASE64;
1149   } else if (strcasecmp(*encoding, "ucs2") == 0) {
1150     return UCS2;
1151   } else if (strcasecmp(*encoding, "ucs-2") == 0) {
1152     return UCS2;
1153   } else if (strcasecmp(*encoding, "utf16le") == 0) {
1154     return UCS2;
1155   } else if (strcasecmp(*encoding, "utf-16le") == 0) {
1156     return UCS2;
1157   } else if (strcasecmp(*encoding, "binary") == 0) {
1158     return BINARY;
1159   } else if (strcasecmp(*encoding, "buffer") == 0) {
1160     return BUFFER;
1161   } else if (strcasecmp(*encoding, "hex") == 0) {
1162     return HEX;
1163   } else if (strcasecmp(*encoding, "raw") == 0) {
1164     if (!no_deprecation) {
1165       fprintf(stderr, "'raw' (array of integers) has been removed. "
1166                       "Use 'binary'.\n");
1167     }
1168     return BINARY;
1169   } else if (strcasecmp(*encoding, "raws") == 0) {
1170     if (!no_deprecation) {
1171       fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
1172                       "Please update your code.\n");
1173     }
1174     return BINARY;
1175   } else {
1176     return _default;
1177   }
1178 }
1179
1180 Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
1181   return StringBytes::Encode(static_cast<const char*>(buf),
1182                              len,
1183                              encoding);
1184 }
1185
1186 // Returns -1 if the handle was not valid for decoding
1187 ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
1188   HandleScope scope(node_isolate);
1189
1190   if (val->IsArray()) {
1191     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
1192                     "Use 'binary'.\n");
1193     assert(0);
1194     return -1;
1195   }
1196
1197   return StringBytes::Size(val, encoding);
1198 }
1199
1200 #ifndef MIN
1201 # define MIN(a, b) ((a) < (b) ? (a) : (b))
1202 #endif
1203
1204 // Returns number of bytes written.
1205 ssize_t DecodeWrite(char *buf,
1206                     size_t buflen,
1207                     v8::Handle<v8::Value> val,
1208                     enum encoding encoding) {
1209   return StringBytes::Write(buf, buflen, val, encoding, NULL);
1210 }
1211
1212 void DisplayExceptionLine(Handle<Message> message) {
1213   // Prevent re-entry into this function.  For example, if there is
1214   // a throw from a program in vm.runInThisContext(code, filename, true),
1215   // then we want to show the original failure, not the secondary one.
1216   static bool displayed_error = false;
1217
1218   if (displayed_error) return;
1219   displayed_error = true;
1220
1221   uv_tty_reset_mode();
1222
1223   fprintf(stderr, "\n");
1224
1225   if (!message.IsEmpty()) {
1226     // Print (filename):(line number): (message).
1227     String::Utf8Value filename(message->GetScriptResourceName());
1228     const char* filename_string = *filename;
1229     int linenum = message->GetLineNumber();
1230     fprintf(stderr, "%s:%i\n", filename_string, linenum);
1231     // Print line of source code.
1232     String::Utf8Value sourceline(message->GetSourceLine());
1233     const char* sourceline_string = *sourceline;
1234
1235     // Because of how node modules work, all scripts are wrapped with a
1236     // "function (module, exports, __filename, ...) {"
1237     // to provide script local variables.
1238     //
1239     // When reporting errors on the first line of a script, this wrapper
1240     // function is leaked to the user. There used to be a hack here to
1241     // truncate off the first 62 characters, but it caused numerous other
1242     // problems when vm.runIn*Context() methods were used for non-module
1243     // code.
1244     //
1245     // If we ever decide to re-instate such a hack, the following steps
1246     // must be taken:
1247     //
1248     // 1. Pass a flag around to say "this code was wrapped"
1249     // 2. Update the stack frame output so that it is also correct.
1250     //
1251     // It would probably be simpler to add a line rather than add some
1252     // number of characters to the first line, since V8 truncates the
1253     // sourceline to 78 characters, and we end up not providing very much
1254     // useful debugging info to the user if we remove 62 characters.
1255
1256     int start = message->GetStartColumn();
1257     int end = message->GetEndColumn();
1258
1259     fprintf(stderr, "%s\n", sourceline_string);
1260     // Print wavy underline (GetUnderline is deprecated).
1261     for (int i = 0; i < start; i++) {
1262       fputc((sourceline_string[i] == '\t') ? '\t' : ' ', stderr);
1263     }
1264     for (int i = start; i < end; i++) {
1265       fputc('^', stderr);
1266     }
1267     fputc('\n', stderr);
1268   }
1269 }
1270
1271
1272 static void ReportException(Handle<Value> er, Handle<Message> message) {
1273   HandleScope scope(node_isolate);
1274
1275   DisplayExceptionLine(message);
1276
1277   Local<Value> trace_value(
1278       er->ToObject()->Get(FIXED_ONE_BYTE_STRING(node_isolate, "stack")));
1279   String::Utf8Value trace(trace_value);
1280
1281   // range errors have a trace member set to undefined
1282   if (trace.length() > 0 && !trace_value->IsUndefined()) {
1283     fprintf(stderr, "%s\n", *trace);
1284   } else {
1285     // this really only happens for RangeErrors, since they're the only
1286     // kind that won't have all this info in the trace, or when non-Error
1287     // objects are thrown manually.
1288     Local<Value> message;
1289     Local<Value> name;
1290
1291     if (er->IsObject()) {
1292       Local<Object> err_obj = er.As<Object>();
1293       message = err_obj->Get(FIXED_ONE_BYTE_STRING(node_isolate, "message"));
1294       name = err_obj->Get(FIXED_ONE_BYTE_STRING(node_isolate, "name"));
1295     }
1296
1297     if (message.IsEmpty() ||
1298         message->IsUndefined() ||
1299         name.IsEmpty() ||
1300         name->IsUndefined()) {
1301       // Not an error object. Just print as-is.
1302       String::Utf8Value message(er);
1303       fprintf(stderr, "%s\n", *message);
1304     } else {
1305       String::Utf8Value name_string(name);
1306       String::Utf8Value message_string(message);
1307       fprintf(stderr, "%s: %s\n", *name_string, *message_string);
1308     }
1309   }
1310
1311   fflush(stderr);
1312 }
1313
1314
1315 static void ReportException(const TryCatch& try_catch) {
1316   ReportException(try_catch.Exception(), try_catch.Message());
1317 }
1318
1319
1320 // Executes a str within the current v8 context.
1321 Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
1322   HandleScope scope(node_isolate);
1323   TryCatch try_catch;
1324
1325   // try_catch must be nonverbose to disable FatalException() handler,
1326   // we will handle exceptions ourself.
1327   try_catch.SetVerbose(false);
1328
1329   Local<v8::Script> script = v8::Script::Compile(source, filename);
1330   if (script.IsEmpty()) {
1331     ReportException(try_catch);
1332     exit(3);
1333   }
1334
1335   Local<Value> result = script->Run();
1336   if (result.IsEmpty()) {
1337     ReportException(try_catch);
1338     exit(4);
1339   }
1340
1341   return scope.Close(result);
1342 }
1343
1344
1345 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1346   HandleScope scope(node_isolate);
1347
1348   Local<Array> ary = Array::New();
1349   QUEUE* q = NULL;
1350   int i = 0;
1351
1352   QUEUE_FOREACH(q, &req_wrap_queue) {
1353     ReqWrap<uv_req_t>* w = container_of(q, ReqWrap<uv_req_t>, req_wrap_queue_);
1354     if (w->persistent().IsEmpty()) continue;
1355     ary->Set(i++, w->object());
1356   }
1357
1358   args.GetReturnValue().Set(ary);
1359 }
1360
1361
1362 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1363 // implemented here for consistency with GetActiveRequests().
1364 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1365   HandleScope scope(node_isolate);
1366
1367   Local<Array> ary = Array::New();
1368   QUEUE* q = NULL;
1369   int i = 0;
1370
1371   Local<String> owner_sym = FIXED_ONE_BYTE_STRING(node_isolate, "owner");
1372
1373   QUEUE_FOREACH(q, &handle_wrap_queue) {
1374     HandleWrap* w = container_of(q, HandleWrap, handle_wrap_queue_);
1375     if (w->persistent().IsEmpty() || (w->flags_ & HandleWrap::kUnref)) continue;
1376     Local<Object> object = w->object();
1377     Local<Value> owner = object->Get(owner_sym);
1378     if (owner->IsUndefined()) owner = object;
1379     ary->Set(i++, owner);
1380   }
1381
1382   args.GetReturnValue().Set(ary);
1383 }
1384
1385
1386 static void Abort(const FunctionCallbackInfo<Value>& args) {
1387   abort();
1388 }
1389
1390
1391 static void Chdir(const FunctionCallbackInfo<Value>& args) {
1392   HandleScope scope(node_isolate);
1393
1394   if (args.Length() != 1 || !args[0]->IsString()) {
1395     return ThrowError("Bad argument.");  // FIXME(bnoordhuis) ThrowTypeError?
1396   }
1397
1398   String::Utf8Value path(args[0]);
1399   int err = uv_chdir(*path);
1400   if (err) {
1401     return ThrowUVException(err, "uv_chdir");
1402   }
1403 }
1404
1405
1406 static void Cwd(const FunctionCallbackInfo<Value>& args) {
1407   HandleScope scope(node_isolate);
1408 #ifdef _WIN32
1409   /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
1410   char buf[MAX_PATH * 4 + 1];
1411 #else
1412   char buf[PATH_MAX + 1];
1413 #endif
1414
1415   int err = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
1416   if (err) {
1417     return ThrowUVException(err, "uv_cwd");
1418   }
1419
1420   buf[ARRAY_SIZE(buf) - 1] = '\0';
1421   Local<String> cwd = String::NewFromUtf8(node_isolate, buf);
1422
1423   args.GetReturnValue().Set(cwd);
1424 }
1425
1426
1427 static void Umask(const FunctionCallbackInfo<Value>& args) {
1428   HandleScope scope(node_isolate);
1429   uint32_t old;
1430
1431   if (args.Length() < 1 || args[0]->IsUndefined()) {
1432     old = umask(0);
1433     umask(static_cast<mode_t>(old));
1434   } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1435     return ThrowTypeError("argument must be an integer or octal string.");
1436   } else {
1437     int oct;
1438     if (args[0]->IsInt32()) {
1439       oct = args[0]->Uint32Value();
1440     } else {
1441       oct = 0;
1442       String::Utf8Value str(args[0]);
1443
1444       // Parse the octal string.
1445       for (int i = 0; i < str.length(); i++) {
1446         char c = (*str)[i];
1447         if (c > '7' || c < '0') {
1448           return ThrowTypeError("invalid octal string");
1449         }
1450         oct *= 8;
1451         oct += c - '0';
1452       }
1453     }
1454     old = umask(static_cast<mode_t>(oct));
1455   }
1456
1457   args.GetReturnValue().Set(old);
1458 }
1459
1460
1461 #if defined(__POSIX__) && !defined(__ANDROID__)
1462
1463 static const uid_t uid_not_found = static_cast<uid_t>(-1);
1464 static const gid_t gid_not_found = static_cast<gid_t>(-1);
1465
1466
1467 static uid_t uid_by_name(const char* name) {
1468   struct passwd pwd;
1469   struct passwd* pp;
1470   char buf[8192];
1471
1472   errno = 0;
1473   pp = NULL;
1474
1475   if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != NULL) {
1476     return pp->pw_uid;
1477   }
1478
1479   return uid_not_found;
1480 }
1481
1482
1483 static char* name_by_uid(uid_t uid) {
1484   struct passwd pwd;
1485   struct passwd* pp;
1486   char buf[8192];
1487   int rc;
1488
1489   errno = 0;
1490   pp = NULL;
1491
1492   if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
1493     return strdup(pp->pw_name);
1494   }
1495
1496   if (rc == 0) {
1497     errno = ENOENT;
1498   }
1499
1500   return NULL;
1501 }
1502
1503
1504 static gid_t gid_by_name(const char* name) {
1505   struct group pwd;
1506   struct group* pp;
1507   char buf[8192];
1508
1509   errno = 0;
1510   pp = NULL;
1511
1512   if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != NULL) {
1513     return pp->gr_gid;
1514   }
1515
1516   return gid_not_found;
1517 }
1518
1519
1520 #if 0  // For future use.
1521 static const char* name_by_gid(gid_t gid) {
1522   struct group pwd;
1523   struct group* pp;
1524   char buf[8192];
1525   int rc;
1526
1527   errno = 0;
1528   pp = NULL;
1529
1530   if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 && pp != NULL) {
1531     return strdup(pp->gr_name);
1532   }
1533
1534   if (rc == 0) {
1535     errno = ENOENT;
1536   }
1537
1538   return NULL;
1539 }
1540 #endif
1541
1542
1543 static uid_t uid_by_name(Handle<Value> value) {
1544   if (value->IsUint32()) {
1545     return static_cast<uid_t>(value->Uint32Value());
1546   } else {
1547     String::Utf8Value name(value);
1548     return uid_by_name(*name);
1549   }
1550 }
1551
1552
1553 static gid_t gid_by_name(Handle<Value> value) {
1554   if (value->IsUint32()) {
1555     return static_cast<gid_t>(value->Uint32Value());
1556   } else {
1557     String::Utf8Value name(value);
1558     return gid_by_name(*name);
1559   }
1560 }
1561
1562
1563 static void GetUid(const FunctionCallbackInfo<Value>& args) {
1564   args.GetReturnValue().Set(getuid());
1565 }
1566
1567
1568 static void GetGid(const FunctionCallbackInfo<Value>& args) {
1569   args.GetReturnValue().Set(getgid());
1570 }
1571
1572
1573 static void SetGid(const FunctionCallbackInfo<Value>& args) {
1574   HandleScope scope(node_isolate);
1575
1576   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1577     return ThrowTypeError("setgid argument must be a number or a string");
1578   }
1579
1580   gid_t gid = gid_by_name(args[0]);
1581
1582   if (gid == gid_not_found) {
1583     return ThrowError("setgid group id does not exist");
1584   }
1585
1586   if (setgid(gid)) {
1587     return ThrowErrnoException(errno, "setgid");
1588   }
1589 }
1590
1591
1592 static void SetUid(const FunctionCallbackInfo<Value>& args) {
1593   HandleScope scope(node_isolate);
1594
1595   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1596     return ThrowTypeError("setuid argument must be a number or a string");
1597   }
1598
1599   uid_t uid = uid_by_name(args[0]);
1600
1601   if (uid == uid_not_found) {
1602     return ThrowError("setuid user id does not exist");
1603   }
1604
1605   if (setuid(uid)) {
1606     return ThrowErrnoException(errno, "setuid");
1607   }
1608 }
1609
1610
1611 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
1612   HandleScope scope(node_isolate);
1613
1614   int ngroups = getgroups(0, NULL);
1615
1616   if (ngroups == -1) {
1617     return ThrowErrnoException(errno, "getgroups");
1618   }
1619
1620   gid_t* groups = new gid_t[ngroups];
1621
1622   ngroups = getgroups(ngroups, groups);
1623
1624   if (ngroups == -1) {
1625     delete[] groups;
1626     return ThrowErrnoException(errno, "getgroups");
1627   }
1628
1629   Local<Array> groups_list = Array::New(ngroups);
1630   bool seen_egid = false;
1631   gid_t egid = getegid();
1632
1633   for (int i = 0; i < ngroups; i++) {
1634     groups_list->Set(i, Integer::New(groups[i], node_isolate));
1635     if (groups[i] == egid) seen_egid = true;
1636   }
1637
1638   delete[] groups;
1639
1640   if (seen_egid == false) {
1641     groups_list->Set(ngroups, Integer::New(egid, node_isolate));
1642   }
1643
1644   args.GetReturnValue().Set(groups_list);
1645 }
1646
1647
1648 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
1649   HandleScope scope(node_isolate);
1650
1651   if (!args[0]->IsArray()) {
1652     return ThrowTypeError("argument 1 must be an array");
1653   }
1654
1655   Local<Array> groups_list = args[0].As<Array>();
1656   size_t size = groups_list->Length();
1657   gid_t* groups = new gid_t[size];
1658
1659   for (size_t i = 0; i < size; i++) {
1660     gid_t gid = gid_by_name(groups_list->Get(i));
1661
1662     if (gid == gid_not_found) {
1663       delete[] groups;
1664       return ThrowError("group name not found");
1665     }
1666
1667     groups[i] = gid;
1668   }
1669
1670   int rc = setgroups(size, groups);
1671   delete[] groups;
1672
1673   if (rc == -1) {
1674     return ThrowErrnoException(errno, "setgroups");
1675   }
1676 }
1677
1678
1679 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
1680   HandleScope scope(node_isolate);
1681
1682   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1683     return ThrowTypeError("argument 1 must be a number or a string");
1684   }
1685
1686   if (!args[1]->IsUint32() && !args[1]->IsString()) {
1687     return ThrowTypeError("argument 2 must be a number or a string");
1688   }
1689
1690   String::Utf8Value arg0(args[0]);
1691   gid_t extra_group;
1692   bool must_free;
1693   char* user;
1694
1695   if (args[0]->IsUint32()) {
1696     user = name_by_uid(args[0]->Uint32Value());
1697     must_free = true;
1698   } else {
1699     user = *arg0;
1700     must_free = false;
1701   }
1702
1703   if (user == NULL) {
1704     return ThrowError("initgroups user not found");
1705   }
1706
1707   extra_group = gid_by_name(args[1]);
1708
1709   if (extra_group == gid_not_found) {
1710     if (must_free) free(user);
1711     return ThrowError("initgroups extra group not found");
1712   }
1713
1714   int rc = initgroups(user, extra_group);
1715
1716   if (must_free) {
1717     free(user);
1718   }
1719
1720   if (rc) {
1721     return ThrowErrnoException(errno, "initgroups");
1722   }
1723 }
1724
1725 #endif  // __POSIX__ && !defined(__ANDROID__)
1726
1727
1728 void MaybeCloseNamedPipe(uv_shutdown_t* req, int status) {
1729   uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(req->handle);
1730   delete req;
1731
1732   if (status == UV_ECANCELED) {
1733     return;  // Already closing.
1734   }
1735   if (status == UV_EPIPE) {
1736     return;  // Read end went away before shutdown completed.
1737   }
1738   assert(status == 0);
1739
1740   if (uv_is_closing(handle)) {
1741     return;
1742   }
1743
1744   uv_close(handle, NULL);
1745 }
1746
1747
1748 void MaybeCloseHandle(uv_handle_t* handle, void* unused) {
1749   if (uv_is_closing(handle)) {
1750     return;
1751   }
1752
1753   // Named pipes get special treatment: we do a shutdown first to flush
1754   // pending writes.  Avoids truncated stdout/stderr output on Windows.
1755   bool do_shutdown = handle->type == UV_NAMED_PIPE &&
1756                      uv_is_writable(reinterpret_cast<uv_stream_t*>(handle));
1757
1758   if (do_shutdown == false) {
1759     uv_close(handle, NULL);
1760     return;
1761   }
1762
1763   uv_shutdown_t* req = new uv_shutdown_t;
1764   uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(handle);
1765   int err = uv_shutdown(req, stream, MaybeCloseNamedPipe);
1766   if (err) {
1767     assert(err == UV_ENOTCONN);
1768     delete req;
1769   }
1770 }
1771
1772
1773 void DisposeEventLoop(uv_loop_t* loop) {
1774   // Don't call into JS land from now on.
1775   process_state = SHUTTING_DOWN;
1776   // Force-close open handles.
1777   uv_walk(loop, MaybeCloseHandle, NULL);
1778   uv_run(loop, UV_RUN_DEFAULT);
1779   uv_loop_delete(loop);
1780 }
1781
1782
1783 void Exit(const FunctionCallbackInfo<Value>& args) {
1784   HandleScope scope(node_isolate);
1785   int32_t exit_code = args[0]->Int32Value();
1786   DisposeEventLoop(uv_default_loop());
1787   exit(exit_code);
1788 }
1789
1790
1791 static void Uptime(const FunctionCallbackInfo<Value>& args) {
1792   HandleScope scope(node_isolate);
1793   double uptime;
1794   if (uv_uptime(&uptime)) return;
1795   args.GetReturnValue().Set(uptime - prog_start_time);
1796 }
1797
1798
1799 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
1800   HandleScope scope(node_isolate);
1801
1802   size_t rss;
1803
1804   int err = uv_resident_set_memory(&rss);
1805   if (err) {
1806     return ThrowUVException(err, "uv_resident_set_memory");
1807   }
1808
1809   Local<Object> info = Object::New();
1810
1811   if (rss_symbol.IsEmpty()) {
1812     rss_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "rss");
1813     heap_total_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "heapTotal");
1814     heap_used_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "heapUsed");
1815   }
1816
1817   info->Set(rss_symbol, Number::New(rss));
1818
1819   // V8 memory usage
1820   HeapStatistics v8_heap_stats;
1821   node_isolate->GetHeapStatistics(&v8_heap_stats);
1822   info->Set(heap_total_symbol,
1823             Integer::NewFromUnsigned(v8_heap_stats.total_heap_size(),
1824                                      node_isolate));
1825   info->Set(heap_used_symbol,
1826             Integer::NewFromUnsigned(v8_heap_stats.used_heap_size(),
1827                                      node_isolate));
1828
1829   args.GetReturnValue().Set(info);
1830 }
1831
1832
1833 void Kill(const FunctionCallbackInfo<Value>& args) {
1834   HandleScope scope(node_isolate);
1835
1836   if (args.Length() != 2) {
1837     return ThrowError("Bad argument.");
1838   }
1839
1840   int pid = args[0]->IntegerValue();
1841   int sig = args[1]->Int32Value();
1842   int err = uv_kill(pid, sig);
1843   args.GetReturnValue().Set(err);
1844 }
1845
1846 // used in Hrtime() below
1847 #define NANOS_PER_SEC 1000000000
1848
1849 // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
1850 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
1851 // so this function instead returns an Array with 2 entries representing seconds
1852 // and nanoseconds, to avoid any integer overflow possibility.
1853 // Pass in an Array from a previous hrtime() call to instead get a time diff.
1854 void Hrtime(const FunctionCallbackInfo<Value>& args) {
1855   HandleScope scope(node_isolate);
1856
1857   uint64_t t = uv_hrtime();
1858
1859   if (args.Length() > 0) {
1860     // return a time diff tuple
1861     if (!args[0]->IsArray()) {
1862       return ThrowTypeError("process.hrtime() only accepts an Array tuple.");
1863     }
1864     Local<Array> inArray = Local<Array>::Cast(args[0]);
1865     uint64_t seconds = inArray->Get(0)->Uint32Value();
1866     uint64_t nanos = inArray->Get(1)->Uint32Value();
1867     t -= (seconds * NANOS_PER_SEC) + nanos;
1868   }
1869
1870   Local<Array> tuple = Array::New(2);
1871   tuple->Set(0, Integer::NewFromUnsigned(t / NANOS_PER_SEC, node_isolate));
1872   tuple->Set(1, Integer::NewFromUnsigned(t % NANOS_PER_SEC, node_isolate));
1873   args.GetReturnValue().Set(tuple);
1874 }
1875
1876
1877 typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
1878
1879 // DLOpen is process.dlopen(module, filename).
1880 // Used to load 'module.node' dynamically shared objects.
1881 void DLOpen(const FunctionCallbackInfo<Value>& args) {
1882   HandleScope scope(node_isolate);
1883   char symbol[1024], *base, *pos;
1884   uv_lib_t lib;
1885   int r;
1886
1887   if (args.Length() < 2) {
1888     return ThrowError("process.dlopen takes exactly 2 arguments.");
1889   }
1890
1891   Local<Object> module = args[0]->ToObject();  // Cast
1892   String::Utf8Value filename(args[1]);  // Cast
1893
1894   if (exports_symbol.IsEmpty()) {
1895     exports_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "exports");
1896   }
1897   Local<Object> exports = module->Get(exports_symbol)->ToObject();
1898
1899   if (uv_dlopen(*filename, &lib)) {
1900     Local<String> errmsg = OneByteString(node_isolate, uv_dlerror(&lib));
1901 #ifdef _WIN32
1902     // Windows needs to add the filename into the error message
1903     errmsg = String::Concat(errmsg, args[1]->ToString());
1904 #endif  // _WIN32
1905     ThrowException(Exception::Error(errmsg));
1906     return;
1907   }
1908
1909   String::Utf8Value path(args[1]);
1910   base = *path;
1911
1912   /* Find the shared library filename within the full path. */
1913 #ifdef __POSIX__
1914   pos = strrchr(base, '/');
1915   if (pos != NULL) {
1916     base = pos + 1;
1917   }
1918 #else  // Windows
1919   for (;;) {
1920     pos = strpbrk(base, "\\/:");
1921     if (pos == NULL) {
1922       break;
1923     }
1924     base = pos + 1;
1925   }
1926 #endif  // __POSIX__
1927
1928   /* Strip the .node extension. */
1929   pos = strrchr(base, '.');
1930   if (pos != NULL) {
1931     *pos = '\0';
1932   }
1933
1934   /* Add the `_module` suffix to the extension name. */
1935   r = snprintf(symbol, sizeof symbol, "%s_module", base);
1936   if (r <= 0 || static_cast<size_t>(r) >= sizeof symbol) {
1937     return ThrowError("Out of memory.");
1938   }
1939
1940   /* Replace dashes with underscores. When loading foo-bar.node,
1941    * look for foo_bar_module, not foo-bar_module.
1942    */
1943   for (pos = symbol; *pos != '\0'; ++pos) {
1944     if (*pos == '-') *pos = '_';
1945   }
1946
1947   node_module_struct *mod;
1948   if (uv_dlsym(&lib, symbol, reinterpret_cast<void**>(&mod))) {
1949     char errmsg[1024];
1950     snprintf(errmsg, sizeof(errmsg), "Symbol %s not found.", symbol);
1951     return ThrowError(errmsg);
1952   }
1953
1954   if (mod->version != NODE_MODULE_VERSION) {
1955     char errmsg[1024];
1956     snprintf(errmsg,
1957              sizeof(errmsg),
1958              "Module version mismatch. Expected %d, got %d.",
1959              NODE_MODULE_VERSION, mod->version);
1960     return ThrowError(errmsg);
1961   }
1962
1963   // Execute the C++ module
1964   mod->register_func(exports, module);
1965
1966   // Tell coverity that 'handle' should not be freed when we return.
1967   // coverity[leaked_storage]
1968 }
1969
1970
1971 static void OnFatalError(const char* location, const char* message) {
1972   if (location) {
1973     fprintf(stderr, "FATAL ERROR: %s %s\n", location, message);
1974   } else {
1975     fprintf(stderr, "FATAL ERROR: %s\n", message);
1976   }
1977   fflush(stderr);
1978 #if defined(DEBUG)
1979   abort();
1980 #endif
1981   exit(5);
1982 }
1983
1984
1985 NO_RETURN void FatalError(const char* location, const char* message) {
1986   OnFatalError(location, message);
1987   // to supress compiler warning
1988   abort();
1989 }
1990
1991
1992 void FatalException(Handle<Value> error, Handle<Message> message) {
1993   HandleScope scope(node_isolate);
1994
1995   if (fatal_exception_symbol.IsEmpty()) {
1996     fatal_exception_symbol =
1997         FIXED_ONE_BYTE_STRING(node_isolate, "_fatalException");
1998   }
1999
2000   Local<Object> process = PersistentToLocal(node_isolate, process_p);
2001   Local<Value> fatal_v = process->Get(fatal_exception_symbol);
2002
2003   if (!fatal_v->IsFunction()) {
2004     // failed before the process._fatalException function was added!
2005     // this is probably pretty bad.  Nothing to do but report and exit.
2006     ReportException(error, message);
2007     exit(6);
2008   }
2009
2010   Local<Function> fatal_f = Local<Function>::Cast(fatal_v);
2011
2012   TryCatch fatal_try_catch;
2013
2014   // Do not call FatalException when _fatalException handler throws
2015   fatal_try_catch.SetVerbose(false);
2016
2017   // this will return true if the JS layer handled it, false otherwise
2018   Local<Value> caught = fatal_f->Call(process, 1, &error);
2019
2020   if (fatal_try_catch.HasCaught()) {
2021     // the fatal exception function threw, so we must exit
2022     ReportException(fatal_try_catch);
2023     exit(7);
2024   }
2025
2026   if (false == caught->BooleanValue()) {
2027     ReportException(error, message);
2028     exit(8);
2029   }
2030 }
2031
2032
2033 void FatalException(const TryCatch& try_catch) {
2034   HandleScope scope(node_isolate);
2035   // TODO(bajtos) do not call FatalException if try_catch is verbose
2036   // (requires V8 API to expose getter for try_catch.is_verbose_)
2037   FatalException(try_catch.Exception(), try_catch.Message());
2038 }
2039
2040
2041 void OnMessage(Handle<Message> message, Handle<Value> error) {
2042   // The current version of V8 sends messages for errors only
2043   // (thus `error` is always set).
2044   FatalException(error, message);
2045 }
2046
2047
2048 static void Binding(const FunctionCallbackInfo<Value>& args) {
2049   HandleScope scope(node_isolate);
2050
2051   Local<String> module = args[0]->ToString();
2052   String::Utf8Value module_v(module);
2053   node_module_struct* modp;
2054
2055   Local<Object> cache = PersistentToLocal(node_isolate, binding_cache);
2056   Local<Object> exports;
2057
2058   if (cache->Has(module)) {
2059     exports = cache->Get(module)->ToObject();
2060     args.GetReturnValue().Set(exports);
2061     return;
2062   }
2063
2064   // Append a string to process.moduleLoadList
2065   char buf[1024];
2066   snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2067
2068   Local<Array> modules = PersistentToLocal(node_isolate, module_load_list);
2069   uint32_t l = modules->Length();
2070   modules->Set(l, OneByteString(node_isolate, buf));
2071
2072   if ((modp = get_builtin_module(*module_v)) != NULL) {
2073     exports = Object::New();
2074     // Internal bindings don't have a "module" object,
2075     // only exports.
2076     modp->register_func(exports, Undefined(node_isolate));
2077     cache->Set(module, exports);
2078   } else if (!strcmp(*module_v, "constants")) {
2079     exports = Object::New();
2080     DefineConstants(exports);
2081     cache->Set(module, exports);
2082   } else if (!strcmp(*module_v, "natives")) {
2083     exports = Object::New();
2084     DefineJavaScript(exports);
2085     cache->Set(module, exports);
2086   } else {
2087     return ThrowError("No such module");
2088   }
2089
2090   args.GetReturnValue().Set(exports);
2091 }
2092
2093
2094 static void ProcessTitleGetter(Local<String> property,
2095                                const PropertyCallbackInfo<Value>& info) {
2096   HandleScope scope(node_isolate);
2097   char buffer[512];
2098   uv_get_process_title(buffer, sizeof(buffer));
2099   info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, buffer));
2100 }
2101
2102
2103 static void ProcessTitleSetter(Local<String> property,
2104                                Local<Value> value,
2105                                const PropertyCallbackInfo<void>& info) {
2106   HandleScope scope(node_isolate);
2107   String::Utf8Value title(value);
2108   // TODO(piscisaureus): protect with a lock
2109   uv_set_process_title(*title);
2110 }
2111
2112
2113 static void EnvGetter(Local<String> property,
2114                       const PropertyCallbackInfo<Value>& info) {
2115   HandleScope scope(node_isolate);
2116 #ifdef __POSIX__
2117   String::Utf8Value key(property);
2118   const char* val = getenv(*key);
2119   if (val) {
2120     return info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, val));
2121   }
2122 #else  // _WIN32
2123   String::Value key(property);
2124   WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2125   DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2126                                          buffer,
2127                                          ARRAY_SIZE(buffer));
2128   // If result >= sizeof buffer the buffer was too small. That should never
2129   // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2130   // not found.
2131   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2132       result < ARRAY_SIZE(buffer)) {
2133     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2134     Local<String> rc = String::NewFromTwoByte(node_isolate, two_byte_buffer);
2135     return info.GetReturnValue().Set(rc);
2136   }
2137 #endif
2138   // Not found.  Fetch from prototype.
2139   info.GetReturnValue().Set(
2140       info.Data().As<Object>()->Get(property));
2141 }
2142
2143
2144 static void EnvSetter(Local<String> property,
2145                       Local<Value> value,
2146                       const PropertyCallbackInfo<Value>& info) {
2147   HandleScope scope(node_isolate);
2148 #ifdef __POSIX__
2149   String::Utf8Value key(property);
2150   String::Utf8Value val(value);
2151   setenv(*key, *val, 1);
2152 #else  // _WIN32
2153   String::Value key(property);
2154   String::Value val(value);
2155   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2156   // Environment variables that start with '=' are read-only.
2157   if (key_ptr[0] != L'=') {
2158     SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2159   }
2160 #endif
2161   // Whether it worked or not, always return rval.
2162   info.GetReturnValue().Set(value);
2163 }
2164
2165
2166 static void EnvQuery(Local<String> property,
2167                      const PropertyCallbackInfo<Integer>& info) {
2168   HandleScope scope(node_isolate);
2169   int32_t rc = -1;  // Not found unless proven otherwise.
2170 #ifdef __POSIX__
2171   String::Utf8Value key(property);
2172   if (getenv(*key)) rc = 0;
2173 #else  // _WIN32
2174   String::Value key(property);
2175   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2176   if (GetEnvironmentVariableW(key_ptr, NULL, 0) > 0 ||
2177       GetLastError() == ERROR_SUCCESS) {
2178     rc = 0;
2179     if (key_ptr[0] == L'=') {
2180       // Environment variables that start with '=' are hidden and read-only.
2181       rc = static_cast<int32_t>(v8::ReadOnly) |
2182            static_cast<int32_t>(v8::DontDelete) |
2183            static_cast<int32_t>(v8::DontEnum);
2184     }
2185   }
2186 #endif
2187   if (rc != -1) info.GetReturnValue().Set(rc);
2188 }
2189
2190
2191 static void EnvDeleter(Local<String> property,
2192                        const PropertyCallbackInfo<Boolean>& info) {
2193   HandleScope scope(node_isolate);
2194   bool rc = true;
2195 #ifdef __POSIX__
2196   String::Utf8Value key(property);
2197   rc = getenv(*key) != NULL;
2198   if (rc) unsetenv(*key);
2199 #else
2200   String::Value key(property);
2201   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2202   if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, NULL)) {
2203     // Deletion failed. Return true if the key wasn't there in the first place,
2204     // false if it is still there.
2205     rc = GetEnvironmentVariableW(key_ptr, NULL, NULL) == 0 &&
2206          GetLastError() != ERROR_SUCCESS;
2207   }
2208 #endif
2209   info.GetReturnValue().Set(rc);
2210 }
2211
2212
2213 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2214   HandleScope scope(node_isolate);
2215 #ifdef __POSIX__
2216   int size = 0;
2217   while (environ[size]) size++;
2218
2219   Local<Array> env = Array::New(size);
2220
2221   for (int i = 0; i < size; ++i) {
2222     const char* var = environ[i];
2223     const char* s = strchr(var, '=');
2224     const int length = s ? s - var : strlen(var);
2225     Local<String> name = String::NewFromUtf8(node_isolate,
2226                                              var,
2227                                              String::kNormalString,
2228                                              length);
2229     env->Set(i, name);
2230   }
2231 #else  // _WIN32
2232   WCHAR* environment = GetEnvironmentStringsW();
2233   if (environment == NULL) return;  // This should not happen.
2234   Local<Array> env = Array::New();
2235   WCHAR* p = environment;
2236   int i = 0;
2237   while (*p != NULL) {
2238     WCHAR *s;
2239     if (*p == L'=') {
2240       // If the key starts with '=' it is a hidden environment variable.
2241       p += wcslen(p) + 1;
2242       continue;
2243     } else {
2244       s = wcschr(p, L'=');
2245     }
2246     if (!s) {
2247       s = p + wcslen(p);
2248     }
2249     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2250     const size_t two_byte_buffer_len = s - p;
2251     Local<String> value = String::NewFromTwoByte(node_isolate,
2252                                                  two_byte_buffer,
2253                                                  String::kNormalString,
2254                                                  two_byte_buffer_len);
2255     env->Set(i++, value);
2256     p = s + wcslen(s) + 1;
2257   }
2258   FreeEnvironmentStringsW(environment);
2259 #endif
2260
2261   info.GetReturnValue().Set(env);
2262 }
2263
2264
2265 static Handle<Object> GetFeatures() {
2266   HandleScope scope(node_isolate);
2267
2268   Local<Object> obj = Object::New();
2269 #if defined(DEBUG) && DEBUG
2270   Local<Value> debug = True(node_isolate);
2271 #else
2272   Local<Value> debug = False(node_isolate);
2273 #endif  // defined(DEBUG) && DEBUG
2274
2275   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "debug"), debug);
2276
2277   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "uv"), True(node_isolate));
2278   // TODO(bnoordhuis) ping libuv
2279   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ipv6"), True(node_isolate));
2280
2281 #ifdef OPENSSL_NPN_NEGOTIATED
2282   Local<Boolean> tls_npn = True(node_isolate);
2283 #else
2284   Local<Boolean> tls_npn = False(node_isolate);
2285 #endif
2286   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_npn"), tls_npn);
2287
2288 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2289   Local<Boolean> tls_sni = True(node_isolate);
2290 #else
2291   Local<Boolean> tls_sni = False(node_isolate);
2292 #endif
2293   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_sni"), tls_sni);
2294
2295   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls"),
2296            Boolean::New(get_builtin_module("crypto") != NULL));
2297
2298   return scope.Close(obj);
2299 }
2300
2301
2302 static void DebugPortGetter(Local<String> property,
2303                             const PropertyCallbackInfo<Value>& info) {
2304   HandleScope scope(node_isolate);
2305   info.GetReturnValue().Set(debug_port);
2306 }
2307
2308
2309 static void DebugPortSetter(Local<String> property,
2310                             Local<Value> value,
2311                             const PropertyCallbackInfo<void>& info) {
2312   HandleScope scope(node_isolate);
2313   debug_port = value->NumberValue();
2314 }
2315
2316
2317 static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2318 static void DebugPause(const FunctionCallbackInfo<Value>& args);
2319 static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2320
2321
2322 void NeedImmediateCallbackGetter(Local<String> property,
2323                                  const PropertyCallbackInfo<Value>& info) {
2324   info.GetReturnValue().Set(need_immediate_cb);
2325 }
2326
2327
2328 static void NeedImmediateCallbackSetter(Local<String> property,
2329                                         Local<Value> value,
2330                                         const PropertyCallbackInfo<void>&) {
2331   HandleScope scope(node_isolate);
2332
2333   bool bool_value = value->BooleanValue();
2334
2335   if (need_immediate_cb == bool_value) return;
2336
2337   need_immediate_cb = bool_value;
2338
2339   if (need_immediate_cb) {
2340     uv_check_start(&check_immediate_watcher, node::CheckImmediate);
2341     // idle handle is needed only to maintain event loop
2342     uv_idle_start(&idle_immediate_dummy, node::IdleImmediateDummy);
2343   } else {
2344     uv_check_stop(&check_immediate_watcher);
2345     uv_idle_stop(&idle_immediate_dummy);
2346   }
2347 }
2348
2349
2350 #define READONLY_PROPERTY(obj, str, var)                                      \
2351   do {                                                                        \
2352     obj->Set(OneByteString(node_isolate, str), var, v8::ReadOnly);            \
2353   } while (0)
2354
2355
2356 Handle<Object> SetupProcessObject(int argc, char *argv[]) {
2357   HandleScope scope(node_isolate);
2358
2359   int i, j;
2360
2361   Local<FunctionTemplate> process_template = FunctionTemplate::New();
2362   process_template->SetClassName(
2363       FIXED_ONE_BYTE_STRING(node_isolate, "process"));
2364
2365   Local<Object> process = process_template->GetFunction()->NewInstance();
2366   assert(process.IsEmpty() == false);
2367   assert(process->IsObject() == true);
2368
2369   process_p.Reset(node_isolate, process);
2370
2371   process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "title"),
2372                        ProcessTitleGetter,
2373                        ProcessTitleSetter);
2374
2375   // process.version
2376   READONLY_PROPERTY(process,
2377                     "version",
2378                     FIXED_ONE_BYTE_STRING(node_isolate, NODE_VERSION));
2379
2380   // process.moduleLoadList
2381   Local<Array> modules = Array::New();
2382   module_load_list.Reset(node_isolate, modules);
2383   READONLY_PROPERTY(process, "moduleLoadList", modules);
2384
2385   // process.versions
2386   Local<Object> versions = Object::New();
2387   READONLY_PROPERTY(process, "versions", versions);
2388
2389   const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
2390                                      "."
2391                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR);
2392   READONLY_PROPERTY(versions,
2393                     "http_parser",
2394                     FIXED_ONE_BYTE_STRING(node_isolate, http_parser_version));
2395
2396   // +1 to get rid of the leading 'v'
2397   READONLY_PROPERTY(versions,
2398                     "node",
2399                     OneByteString(node_isolate, NODE_VERSION + 1));
2400   READONLY_PROPERTY(versions,
2401                     "v8",
2402                     OneByteString(node_isolate, V8::GetVersion()));
2403   READONLY_PROPERTY(versions,
2404                     "uv",
2405                     OneByteString(node_isolate, uv_version_string()));
2406   READONLY_PROPERTY(versions,
2407                     "zlib",
2408                     FIXED_ONE_BYTE_STRING(node_isolate, ZLIB_VERSION));
2409
2410   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
2411   READONLY_PROPERTY(versions,
2412                     "modules",
2413                     FIXED_ONE_BYTE_STRING(node_isolate, node_modules_version));
2414
2415 #if HAVE_OPENSSL
2416   // Stupid code to slice out the version string.
2417   int c, l = strlen(OPENSSL_VERSION_TEXT);
2418   for (i = j = 0; i < l; i++) {
2419     c = OPENSSL_VERSION_TEXT[i];
2420     if ('0' <= c && c <= '9') {
2421       for (j = i + 1; j < l; j++) {
2422         c = OPENSSL_VERSION_TEXT[j];
2423         if (c == ' ') break;
2424       }
2425       break;
2426     }
2427   }
2428   READONLY_PROPERTY(
2429       versions,
2430       "openssl",
2431       OneByteString(node_isolate, &OPENSSL_VERSION_TEXT[i], j - i));
2432 #endif
2433
2434
2435
2436   // process.arch
2437   READONLY_PROPERTY(process, "arch", OneByteString(node_isolate, ARCH));
2438
2439   // process.platform
2440   READONLY_PROPERTY(process,
2441                     "platform",
2442                     OneByteString(node_isolate, PLATFORM));
2443
2444   // process.argv
2445   Local<Array> arguments = Array::New(argc - option_end_index + 1);
2446   arguments->Set(0, String::NewFromUtf8(node_isolate, argv[0]));
2447   for (j = 1, i = option_end_index; i < argc; j++, i++) {
2448     arguments->Set(j, String::NewFromUtf8(node_isolate, argv[i]));
2449   }
2450   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "argv"), arguments);
2451
2452   // process.execArgv
2453   Local<Array> exec_argv = Array::New(option_end_index - 1);
2454   for (j = 1, i = 0; j < option_end_index; j++, i++) {
2455     exec_argv->Set(i, String::NewFromUtf8(node_isolate, argv[j]));
2456   }
2457   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execArgv"), exec_argv);
2458
2459   // create process.env
2460   Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
2461   envTemplate->SetNamedPropertyHandler(EnvGetter,
2462                                        EnvSetter,
2463                                        EnvQuery,
2464                                        EnvDeleter,
2465                                        EnvEnumerator,
2466                                        Object::New());
2467   Local<Object> env = envTemplate->NewInstance();
2468   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "env"), env);
2469
2470   READONLY_PROPERTY(process, "pid", Integer::New(getpid(), node_isolate));
2471   READONLY_PROPERTY(process, "features", GetFeatures());
2472   process->SetAccessor(
2473       FIXED_ONE_BYTE_STRING(node_isolate, "_needImmediateCallback"),
2474       NeedImmediateCallbackGetter,
2475       NeedImmediateCallbackSetter);
2476
2477   // -e, --eval
2478   if (eval_string) {
2479     READONLY_PROPERTY(process,
2480                       "_eval",
2481                       String::NewFromUtf8(node_isolate, eval_string));
2482   }
2483
2484   // -p, --print
2485   if (print_eval) {
2486     READONLY_PROPERTY(process, "_print_eval", True(node_isolate));
2487   }
2488
2489   // -i, --interactive
2490   if (force_repl) {
2491     READONLY_PROPERTY(process, "_forceRepl", True(node_isolate));
2492   }
2493
2494   // --no-deprecation
2495   if (no_deprecation) {
2496     READONLY_PROPERTY(process, "noDeprecation", True(node_isolate));
2497   }
2498
2499   // --throw-deprecation
2500   if (throw_deprecation) {
2501     READONLY_PROPERTY(process, "throwDeprecation", True(node_isolate));
2502   }
2503
2504   // --trace-deprecation
2505   if (trace_deprecation) {
2506     READONLY_PROPERTY(process, "traceDeprecation", True(node_isolate));
2507   }
2508
2509   size_t exec_path_len = 2 * PATH_MAX;
2510   char* exec_path = new char[exec_path_len];
2511   Local<String> exec_path_value;
2512   if (uv_exepath(exec_path, &exec_path_len) == 0) {
2513     exec_path_value = String::NewFromUtf8(node_isolate,
2514                                           exec_path,
2515                                           String::kNormalString,
2516                                           exec_path_len);
2517   } else {
2518     exec_path_value = String::NewFromUtf8(node_isolate, argv[0]);
2519   }
2520   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execPath"),
2521                exec_path_value);
2522   delete[] exec_path;
2523
2524   process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "debugPort"),
2525                        DebugPortGetter,
2526                        DebugPortSetter);
2527
2528   // define various internal methods
2529   NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests);
2530   NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles);
2531   NODE_SET_METHOD(process, "reallyExit", Exit);
2532   NODE_SET_METHOD(process, "abort", Abort);
2533   NODE_SET_METHOD(process, "chdir", Chdir);
2534   NODE_SET_METHOD(process, "cwd", Cwd);
2535
2536   NODE_SET_METHOD(process, "umask", Umask);
2537
2538 #if defined(__POSIX__) && !defined(__ANDROID__)
2539   NODE_SET_METHOD(process, "getuid", GetUid);
2540   NODE_SET_METHOD(process, "setuid", SetUid);
2541
2542   NODE_SET_METHOD(process, "setgid", SetGid);
2543   NODE_SET_METHOD(process, "getgid", GetGid);
2544
2545   NODE_SET_METHOD(process, "getgroups", GetGroups);
2546   NODE_SET_METHOD(process, "setgroups", SetGroups);
2547   NODE_SET_METHOD(process, "initgroups", InitGroups);
2548 #endif  // __POSIX__ && !defined(__ANDROID__)
2549
2550   NODE_SET_METHOD(process, "_kill", Kill);
2551
2552   NODE_SET_METHOD(process, "_debugProcess", DebugProcess);
2553   NODE_SET_METHOD(process, "_debugPause", DebugPause);
2554   NODE_SET_METHOD(process, "_debugEnd", DebugEnd);
2555
2556   NODE_SET_METHOD(process, "hrtime", Hrtime);
2557
2558   NODE_SET_METHOD(process, "dlopen", DLOpen);
2559
2560   NODE_SET_METHOD(process, "uptime", Uptime);
2561   NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
2562
2563   NODE_SET_METHOD(process, "binding", Binding);
2564
2565   NODE_SET_METHOD(process, "_setupDomainUse", SetupDomainUse);
2566
2567   // values use to cross communicate with processNextTick
2568   Local<Object> info_box = Object::New();
2569   info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
2570                                                     kExternalUnsignedIntArray,
2571                                                     4);
2572   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickInfoBox"), info_box);
2573
2574   // pre-set _events object for faster emit checks
2575   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_events"), Object::New());
2576
2577   return scope.Close(process);
2578 }
2579
2580
2581 #undef READONLY_PROPERTY
2582
2583
2584 static void AtExit() {
2585   uv_tty_reset_mode();
2586 }
2587
2588
2589 static void SignalExit(int signal) {
2590   uv_tty_reset_mode();
2591   _exit(128 + signal);
2592 }
2593
2594
2595 void Load(Handle<Object> process_l) {
2596   HandleScope handle_scope(node_isolate);
2597
2598   process_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "process");
2599   domain_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "domain");
2600
2601   // Compile, execute the src/node.js file. (Which was included as static C
2602   // string in node_natives.h. 'natve_node' is the string containing that
2603   // source code.)
2604
2605   // The node.js file returns a function 'f'
2606   atexit(AtExit);
2607
2608   TryCatch try_catch;
2609
2610   // Disable verbose mode to stop FatalException() handler from trying
2611   // to handle the exception. Errors this early in the start-up phase
2612   // are not safe to ignore.
2613   try_catch.SetVerbose(false);
2614
2615   Local<String> script_name = FIXED_ONE_BYTE_STRING(node_isolate, "node.js");
2616   Local<Value> f_value = ExecuteString(MainSource(), script_name);
2617   if (try_catch.HasCaught())  {
2618     ReportException(try_catch);
2619     exit(10);
2620   }
2621   assert(f_value->IsFunction());
2622   Local<Function> f = Local<Function>::Cast(f_value);
2623
2624   // Now we call 'f' with the 'process' variable that we've built up with
2625   // all our bindings. Inside node.js we'll take care of assigning things to
2626   // their places.
2627
2628   // We start the process this way in order to be more modular. Developers
2629   // who do not like how 'src/node.js' setups the module system but do like
2630   // Node's I/O bindings may want to replace 'f' with their own function.
2631
2632   // Add a reference to the global object
2633   Local<Object> global = v8::Context::GetCurrent()->Global();
2634
2635 #if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
2636   InitDTrace(global);
2637 #endif
2638
2639 #if defined HAVE_PERFCTR
2640   InitPerfCounters(global);
2641 #endif
2642
2643   // Enable handling of uncaught exceptions
2644   // (FatalException(), break on uncaught exception in debugger)
2645   //
2646   // This is not strictly necessary since it's almost impossible
2647   // to attach the debugger fast enought to break on exception
2648   // thrown during process startup.
2649   try_catch.SetVerbose(true);
2650
2651   Local<Value> arg = process_l;
2652   f->Call(global, 1, &arg);
2653 }
2654
2655 static void PrintHelp();
2656
2657 static void ParseDebugOpt(const char* arg) {
2658   const char *p = 0;
2659
2660   if (strstr(arg, "--debug-port=") == arg) {
2661     p = 1 + strchr(arg, '=');
2662     debug_port = atoi(p);
2663   } else {
2664     use_debug_agent = true;
2665     if (!strcmp(arg, "--debug-brk")) {
2666       debug_wait_connect = true;
2667       return;
2668     } else if (!strcmp(arg, "--debug")) {
2669       return;
2670     } else if (strstr(arg, "--debug-brk=") == arg) {
2671       debug_wait_connect = true;
2672       p = 1 + strchr(arg, '=');
2673       debug_port = atoi(p);
2674     } else if (strstr(arg, "--debug=") == arg) {
2675       p = 1 + strchr(arg, '=');
2676       debug_port = atoi(p);
2677     }
2678   }
2679   if (p && debug_port > 1024 && debug_port <  65536)
2680       return;
2681
2682   fprintf(stderr, "Bad debug option.\n");
2683   if (p) fprintf(stderr, "Debug port must be in range 1025 to 65535.\n");
2684
2685   PrintHelp();
2686   exit(12);
2687 }
2688
2689 static void PrintHelp() {
2690   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
2691          "       node debug script.js [arguments] \n"
2692          "\n"
2693          "Options:\n"
2694          "  -v, --version        print node's version\n"
2695          "  -e, --eval script    evaluate script\n"
2696          "  -p, --print          evaluate script and print result\n"
2697          "  -i, --interactive    always enter the REPL even if stdin\n"
2698          "                       does not appear to be a terminal\n"
2699          "  --no-deprecation     silence deprecation warnings\n"
2700          "  --trace-deprecation  show stack traces on deprecations\n"
2701          "  --v8-options         print v8 command line options\n"
2702          "  --max-stack-size=val set max v8 stack size (bytes)\n"
2703          "\n"
2704          "Environment variables:\n"
2705 #ifdef _WIN32
2706          "NODE_PATH              ';'-separated list of directories\n"
2707 #else
2708          "NODE_PATH              ':'-separated list of directories\n"
2709 #endif
2710          "                       prefixed to the module search path.\n"
2711          "NODE_MODULE_CONTEXTS   Set to 1 to load modules in their own\n"
2712          "                       global contexts.\n"
2713          "NODE_DISABLE_COLORS    Set to 1 to disable colors in the REPL\n"
2714          "\n"
2715          "Documentation can be found at http://nodejs.org/\n");
2716 }
2717
2718
2719 // Parse node command line arguments.
2720 static void ParseArgs(int argc, char **argv) {
2721   int i;
2722
2723   // TODO(bnoordhuis) use parse opts
2724   for (i = 1; i < argc; i++) {
2725     const char *arg = argv[i];
2726     if (strstr(arg, "--debug") == arg) {
2727       ParseDebugOpt(arg);
2728       argv[i] = const_cast<char*>("");
2729     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
2730       printf("%s\n", NODE_VERSION);
2731       exit(0);
2732     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
2733       PrintHelp();
2734       exit(0);
2735     } else if (strcmp(arg, "--eval") == 0   ||
2736                strcmp(arg, "-e") == 0       ||
2737                strcmp(arg, "--print") == 0  ||
2738                strcmp(arg, "-pe") == 0      ||
2739                strcmp(arg, "-p") == 0) {
2740       bool is_eval = strchr(arg, 'e') != NULL;
2741       bool is_print = strchr(arg, 'p') != NULL;
2742
2743       // argument to -p and --print is optional
2744       if (is_eval == true && i + 1 >= argc) {
2745         fprintf(stderr, "Error: %s requires an argument\n", arg);
2746         exit(13);
2747       }
2748
2749       print_eval = print_eval || is_print;
2750       argv[i] = const_cast<char*>("");
2751
2752       // --eval, -e and -pe always require an argument
2753       if (is_eval == true) {
2754         eval_string = argv[++i];
2755         continue;
2756       }
2757
2758       // next arg is the expression to evaluate unless it starts with:
2759       //  - a dash, then it's another switch
2760       //  - "\\-", then it's an escaped expression, drop the backslash
2761       if (argv[i + 1] == NULL) continue;
2762       if (argv[i + 1][0] == '-') continue;
2763       eval_string = argv[++i];
2764       if (strncmp(eval_string, "\\-", 2) == 0) ++eval_string;
2765     } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
2766       force_repl = true;
2767       argv[i] = const_cast<char*>("");
2768     } else if (strcmp(arg, "--v8-options") == 0) {
2769       argv[i] = const_cast<char*>("--help");
2770     } else if (strcmp(arg, "--no-deprecation") == 0) {
2771       argv[i] = const_cast<char*>("");
2772       no_deprecation = true;
2773     } else if (strcmp(arg, "--trace-deprecation") == 0) {
2774       argv[i] = const_cast<char*>("");
2775       trace_deprecation = true;
2776     } else if (strcmp(arg, "--throw-deprecation") == 0) {
2777       argv[i] = const_cast<char*>("");
2778       throw_deprecation = true;
2779     } else if (argv[i][0] != '-') {
2780       break;
2781     }
2782   }
2783
2784   option_end_index = i;
2785 }
2786
2787
2788 // Called from the main thread.
2789 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle, int status) {
2790   v8::Debug::ProcessDebugMessages();
2791 }
2792
2793
2794 // Called from V8 Debug Agent TCP thread.
2795 static void DispatchMessagesDebugAgentCallback() {
2796   uv_async_send(&dispatch_debug_messages_async);
2797 }
2798
2799
2800 // Called from the main thread
2801 static void EmitDebugEnabledAsyncCallback(uv_async_t* handle, int status) {
2802   HandleScope handle_scope(node_isolate);
2803   Local<Object> obj = Object::New();
2804   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "cmd"),
2805            FIXED_ONE_BYTE_STRING(node_isolate, "NODE_DEBUG_ENABLED"));
2806   Local<Value> args[] = {
2807     FIXED_ONE_BYTE_STRING(node_isolate, "internalMessage"),
2808     obj
2809   };
2810   MakeCallback(process_p, "emit", ARRAY_SIZE(args), args);
2811 }
2812
2813
2814 // Called from the signal watcher callback
2815 static void EmitDebugEnabled() {
2816   uv_async_send(&emit_debug_enabled_async);
2817 }
2818
2819
2820 static void EnableDebug(bool wait_connect) {
2821   // If we're called from another thread, make sure to enter the right
2822   // v8 isolate.
2823   node_isolate->Enter();
2824
2825   v8::Debug::SetDebugMessageDispatchHandler(DispatchMessagesDebugAgentCallback,
2826                                             false);
2827
2828   // Start the debug thread and it's associated TCP server on port 5858.
2829   bool r = v8::Debug::EnableAgent("node " NODE_VERSION,
2830                                   debug_port,
2831                                   wait_connect);
2832
2833   // Crappy check that everything went well. FIXME
2834   assert(r);
2835
2836   // Print out some information.
2837   fprintf(stderr, "debugger listening on port %d\n", debug_port);
2838   fflush(stderr);
2839
2840   debugger_running = true;
2841
2842   // Do not emit NODE_DEBUG_ENABLED when debugger is enabled before starting
2843   // the main process (i.e. when called via `node --debug`)
2844   if (!process_p.IsEmpty())
2845     EmitDebugEnabled();
2846
2847   node_isolate->Exit();
2848 }
2849
2850
2851 #ifdef __POSIX__
2852 static void EnableDebugSignalHandler(uv_signal_t* handle, int) {
2853   // Break once process will return execution to v8
2854   v8::Debug::DebugBreak(node_isolate);
2855
2856   if (!debugger_running) {
2857     fprintf(stderr, "Hit SIGUSR1 - starting debugger agent.\n");
2858     EnableDebug(false);
2859   }
2860 }
2861
2862
2863 static void RegisterSignalHandler(int signal, void (*handler)(int signal)) {
2864   struct sigaction sa;
2865
2866   memset(&sa, 0, sizeof(sa));
2867   sa.sa_handler = handler;
2868   sigfillset(&sa.sa_mask);
2869   sigaction(signal, &sa, NULL);
2870 }
2871
2872
2873 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
2874   HandleScope scope(node_isolate);
2875
2876   if (args.Length() != 1) {
2877     return ThrowError("Invalid number of arguments.");
2878   }
2879
2880   pid_t pid;
2881   int r;
2882
2883   pid = args[0]->IntegerValue();
2884   r = kill(pid, SIGUSR1);
2885   if (r != 0) {
2886     return ThrowErrnoException(errno, "kill");
2887   }
2888 }
2889 #endif  // __POSIX__
2890
2891
2892 #ifdef _WIN32
2893 DWORD WINAPI EnableDebugThreadProc(void* arg) {
2894   // Break once process will return execution to v8
2895   if (!debugger_running) {
2896     for (int i = 0; i < 1; i++) {
2897       fprintf(stderr, "Starting debugger agent.\r\n");
2898       fflush(stderr);
2899       EnableDebug(false);
2900     }
2901   }
2902
2903   v8::Debug::DebugBreak(node_isolate);
2904
2905   return 0;
2906 }
2907
2908
2909 static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
2910     size_t buf_len) {
2911   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
2912 }
2913
2914
2915 static int RegisterDebugSignalHandler() {
2916   wchar_t mapping_name[32];
2917   HANDLE mapping_handle;
2918   DWORD pid;
2919   LPTHREAD_START_ROUTINE* handler;
2920
2921   pid = GetCurrentProcessId();
2922
2923   if (GetDebugSignalHandlerMappingName(pid,
2924                                        mapping_name,
2925                                        ARRAY_SIZE(mapping_name)) < 0) {
2926     return -1;
2927   }
2928
2929   mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
2930                                       NULL,
2931                                       PAGE_READWRITE,
2932                                       0,
2933                                       sizeof *handler,
2934                                       mapping_name);
2935   if (mapping_handle == NULL) {
2936     return -1;
2937   }
2938
2939   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
2940       MapViewOfFile(mapping_handle,
2941                     FILE_MAP_ALL_ACCESS,
2942                     0,
2943                     0,
2944                     sizeof *handler));
2945   if (handler == NULL) {
2946     CloseHandle(mapping_handle);
2947     return -1;
2948   }
2949
2950   *handler = EnableDebugThreadProc;
2951
2952   UnmapViewOfFile(static_cast<void*>(handler));
2953
2954   return 0;
2955 }
2956
2957
2958 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
2959   HandleScope scope(node_isolate);
2960   DWORD pid;
2961   HANDLE process = NULL;
2962   HANDLE thread = NULL;
2963   HANDLE mapping = NULL;
2964   wchar_t mapping_name[32];
2965   LPTHREAD_START_ROUTINE* handler = NULL;
2966
2967   if (args.Length() != 1) {
2968     ThrowError("Invalid number of arguments.");
2969     goto out;
2970   }
2971
2972   pid = (DWORD) args[0]->IntegerValue();
2973
2974   process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
2975                             PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
2976                             PROCESS_VM_READ,
2977                         FALSE,
2978                         pid);
2979   if (process == NULL) {
2980     ThrowException(WinapiErrnoException(GetLastError(), "OpenProcess"));
2981     goto out;
2982   }
2983
2984   if (GetDebugSignalHandlerMappingName(pid,
2985                                        mapping_name,
2986                                        ARRAY_SIZE(mapping_name)) < 0) {
2987     ThrowErrnoException(errno, "sprintf");
2988     goto out;
2989   }
2990
2991   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
2992   if (mapping == NULL) {
2993     ThrowException(WinapiErrnoException(GetLastError(), "OpenFileMappingW"));
2994     goto out;
2995   }
2996
2997   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
2998       MapViewOfFile(mapping,
2999                     FILE_MAP_READ,
3000                     0,
3001                     0,
3002                     sizeof *handler));
3003   if (handler == NULL || *handler == NULL) {
3004     ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile"));
3005     goto out;
3006   }
3007
3008   thread = CreateRemoteThread(process,
3009                               NULL,
3010                               0,
3011                               *handler,
3012                               NULL,
3013                               0,
3014                               NULL);
3015   if (thread == NULL) {
3016     ThrowException(WinapiErrnoException(GetLastError(), "CreateRemoteThread"));
3017     goto out;
3018   }
3019
3020   // Wait for the thread to terminate
3021   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
3022     ThrowException(WinapiErrnoException(GetLastError(), "WaitForSingleObject"));
3023     goto out;
3024   }
3025
3026  out:
3027   if (process != NULL)
3028     CloseHandle(process);
3029   if (thread != NULL)
3030     CloseHandle(thread);
3031   if (handler != NULL)
3032     UnmapViewOfFile(handler);
3033   if (mapping != NULL)
3034     CloseHandle(mapping);
3035 }
3036 #endif  // _WIN32
3037
3038
3039 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
3040   v8::Debug::DebugBreak(node_isolate);
3041 }
3042
3043
3044 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
3045   if (debugger_running) {
3046     v8::Debug::DisableAgent();
3047     debugger_running = false;
3048   }
3049 }
3050
3051
3052 char** Init(int argc, char *argv[]) {
3053   // Initialize prog_start_time to get relative uptime.
3054   uv_uptime(&prog_start_time);
3055
3056   // Make inherited handles noninheritable.
3057   uv_disable_stdio_inheritance();
3058
3059   // init async debug messages dispatching
3060   uv_async_init(uv_default_loop(),
3061                 &dispatch_debug_messages_async,
3062                 DispatchDebugMessagesAsyncCallback);
3063   uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
3064
3065   // init async NODE_DEBUG_ENABLED emitter
3066   uv_async_init(uv_default_loop(),
3067                 &emit_debug_enabled_async,
3068                 EmitDebugEnabledAsyncCallback);
3069   uv_unref(reinterpret_cast<uv_handle_t*>(&emit_debug_enabled_async));
3070
3071   // Parse a few arguments which are specific to Node.
3072   node::ParseArgs(argc, argv);
3073   // Parse the rest of the args (up to the 'option_end_index' (where '--' was
3074   // in the command line))
3075   int v8argc = option_end_index;
3076   char **v8argv = argv;
3077
3078   if (debug_wait_connect) {
3079     // v8argv is a copy of argv up to the script file argument +2 if --debug-brk
3080     // to expose the v8 debugger js object so that node.js can set
3081     // a breakpoint on the first line of the startup script
3082     v8argc += 2;
3083     v8argv = new char*[v8argc];
3084     memcpy(v8argv, argv, sizeof(*argv) * option_end_index);
3085     v8argv[option_end_index] = const_cast<char*>("--expose_debug_as");
3086     v8argv[option_end_index + 1] = const_cast<char*>("v8debug");
3087   }
3088
3089   V8::SetFlagsFromCommandLine(&v8argc, v8argv, false);
3090
3091   const char typed_arrays_flag[] = "--harmony_typed_arrays";
3092   V8::SetFlagsFromString(typed_arrays_flag, sizeof(typed_arrays_flag) - 1);
3093   V8::SetArrayBufferAllocator(&ArrayBufferAllocator::the_singleton);
3094
3095   // Fetch a reference to the main isolate, so we have a reference to it
3096   // even when we need it to access it from another (debugger) thread.
3097   node_isolate = Isolate::GetCurrent();
3098
3099 #ifdef __POSIX__
3100   // Ignore SIGPIPE
3101   RegisterSignalHandler(SIGPIPE, SIG_IGN);
3102   RegisterSignalHandler(SIGINT, SignalExit);
3103   RegisterSignalHandler(SIGTERM, SignalExit);
3104 #endif  // __POSIX__
3105
3106   uv_check_init(uv_default_loop(), &check_immediate_watcher);
3107   uv_unref(reinterpret_cast<uv_handle_t*>(&check_immediate_watcher));
3108   uv_idle_init(uv_default_loop(), &idle_immediate_dummy);
3109
3110   V8::SetFatalErrorHandler(node::OnFatalError);
3111   V8::AddMessageListener(OnMessage);
3112
3113   // If the --debug flag was specified then initialize the debug thread.
3114   if (use_debug_agent) {
3115     EnableDebug(debug_wait_connect);
3116   } else {
3117 #ifdef _WIN32
3118     RegisterDebugSignalHandler();
3119 #else  // Posix
3120     static uv_signal_t signal_watcher;
3121     uv_signal_init(uv_default_loop(), &signal_watcher);
3122     uv_signal_start(&signal_watcher, EnableDebugSignalHandler, SIGUSR1);
3123     uv_unref(reinterpret_cast<uv_handle_t*>(&signal_watcher));
3124 #endif  // __POSIX__
3125   }
3126
3127   return argv;
3128 }
3129
3130
3131 struct AtExitCallback {
3132   AtExitCallback* next_;
3133   void (*cb_)(void* arg);
3134   void* arg_;
3135 };
3136
3137 static AtExitCallback* at_exit_functions_;
3138
3139
3140 void RunAtExit() {
3141   AtExitCallback* p = at_exit_functions_;
3142   at_exit_functions_ = NULL;
3143
3144   while (p) {
3145     AtExitCallback* q = p->next_;
3146     p->cb_(p->arg_);
3147     delete p;
3148     p = q;
3149   }
3150 }
3151
3152
3153 void AtExit(void (*cb)(void* arg), void* arg) {
3154   AtExitCallback* p = new AtExitCallback;
3155   p->cb_ = cb;
3156   p->arg_ = arg;
3157   p->next_ = at_exit_functions_;
3158   at_exit_functions_ = p;
3159 }
3160
3161
3162 void EmitExit(v8::Handle<v8::Object> process_l) {
3163   // process.emit('exit')
3164   process_l->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_exiting"),
3165                  True(node_isolate));
3166   Local<Value> args[] = {
3167     FIXED_ONE_BYTE_STRING(node_isolate, "exit"),
3168     Integer::New(0, node_isolate)
3169   };
3170   MakeCallback(process_l, "emit", ARRAY_SIZE(args), args);
3171 }
3172
3173 static char **copy_argv(int argc, char **argv) {
3174   size_t strlen_sum;
3175   char **argv_copy;
3176   char *argv_data;
3177   size_t len;
3178   int i;
3179
3180   strlen_sum = 0;
3181   for (i = 0; i < argc; i++) {
3182     strlen_sum += strlen(argv[i]) + 1;
3183   }
3184
3185   argv_copy = static_cast<char**>(
3186       malloc(sizeof(*argv_copy) * (argc + 1) + strlen_sum));
3187   if (!argv_copy) {
3188     return NULL;
3189   }
3190
3191   argv_data = reinterpret_cast<char*>(argv_copy) +
3192               sizeof(*argv_copy) * (argc + 1);
3193
3194   for (i = 0; i < argc; i++) {
3195     argv_copy[i] = argv_data;
3196     len = strlen(argv[i]) + 1;
3197     memcpy(argv_data, argv[i], len);
3198     argv_data += len;
3199   }
3200
3201   argv_copy[argc] = NULL;
3202
3203   return argv_copy;
3204 }
3205
3206 int Start(int argc, char *argv[]) {
3207   // Hack aroung with the argv pointer. Used for process.title = "blah".
3208   argv = uv_setup_args(argc, argv);
3209
3210   // Logic to duplicate argv as Init() modifies arguments
3211   // that are passed into it.
3212   char **argv_copy = copy_argv(argc, argv);
3213
3214   // This needs to run *before* V8::Initialize()
3215   // Use copy here as to not modify the original argv:
3216   Init(argc, argv_copy);
3217
3218   V8::Initialize();
3219   {
3220     Locker locker(node_isolate);
3221     HandleScope handle_scope(node_isolate);
3222
3223     // Create the one and only Context.
3224     Local<Context> context = Context::New(node_isolate);
3225     Context::Scope context_scope(context);
3226
3227     binding_cache.Reset(node_isolate, Object::New());
3228
3229     // Use original argv, as we're just copying values out of it.
3230     Local<Object> process_l = SetupProcessObject(argc, argv);
3231
3232     // Create all the objects, load modules, do everything.
3233     // so your next reading stop should be node::Load()!
3234     Load(process_l);
3235
3236     // All our arguments are loaded. We've evaluated all of the scripts. We
3237     // might even have created TCP servers. Now we enter the main eventloop. If
3238     // there are no watchers on the loop (except for the ones that were
3239     // uv_unref'd) then this function exits. As long as there are active
3240     // watchers, it blocks.
3241     process_state = RUNNING;
3242     uv_run(uv_default_loop(), UV_RUN_DEFAULT);
3243
3244     EmitExit(process_l);
3245     RunAtExit();
3246   }
3247
3248   DisposeEventLoop(uv_default_loop());
3249   V8::Dispose();
3250
3251   // Clean up the copy:
3252   free(argv_copy);
3253
3254   return 0;
3255 }
3256
3257
3258 }  // namespace node