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