src: fix solaris 10 build error
[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   // uid_t is an uint32_t on all supported platforms.
1553   args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
1554 }
1555
1556
1557 static void GetGid(const FunctionCallbackInfo<Value>& args) {
1558   // gid_t is an uint32_t on all supported platforms.
1559   args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
1560 }
1561
1562
1563 static void SetGid(const FunctionCallbackInfo<Value>& args) {
1564   HandleScope scope(node_isolate);
1565
1566   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1567     return ThrowTypeError("setgid argument must be a number or a string");
1568   }
1569
1570   gid_t gid = gid_by_name(args[0]);
1571
1572   if (gid == gid_not_found) {
1573     return ThrowError("setgid group id does not exist");
1574   }
1575
1576   if (setgid(gid)) {
1577     return ThrowErrnoException(errno, "setgid");
1578   }
1579 }
1580
1581
1582 static void SetUid(const FunctionCallbackInfo<Value>& args) {
1583   HandleScope scope(node_isolate);
1584
1585   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1586     return ThrowTypeError("setuid argument must be a number or a string");
1587   }
1588
1589   uid_t uid = uid_by_name(args[0]);
1590
1591   if (uid == uid_not_found) {
1592     return ThrowError("setuid user id does not exist");
1593   }
1594
1595   if (setuid(uid)) {
1596     return ThrowErrnoException(errno, "setuid");
1597   }
1598 }
1599
1600
1601 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
1602   HandleScope scope(node_isolate);
1603
1604   int ngroups = getgroups(0, NULL);
1605
1606   if (ngroups == -1) {
1607     return ThrowErrnoException(errno, "getgroups");
1608   }
1609
1610   gid_t* groups = new gid_t[ngroups];
1611
1612   ngroups = getgroups(ngroups, groups);
1613
1614   if (ngroups == -1) {
1615     delete[] groups;
1616     return ThrowErrnoException(errno, "getgroups");
1617   }
1618
1619   Local<Array> groups_list = Array::New(ngroups);
1620   bool seen_egid = false;
1621   gid_t egid = getegid();
1622
1623   for (int i = 0; i < ngroups; i++) {
1624     groups_list->Set(i, Integer::New(groups[i], node_isolate));
1625     if (groups[i] == egid) seen_egid = true;
1626   }
1627
1628   delete[] groups;
1629
1630   if (seen_egid == false) {
1631     groups_list->Set(ngroups, Integer::New(egid, node_isolate));
1632   }
1633
1634   args.GetReturnValue().Set(groups_list);
1635 }
1636
1637
1638 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
1639   HandleScope scope(node_isolate);
1640
1641   if (!args[0]->IsArray()) {
1642     return ThrowTypeError("argument 1 must be an array");
1643   }
1644
1645   Local<Array> groups_list = args[0].As<Array>();
1646   size_t size = groups_list->Length();
1647   gid_t* groups = new gid_t[size];
1648
1649   for (size_t i = 0; i < size; i++) {
1650     gid_t gid = gid_by_name(groups_list->Get(i));
1651
1652     if (gid == gid_not_found) {
1653       delete[] groups;
1654       return ThrowError("group name not found");
1655     }
1656
1657     groups[i] = gid;
1658   }
1659
1660   int rc = setgroups(size, groups);
1661   delete[] groups;
1662
1663   if (rc == -1) {
1664     return ThrowErrnoException(errno, "setgroups");
1665   }
1666 }
1667
1668
1669 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
1670   HandleScope scope(node_isolate);
1671
1672   if (!args[0]->IsUint32() && !args[0]->IsString()) {
1673     return ThrowTypeError("argument 1 must be a number or a string");
1674   }
1675
1676   if (!args[1]->IsUint32() && !args[1]->IsString()) {
1677     return ThrowTypeError("argument 2 must be a number or a string");
1678   }
1679
1680   String::Utf8Value arg0(args[0]);
1681   gid_t extra_group;
1682   bool must_free;
1683   char* user;
1684
1685   if (args[0]->IsUint32()) {
1686     user = name_by_uid(args[0]->Uint32Value());
1687     must_free = true;
1688   } else {
1689     user = *arg0;
1690     must_free = false;
1691   }
1692
1693   if (user == NULL) {
1694     return ThrowError("initgroups user not found");
1695   }
1696
1697   extra_group = gid_by_name(args[1]);
1698
1699   if (extra_group == gid_not_found) {
1700     if (must_free) free(user);
1701     return ThrowError("initgroups extra group not found");
1702   }
1703
1704   int rc = initgroups(user, extra_group);
1705
1706   if (must_free) {
1707     free(user);
1708   }
1709
1710   if (rc) {
1711     return ThrowErrnoException(errno, "initgroups");
1712   }
1713 }
1714
1715 #endif  // __POSIX__ && !defined(__ANDROID__)
1716
1717
1718 void Exit(const FunctionCallbackInfo<Value>& args) {
1719   HandleScope scope(node_isolate);
1720   exit(args[0]->IntegerValue());
1721 }
1722
1723
1724 static void Uptime(const FunctionCallbackInfo<Value>& args) {
1725   HandleScope scope(node_isolate);
1726   double uptime;
1727   if (uv_uptime(&uptime)) return;
1728   args.GetReturnValue().Set(uptime - prog_start_time);
1729 }
1730
1731
1732 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
1733   HandleScope scope(node_isolate);
1734
1735   size_t rss;
1736
1737   int err = uv_resident_set_memory(&rss);
1738   if (err) {
1739     return ThrowUVException(err, "uv_resident_set_memory");
1740   }
1741
1742   Local<Object> info = Object::New();
1743
1744   if (rss_symbol.IsEmpty()) {
1745     rss_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "rss");
1746     heap_total_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "heapTotal");
1747     heap_used_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "heapUsed");
1748   }
1749
1750   info->Set(rss_symbol, Number::New(rss));
1751
1752   // V8 memory usage
1753   HeapStatistics v8_heap_stats;
1754   node_isolate->GetHeapStatistics(&v8_heap_stats);
1755   info->Set(heap_total_symbol,
1756             Integer::NewFromUnsigned(v8_heap_stats.total_heap_size(),
1757                                      node_isolate));
1758   info->Set(heap_used_symbol,
1759             Integer::NewFromUnsigned(v8_heap_stats.used_heap_size(),
1760                                      node_isolate));
1761
1762   args.GetReturnValue().Set(info);
1763 }
1764
1765
1766 void Kill(const FunctionCallbackInfo<Value>& args) {
1767   HandleScope scope(node_isolate);
1768
1769   if (args.Length() != 2) {
1770     return ThrowError("Bad argument.");
1771   }
1772
1773   int pid = args[0]->IntegerValue();
1774   int sig = args[1]->Int32Value();
1775   int err = uv_kill(pid, sig);
1776   args.GetReturnValue().Set(err);
1777 }
1778
1779 // used in Hrtime() below
1780 #define NANOS_PER_SEC 1000000000
1781
1782 // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
1783 // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
1784 // so this function instead returns an Array with 2 entries representing seconds
1785 // and nanoseconds, to avoid any integer overflow possibility.
1786 // Pass in an Array from a previous hrtime() call to instead get a time diff.
1787 void Hrtime(const FunctionCallbackInfo<Value>& args) {
1788   HandleScope scope(node_isolate);
1789
1790   uint64_t t = uv_hrtime();
1791
1792   if (args.Length() > 0) {
1793     // return a time diff tuple
1794     if (!args[0]->IsArray()) {
1795       return ThrowTypeError("process.hrtime() only accepts an Array tuple.");
1796     }
1797     Local<Array> inArray = Local<Array>::Cast(args[0]);
1798     uint64_t seconds = inArray->Get(0)->Uint32Value();
1799     uint64_t nanos = inArray->Get(1)->Uint32Value();
1800     t -= (seconds * NANOS_PER_SEC) + nanos;
1801   }
1802
1803   Local<Array> tuple = Array::New(2);
1804   tuple->Set(0, Integer::NewFromUnsigned(t / NANOS_PER_SEC, node_isolate));
1805   tuple->Set(1, Integer::NewFromUnsigned(t % NANOS_PER_SEC, node_isolate));
1806   args.GetReturnValue().Set(tuple);
1807 }
1808
1809
1810 typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
1811
1812 // DLOpen is process.dlopen(module, filename).
1813 // Used to load 'module.node' dynamically shared objects.
1814 void DLOpen(const FunctionCallbackInfo<Value>& args) {
1815   HandleScope scope(node_isolate);
1816   char symbol[1024], *base, *pos;
1817   uv_lib_t lib;
1818   int r;
1819
1820   if (args.Length() < 2) {
1821     return ThrowError("process.dlopen takes exactly 2 arguments.");
1822   }
1823
1824   Local<Object> module = args[0]->ToObject();  // Cast
1825   String::Utf8Value filename(args[1]);  // Cast
1826
1827   if (exports_symbol.IsEmpty()) {
1828     exports_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "exports");
1829   }
1830   Local<Object> exports = module->Get(exports_symbol)->ToObject();
1831
1832   if (uv_dlopen(*filename, &lib)) {
1833     Local<String> errmsg = OneByteString(node_isolate, uv_dlerror(&lib));
1834 #ifdef _WIN32
1835     // Windows needs to add the filename into the error message
1836     errmsg = String::Concat(errmsg, args[1]->ToString());
1837 #endif  // _WIN32
1838     ThrowException(Exception::Error(errmsg));
1839     return;
1840   }
1841
1842   String::Utf8Value path(args[1]);
1843   base = *path;
1844
1845   /* Find the shared library filename within the full path. */
1846 #ifdef __POSIX__
1847   pos = strrchr(base, '/');
1848   if (pos != NULL) {
1849     base = pos + 1;
1850   }
1851 #else  // Windows
1852   for (;;) {
1853     pos = strpbrk(base, "\\/:");
1854     if (pos == NULL) {
1855       break;
1856     }
1857     base = pos + 1;
1858   }
1859 #endif  // __POSIX__
1860
1861   /* Strip the .node extension. */
1862   pos = strrchr(base, '.');
1863   if (pos != NULL) {
1864     *pos = '\0';
1865   }
1866
1867   /* Add the `_module` suffix to the extension name. */
1868   r = snprintf(symbol, sizeof symbol, "%s_module", base);
1869   if (r <= 0 || static_cast<size_t>(r) >= sizeof symbol) {
1870     return ThrowError("Out of memory.");
1871   }
1872
1873   /* Replace dashes with underscores. When loading foo-bar.node,
1874    * look for foo_bar_module, not foo-bar_module.
1875    */
1876   for (pos = symbol; *pos != '\0'; ++pos) {
1877     if (*pos == '-') *pos = '_';
1878   }
1879
1880   node_module_struct *mod;
1881   if (uv_dlsym(&lib, symbol, reinterpret_cast<void**>(&mod))) {
1882     char errmsg[1024];
1883     snprintf(errmsg, sizeof(errmsg), "Symbol %s not found.", symbol);
1884     return ThrowError(errmsg);
1885   }
1886
1887   if (mod->version != NODE_MODULE_VERSION) {
1888     char errmsg[1024];
1889     snprintf(errmsg,
1890              sizeof(errmsg),
1891              "Module version mismatch. Expected %d, got %d.",
1892              NODE_MODULE_VERSION, mod->version);
1893     return ThrowError(errmsg);
1894   }
1895
1896   // Execute the C++ module
1897   mod->register_func(exports, module);
1898
1899   // Tell coverity that 'handle' should not be freed when we return.
1900   // coverity[leaked_storage]
1901 }
1902
1903
1904 static void OnFatalError(const char* location, const char* message) {
1905   if (location) {
1906     fprintf(stderr, "FATAL ERROR: %s %s\n", location, message);
1907   } else {
1908     fprintf(stderr, "FATAL ERROR: %s\n", message);
1909   }
1910   fflush(stderr);
1911 #if defined(DEBUG)
1912   abort();
1913 #endif
1914   exit(5);
1915 }
1916
1917
1918 NO_RETURN void FatalError(const char* location, const char* message) {
1919   OnFatalError(location, message);
1920   // to supress compiler warning
1921   abort();
1922 }
1923
1924
1925 void FatalException(Handle<Value> error, Handle<Message> message) {
1926   HandleScope scope(node_isolate);
1927
1928   if (fatal_exception_symbol.IsEmpty()) {
1929     fatal_exception_symbol =
1930         FIXED_ONE_BYTE_STRING(node_isolate, "_fatalException");
1931   }
1932
1933   Local<Object> process = PersistentToLocal(node_isolate, process_p);
1934   Local<Value> fatal_v = process->Get(fatal_exception_symbol);
1935
1936   if (!fatal_v->IsFunction()) {
1937     // failed before the process._fatalException function was added!
1938     // this is probably pretty bad.  Nothing to do but report and exit.
1939     ReportException(error, message);
1940     exit(6);
1941   }
1942
1943   Local<Function> fatal_f = Local<Function>::Cast(fatal_v);
1944
1945   TryCatch fatal_try_catch;
1946
1947   // Do not call FatalException when _fatalException handler throws
1948   fatal_try_catch.SetVerbose(false);
1949
1950   // this will return true if the JS layer handled it, false otherwise
1951   Local<Value> caught = fatal_f->Call(process, 1, &error);
1952
1953   if (fatal_try_catch.HasCaught()) {
1954     // the fatal exception function threw, so we must exit
1955     ReportException(fatal_try_catch);
1956     exit(7);
1957   }
1958
1959   if (false == caught->BooleanValue()) {
1960     ReportException(error, message);
1961     exit(8);
1962   }
1963 }
1964
1965
1966 void FatalException(const TryCatch& try_catch) {
1967   HandleScope scope(node_isolate);
1968   // TODO(bajtos) do not call FatalException if try_catch is verbose
1969   // (requires V8 API to expose getter for try_catch.is_verbose_)
1970   FatalException(try_catch.Exception(), try_catch.Message());
1971 }
1972
1973
1974 void OnMessage(Handle<Message> message, Handle<Value> error) {
1975   // The current version of V8 sends messages for errors only
1976   // (thus `error` is always set).
1977   FatalException(error, message);
1978 }
1979
1980
1981 static void Binding(const FunctionCallbackInfo<Value>& args) {
1982   HandleScope scope(node_isolate);
1983
1984   Local<String> module = args[0]->ToString();
1985   String::Utf8Value module_v(module);
1986   node_module_struct* modp;
1987
1988   Local<Object> cache = PersistentToLocal(node_isolate, binding_cache);
1989   Local<Object> exports;
1990
1991   if (cache->Has(module)) {
1992     exports = cache->Get(module)->ToObject();
1993     args.GetReturnValue().Set(exports);
1994     return;
1995   }
1996
1997   // Append a string to process.moduleLoadList
1998   char buf[1024];
1999   snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2000
2001   Local<Array> modules = PersistentToLocal(node_isolate, module_load_list);
2002   uint32_t l = modules->Length();
2003   modules->Set(l, OneByteString(node_isolate, buf));
2004
2005   if ((modp = get_builtin_module(*module_v)) != NULL) {
2006     exports = Object::New();
2007     // Internal bindings don't have a "module" object,
2008     // only exports.
2009     modp->register_func(exports, Undefined(node_isolate));
2010     cache->Set(module, exports);
2011   } else if (!strcmp(*module_v, "constants")) {
2012     exports = Object::New();
2013     DefineConstants(exports);
2014     cache->Set(module, exports);
2015   } else if (!strcmp(*module_v, "natives")) {
2016     exports = Object::New();
2017     DefineJavaScript(exports);
2018     cache->Set(module, exports);
2019   } else {
2020     return ThrowError("No such module");
2021   }
2022
2023   args.GetReturnValue().Set(exports);
2024 }
2025
2026
2027 static void ProcessTitleGetter(Local<String> property,
2028                                const PropertyCallbackInfo<Value>& info) {
2029   HandleScope scope(node_isolate);
2030   char buffer[512];
2031   uv_get_process_title(buffer, sizeof(buffer));
2032   info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, buffer));
2033 }
2034
2035
2036 static void ProcessTitleSetter(Local<String> property,
2037                                Local<Value> value,
2038                                const PropertyCallbackInfo<void>& info) {
2039   HandleScope scope(node_isolate);
2040   String::Utf8Value title(value);
2041   // TODO(piscisaureus): protect with a lock
2042   uv_set_process_title(*title);
2043 }
2044
2045
2046 static void EnvGetter(Local<String> property,
2047                       const PropertyCallbackInfo<Value>& info) {
2048   HandleScope scope(node_isolate);
2049 #ifdef __POSIX__
2050   String::Utf8Value key(property);
2051   const char* val = getenv(*key);
2052   if (val) {
2053     return info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, val));
2054   }
2055 #else  // _WIN32
2056   String::Value key(property);
2057   WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2058   DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2059                                          buffer,
2060                                          ARRAY_SIZE(buffer));
2061   // If result >= sizeof buffer the buffer was too small. That should never
2062   // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2063   // not found.
2064   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2065       result < ARRAY_SIZE(buffer)) {
2066     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2067     Local<String> rc = String::NewFromTwoByte(node_isolate, two_byte_buffer);
2068     return info.GetReturnValue().Set(rc);
2069   }
2070 #endif
2071   // Not found.  Fetch from prototype.
2072   info.GetReturnValue().Set(
2073       info.Data().As<Object>()->Get(property));
2074 }
2075
2076
2077 static void EnvSetter(Local<String> property,
2078                       Local<Value> value,
2079                       const PropertyCallbackInfo<Value>& info) {
2080   HandleScope scope(node_isolate);
2081 #ifdef __POSIX__
2082   String::Utf8Value key(property);
2083   String::Utf8Value val(value);
2084   setenv(*key, *val, 1);
2085 #else  // _WIN32
2086   String::Value key(property);
2087   String::Value val(value);
2088   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2089   // Environment variables that start with '=' are read-only.
2090   if (key_ptr[0] != L'=') {
2091     SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2092   }
2093 #endif
2094   // Whether it worked or not, always return rval.
2095   info.GetReturnValue().Set(value);
2096 }
2097
2098
2099 static void EnvQuery(Local<String> property,
2100                      const PropertyCallbackInfo<Integer>& info) {
2101   HandleScope scope(node_isolate);
2102   int32_t rc = -1;  // Not found unless proven otherwise.
2103 #ifdef __POSIX__
2104   String::Utf8Value key(property);
2105   if (getenv(*key)) rc = 0;
2106 #else  // _WIN32
2107   String::Value key(property);
2108   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2109   if (GetEnvironmentVariableW(key_ptr, NULL, 0) > 0 ||
2110       GetLastError() == ERROR_SUCCESS) {
2111     rc = 0;
2112     if (key_ptr[0] == L'=') {
2113       // Environment variables that start with '=' are hidden and read-only.
2114       rc = static_cast<int32_t>(v8::ReadOnly) |
2115            static_cast<int32_t>(v8::DontDelete) |
2116            static_cast<int32_t>(v8::DontEnum);
2117     }
2118   }
2119 #endif
2120   if (rc != -1) info.GetReturnValue().Set(rc);
2121 }
2122
2123
2124 static void EnvDeleter(Local<String> property,
2125                        const PropertyCallbackInfo<Boolean>& info) {
2126   HandleScope scope(node_isolate);
2127   bool rc = true;
2128 #ifdef __POSIX__
2129   String::Utf8Value key(property);
2130   rc = getenv(*key) != NULL;
2131   if (rc) unsetenv(*key);
2132 #else
2133   String::Value key(property);
2134   WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2135   if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, NULL)) {
2136     // Deletion failed. Return true if the key wasn't there in the first place,
2137     // false if it is still there.
2138     rc = GetEnvironmentVariableW(key_ptr, NULL, NULL) == 0 &&
2139          GetLastError() != ERROR_SUCCESS;
2140   }
2141 #endif
2142   info.GetReturnValue().Set(rc);
2143 }
2144
2145
2146 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2147   HandleScope scope(node_isolate);
2148 #ifdef __POSIX__
2149   int size = 0;
2150   while (environ[size]) size++;
2151
2152   Local<Array> env = Array::New(size);
2153
2154   for (int i = 0; i < size; ++i) {
2155     const char* var = environ[i];
2156     const char* s = strchr(var, '=');
2157     const int length = s ? s - var : strlen(var);
2158     Local<String> name = String::NewFromUtf8(node_isolate,
2159                                              var,
2160                                              String::kNormalString,
2161                                              length);
2162     env->Set(i, name);
2163   }
2164 #else  // _WIN32
2165   WCHAR* environment = GetEnvironmentStringsW();
2166   if (environment == NULL) return;  // This should not happen.
2167   Local<Array> env = Array::New();
2168   WCHAR* p = environment;
2169   int i = 0;
2170   while (*p != NULL) {
2171     WCHAR *s;
2172     if (*p == L'=') {
2173       // If the key starts with '=' it is a hidden environment variable.
2174       p += wcslen(p) + 1;
2175       continue;
2176     } else {
2177       s = wcschr(p, L'=');
2178     }
2179     if (!s) {
2180       s = p + wcslen(p);
2181     }
2182     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2183     const size_t two_byte_buffer_len = s - p;
2184     Local<String> value = String::NewFromTwoByte(node_isolate,
2185                                                  two_byte_buffer,
2186                                                  String::kNormalString,
2187                                                  two_byte_buffer_len);
2188     env->Set(i++, value);
2189     p = s + wcslen(s) + 1;
2190   }
2191   FreeEnvironmentStringsW(environment);
2192 #endif
2193
2194   info.GetReturnValue().Set(env);
2195 }
2196
2197
2198 static Handle<Object> GetFeatures() {
2199   HandleScope scope(node_isolate);
2200
2201   Local<Object> obj = Object::New();
2202 #if defined(DEBUG) && DEBUG
2203   Local<Value> debug = True(node_isolate);
2204 #else
2205   Local<Value> debug = False(node_isolate);
2206 #endif  // defined(DEBUG) && DEBUG
2207
2208   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "debug"), debug);
2209
2210   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "uv"), True(node_isolate));
2211   // TODO(bnoordhuis) ping libuv
2212   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ipv6"), True(node_isolate));
2213
2214 #ifdef OPENSSL_NPN_NEGOTIATED
2215   Local<Boolean> tls_npn = True(node_isolate);
2216 #else
2217   Local<Boolean> tls_npn = False(node_isolate);
2218 #endif
2219   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_npn"), tls_npn);
2220
2221 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2222   Local<Boolean> tls_sni = True(node_isolate);
2223 #else
2224   Local<Boolean> tls_sni = False(node_isolate);
2225 #endif
2226   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_sni"), tls_sni);
2227
2228   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls"),
2229            Boolean::New(get_builtin_module("crypto") != NULL));
2230
2231   return scope.Close(obj);
2232 }
2233
2234
2235 static void DebugPortGetter(Local<String> property,
2236                             const PropertyCallbackInfo<Value>& info) {
2237   HandleScope scope(node_isolate);
2238   info.GetReturnValue().Set(debug_port);
2239 }
2240
2241
2242 static void DebugPortSetter(Local<String> property,
2243                             Local<Value> value,
2244                             const PropertyCallbackInfo<void>& info) {
2245   HandleScope scope(node_isolate);
2246   debug_port = value->NumberValue();
2247 }
2248
2249
2250 static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2251 static void DebugPause(const FunctionCallbackInfo<Value>& args);
2252 static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2253
2254
2255 void NeedImmediateCallbackGetter(Local<String> property,
2256                                  const PropertyCallbackInfo<Value>& info) {
2257   info.GetReturnValue().Set(need_immediate_cb);
2258 }
2259
2260
2261 static void NeedImmediateCallbackSetter(Local<String> property,
2262                                         Local<Value> value,
2263                                         const PropertyCallbackInfo<void>&) {
2264   HandleScope scope(node_isolate);
2265
2266   bool bool_value = value->BooleanValue();
2267
2268   if (need_immediate_cb == bool_value) return;
2269
2270   need_immediate_cb = bool_value;
2271
2272   if (need_immediate_cb) {
2273     uv_check_start(&check_immediate_watcher, node::CheckImmediate);
2274     // idle handle is needed only to maintain event loop
2275     uv_idle_start(&idle_immediate_dummy, node::IdleImmediateDummy);
2276   } else {
2277     uv_check_stop(&check_immediate_watcher);
2278     uv_idle_stop(&idle_immediate_dummy);
2279   }
2280 }
2281
2282
2283 #define READONLY_PROPERTY(obj, str, var)                                      \
2284   do {                                                                        \
2285     obj->Set(OneByteString(node_isolate, str), var, v8::ReadOnly);            \
2286   } while (0)
2287
2288
2289 Handle<Object> SetupProcessObject(int argc,
2290                                   const char* const* argv,
2291                                   int exec_argc,
2292                                   const char* const* exec_argv) {
2293   HandleScope scope(node_isolate);
2294
2295   int i, j;
2296
2297   Local<FunctionTemplate> process_template = FunctionTemplate::New();
2298   process_template->SetClassName(
2299       FIXED_ONE_BYTE_STRING(node_isolate, "process"));
2300
2301   Local<Object> process = process_template->GetFunction()->NewInstance();
2302   assert(process.IsEmpty() == false);
2303   assert(process->IsObject() == true);
2304
2305   process_p.Reset(node_isolate, process);
2306
2307   process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "title"),
2308                        ProcessTitleGetter,
2309                        ProcessTitleSetter);
2310
2311   // process.version
2312   READONLY_PROPERTY(process,
2313                     "version",
2314                     FIXED_ONE_BYTE_STRING(node_isolate, NODE_VERSION));
2315
2316   // process.moduleLoadList
2317   Local<Array> modules = Array::New();
2318   module_load_list.Reset(node_isolate, modules);
2319   READONLY_PROPERTY(process, "moduleLoadList", modules);
2320
2321   // process.versions
2322   Local<Object> versions = Object::New();
2323   READONLY_PROPERTY(process, "versions", versions);
2324
2325   const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
2326                                      "."
2327                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR);
2328   READONLY_PROPERTY(versions,
2329                     "http_parser",
2330                     FIXED_ONE_BYTE_STRING(node_isolate, http_parser_version));
2331
2332   // +1 to get rid of the leading 'v'
2333   READONLY_PROPERTY(versions,
2334                     "node",
2335                     OneByteString(node_isolate, NODE_VERSION + 1));
2336   READONLY_PROPERTY(versions,
2337                     "v8",
2338                     OneByteString(node_isolate, V8::GetVersion()));
2339   READONLY_PROPERTY(versions,
2340                     "uv",
2341                     OneByteString(node_isolate, uv_version_string()));
2342   READONLY_PROPERTY(versions,
2343                     "zlib",
2344                     FIXED_ONE_BYTE_STRING(node_isolate, ZLIB_VERSION));
2345
2346   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
2347   READONLY_PROPERTY(versions,
2348                     "modules",
2349                     FIXED_ONE_BYTE_STRING(node_isolate, node_modules_version));
2350
2351 #if HAVE_OPENSSL
2352   // Stupid code to slice out the version string.
2353   int c, l = strlen(OPENSSL_VERSION_TEXT);
2354   for (i = j = 0; i < l; i++) {
2355     c = OPENSSL_VERSION_TEXT[i];
2356     if ('0' <= c && c <= '9') {
2357       for (j = i + 1; j < l; j++) {
2358         c = OPENSSL_VERSION_TEXT[j];
2359         if (c == ' ') break;
2360       }
2361       break;
2362     }
2363   }
2364   READONLY_PROPERTY(
2365       versions,
2366       "openssl",
2367       OneByteString(node_isolate, &OPENSSL_VERSION_TEXT[i], j - i));
2368 #endif
2369
2370
2371
2372   // process.arch
2373   READONLY_PROPERTY(process, "arch", OneByteString(node_isolate, ARCH));
2374
2375   // process.platform
2376   READONLY_PROPERTY(process,
2377                     "platform",
2378                     OneByteString(node_isolate, PLATFORM));
2379
2380   // process.argv
2381   Local<Array> arguments = Array::New(argc);
2382   for (int i = 0; i < argc; ++i) {
2383     arguments->Set(i, String::NewFromUtf8(node_isolate, argv[i]));
2384   }
2385   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "argv"), arguments);
2386
2387   // process.execArgv
2388   Local<Array> exec_arguments = Array::New(exec_argc);
2389   for (int i = 0; i < exec_argc; ++i) {
2390     exec_arguments->Set(i, String::NewFromUtf8(node_isolate, exec_argv[i]));
2391   }
2392   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execArgv"), exec_arguments);
2393
2394   // create process.env
2395   Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
2396   envTemplate->SetNamedPropertyHandler(EnvGetter,
2397                                        EnvSetter,
2398                                        EnvQuery,
2399                                        EnvDeleter,
2400                                        EnvEnumerator,
2401                                        Object::New());
2402   Local<Object> env = envTemplate->NewInstance();
2403   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "env"), env);
2404
2405   READONLY_PROPERTY(process, "pid", Integer::New(getpid(), node_isolate));
2406   READONLY_PROPERTY(process, "features", GetFeatures());
2407   process->SetAccessor(
2408       FIXED_ONE_BYTE_STRING(node_isolate, "_needImmediateCallback"),
2409       NeedImmediateCallbackGetter,
2410       NeedImmediateCallbackSetter);
2411
2412   // -e, --eval
2413   if (eval_string) {
2414     READONLY_PROPERTY(process,
2415                       "_eval",
2416                       String::NewFromUtf8(node_isolate, eval_string));
2417   }
2418
2419   // -p, --print
2420   if (print_eval) {
2421     READONLY_PROPERTY(process, "_print_eval", True(node_isolate));
2422   }
2423
2424   // -i, --interactive
2425   if (force_repl) {
2426     READONLY_PROPERTY(process, "_forceRepl", True(node_isolate));
2427   }
2428
2429   // --no-deprecation
2430   if (no_deprecation) {
2431     READONLY_PROPERTY(process, "noDeprecation", True(node_isolate));
2432   }
2433
2434   // --throw-deprecation
2435   if (throw_deprecation) {
2436     READONLY_PROPERTY(process, "throwDeprecation", True(node_isolate));
2437   }
2438
2439   // --trace-deprecation
2440   if (trace_deprecation) {
2441     READONLY_PROPERTY(process, "traceDeprecation", True(node_isolate));
2442   }
2443
2444   size_t exec_path_len = 2 * PATH_MAX;
2445   char* exec_path = new char[exec_path_len];
2446   Local<String> exec_path_value;
2447   if (uv_exepath(exec_path, &exec_path_len) == 0) {
2448     exec_path_value = String::NewFromUtf8(node_isolate,
2449                                           exec_path,
2450                                           String::kNormalString,
2451                                           exec_path_len);
2452   } else {
2453     exec_path_value = String::NewFromUtf8(node_isolate, argv[0]);
2454   }
2455   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execPath"),
2456                exec_path_value);
2457   delete[] exec_path;
2458
2459   process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "debugPort"),
2460                        DebugPortGetter,
2461                        DebugPortSetter);
2462
2463   // define various internal methods
2464   NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests);
2465   NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles);
2466   NODE_SET_METHOD(process, "reallyExit", Exit);
2467   NODE_SET_METHOD(process, "abort", Abort);
2468   NODE_SET_METHOD(process, "chdir", Chdir);
2469   NODE_SET_METHOD(process, "cwd", Cwd);
2470
2471   NODE_SET_METHOD(process, "umask", Umask);
2472
2473 #if defined(__POSIX__) && !defined(__ANDROID__)
2474   NODE_SET_METHOD(process, "getuid", GetUid);
2475   NODE_SET_METHOD(process, "setuid", SetUid);
2476
2477   NODE_SET_METHOD(process, "setgid", SetGid);
2478   NODE_SET_METHOD(process, "getgid", GetGid);
2479
2480   NODE_SET_METHOD(process, "getgroups", GetGroups);
2481   NODE_SET_METHOD(process, "setgroups", SetGroups);
2482   NODE_SET_METHOD(process, "initgroups", InitGroups);
2483 #endif  // __POSIX__ && !defined(__ANDROID__)
2484
2485   NODE_SET_METHOD(process, "_kill", Kill);
2486
2487   NODE_SET_METHOD(process, "_debugProcess", DebugProcess);
2488   NODE_SET_METHOD(process, "_debugPause", DebugPause);
2489   NODE_SET_METHOD(process, "_debugEnd", DebugEnd);
2490
2491   NODE_SET_METHOD(process, "hrtime", Hrtime);
2492
2493   NODE_SET_METHOD(process, "dlopen", DLOpen);
2494
2495   NODE_SET_METHOD(process, "uptime", Uptime);
2496   NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
2497
2498   NODE_SET_METHOD(process, "binding", Binding);
2499
2500   NODE_SET_METHOD(process, "_setupDomainUse", SetupDomainUse);
2501
2502   // values use to cross communicate with processNextTick
2503   Local<Object> info_box = Object::New();
2504   info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
2505                                                     kExternalUnsignedIntArray,
2506                                                     4);
2507   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickInfoBox"), info_box);
2508
2509   // pre-set _events object for faster emit checks
2510   process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_events"), Object::New());
2511
2512   return scope.Close(process);
2513 }
2514
2515
2516 #undef READONLY_PROPERTY
2517
2518
2519 static void AtExit() {
2520   uv_tty_reset_mode();
2521 }
2522
2523
2524 static void SignalExit(int signal) {
2525   uv_tty_reset_mode();
2526   _exit(128 + signal);
2527 }
2528
2529
2530 // Most of the time, it's best to use `console.error` to write
2531 // to the process.stderr stream.  However, in some cases, such as
2532 // when debugging the stream.Writable class or the process.nextTick
2533 // function, it is useful to bypass JavaScript entirely.
2534 static void RawDebug(const FunctionCallbackInfo<Value>& args) {
2535   HandleScope scope(node_isolate);
2536
2537   assert(args.Length() == 1 && args[0]->IsString() &&
2538          "must be called with a single string");
2539
2540   String::Utf8Value message(args[0]);
2541   fprintf(stderr, "%s\n", *message);
2542   fflush(stderr);
2543 }
2544
2545
2546 void Load(Handle<Object> process_l) {
2547   HandleScope handle_scope(node_isolate);
2548
2549   process_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "process");
2550   domain_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "domain");
2551
2552   // Compile, execute the src/node.js file. (Which was included as static C
2553   // string in node_natives.h. 'natve_node' is the string containing that
2554   // source code.)
2555
2556   // The node.js file returns a function 'f'
2557   atexit(AtExit);
2558
2559   TryCatch try_catch;
2560
2561   // Disable verbose mode to stop FatalException() handler from trying
2562   // to handle the exception. Errors this early in the start-up phase
2563   // are not safe to ignore.
2564   try_catch.SetVerbose(false);
2565
2566   Local<String> script_name = FIXED_ONE_BYTE_STRING(node_isolate, "node.js");
2567   Local<Value> f_value = ExecuteString(MainSource(), script_name);
2568   if (try_catch.HasCaught())  {
2569     ReportException(try_catch);
2570     exit(10);
2571   }
2572   assert(f_value->IsFunction());
2573   Local<Function> f = Local<Function>::Cast(f_value);
2574
2575   // Now we call 'f' with the 'process' variable that we've built up with
2576   // all our bindings. Inside node.js we'll take care of assigning things to
2577   // their places.
2578
2579   // We start the process this way in order to be more modular. Developers
2580   // who do not like how 'src/node.js' setups the module system but do like
2581   // Node's I/O bindings may want to replace 'f' with their own function.
2582
2583   // Add a reference to the global object
2584   Local<Object> global = v8::Context::GetCurrent()->Global();
2585
2586 #if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
2587   InitDTrace(global);
2588 #endif
2589
2590 #if defined HAVE_PERFCTR
2591   InitPerfCounters(global);
2592 #endif
2593
2594   // Enable handling of uncaught exceptions
2595   // (FatalException(), break on uncaught exception in debugger)
2596   //
2597   // This is not strictly necessary since it's almost impossible
2598   // to attach the debugger fast enought to break on exception
2599   // thrown during process startup.
2600   try_catch.SetVerbose(true);
2601
2602   NODE_SET_METHOD(process_l, "_rawDebug", RawDebug);
2603
2604   Local<Value> arg = process_l;
2605   f->Call(global, 1, &arg);
2606 }
2607
2608 static void PrintHelp();
2609
2610 static void ParseDebugOpt(const char* arg) {
2611   const char *p = 0;
2612
2613   if (strstr(arg, "--debug-port=") == arg) {
2614     p = 1 + strchr(arg, '=');
2615     debug_port = atoi(p);
2616   } else {
2617     use_debug_agent = true;
2618     if (!strcmp(arg, "--debug-brk")) {
2619       debug_wait_connect = true;
2620       return;
2621     } else if (!strcmp(arg, "--debug")) {
2622       return;
2623     } else if (strstr(arg, "--debug-brk=") == arg) {
2624       debug_wait_connect = true;
2625       p = 1 + strchr(arg, '=');
2626       debug_port = atoi(p);
2627     } else if (strstr(arg, "--debug=") == arg) {
2628       p = 1 + strchr(arg, '=');
2629       debug_port = atoi(p);
2630     }
2631   }
2632   if (p && debug_port > 1024 && debug_port <  65536)
2633       return;
2634
2635   fprintf(stderr, "Bad debug option.\n");
2636   if (p) fprintf(stderr, "Debug port must be in range 1025 to 65535.\n");
2637
2638   PrintHelp();
2639   exit(12);
2640 }
2641
2642 static void PrintHelp() {
2643   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
2644          "       node debug script.js [arguments] \n"
2645          "\n"
2646          "Options:\n"
2647          "  -v, --version        print node's version\n"
2648          "  -e, --eval script    evaluate script\n"
2649          "  -p, --print          evaluate script and print result\n"
2650          "  -i, --interactive    always enter the REPL even if stdin\n"
2651          "                       does not appear to be a terminal\n"
2652          "  --no-deprecation     silence deprecation warnings\n"
2653          "  --trace-deprecation  show stack traces on deprecations\n"
2654          "  --v8-options         print v8 command line options\n"
2655          "  --max-stack-size=val set max v8 stack size (bytes)\n"
2656          "\n"
2657          "Environment variables:\n"
2658 #ifdef _WIN32
2659          "NODE_PATH              ';'-separated list of directories\n"
2660 #else
2661          "NODE_PATH              ':'-separated list of directories\n"
2662 #endif
2663          "                       prefixed to the module search path.\n"
2664          "NODE_MODULE_CONTEXTS   Set to 1 to load modules in their own\n"
2665          "                       global contexts.\n"
2666          "NODE_DISABLE_COLORS    Set to 1 to disable colors in the REPL\n"
2667          "\n"
2668          "Documentation can be found at http://nodejs.org/\n");
2669 }
2670
2671
2672 // Parse command line arguments.
2673 //
2674 // argv is modified in place. exec_argv and v8_argv are out arguments that
2675 // ParseArgs() allocates memory for and stores a pointer to the output
2676 // vector in.  The caller should free them with delete[].
2677 //
2678 // On exit:
2679 //
2680 //  * argv contains the arguments with node and V8 options filtered out.
2681 //  * exec_argv contains both node and V8 options and nothing else.
2682 //  * v8_argv contains argv[0] plus any V8 options
2683 static void ParseArgs(int* argc,
2684                       const char** argv,
2685                       int* exec_argc,
2686                       const char*** exec_argv,
2687                       int* v8_argc,
2688                       const char*** v8_argv) {
2689   const unsigned int nargs = static_cast<unsigned int>(*argc);
2690   const char** new_exec_argv = new const char*[nargs];
2691   const char** new_v8_argv = new const char*[nargs];
2692   const char** new_argv = new const char*[nargs];
2693
2694   for (unsigned int i = 0; i < nargs; ++i) {
2695     new_exec_argv[i] = NULL;
2696     new_v8_argv[i] = NULL;
2697     new_argv[i] = NULL;
2698   }
2699
2700   // exec_argv starts with the first option, the other two start with argv[0].
2701   unsigned int new_exec_argc = 0;
2702   unsigned int new_v8_argc = 1;
2703   unsigned int new_argc = 1;
2704   new_v8_argv[0] = argv[0];
2705   new_argv[0] = argv[0];
2706
2707   unsigned int index = 1;
2708   while (index < nargs && argv[index][0] == '-') {
2709     const char* const arg = argv[index];
2710     unsigned int args_consumed = 1;
2711
2712     if (strstr(arg, "--debug") == arg) {
2713       ParseDebugOpt(arg);
2714     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
2715       printf("%s\n", NODE_VERSION);
2716       exit(0);
2717     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
2718       PrintHelp();
2719       exit(0);
2720     } else if (strcmp(arg, "--eval") == 0 ||
2721                strcmp(arg, "-e") == 0 ||
2722                strcmp(arg, "--print") == 0 ||
2723                strcmp(arg, "-pe") == 0 ||
2724                strcmp(arg, "-p") == 0) {
2725       bool is_eval = strchr(arg, 'e') != NULL;
2726       bool is_print = strchr(arg, 'p') != NULL;
2727       print_eval = print_eval || is_print;
2728       // --eval, -e and -pe always require an argument.
2729       if (is_eval == true) {
2730         args_consumed += 1;
2731         eval_string = argv[index + 1];
2732         if (eval_string == NULL) {
2733           fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
2734           exit(1);
2735         }
2736       } else if (argv[index + 1] != NULL && argv[index + 1][0] != '-') {
2737         args_consumed += 1;
2738         eval_string = argv[index + 1];
2739         if (strncmp(eval_string, "\\-", 2) == 0) {
2740           // Starts with "\\-": escaped expression, drop the backslash.
2741           eval_string += 1;
2742         }
2743       }
2744     } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
2745       force_repl = true;
2746     } else if (strcmp(arg, "--no-deprecation") == 0) {
2747       no_deprecation = true;
2748     } else if (strcmp(arg, "--trace-deprecation") == 0) {
2749       trace_deprecation = true;
2750     } else if (strcmp(arg, "--throw-deprecation") == 0) {
2751       throw_deprecation = true;
2752     } else if (strcmp(arg, "--v8-options") == 0) {
2753       new_v8_argv[new_v8_argc] = "--help";
2754       new_v8_argc += 1;
2755     } else {
2756       // V8 option.  Pass through as-is.
2757       new_v8_argv[new_v8_argc] = arg;
2758       new_v8_argc += 1;
2759     }
2760
2761     memcpy(new_exec_argv + new_exec_argc,
2762            argv + index,
2763            args_consumed * sizeof(*argv));
2764
2765     new_exec_argc += args_consumed;
2766     index += args_consumed;
2767   }
2768
2769   // Copy remaining arguments.
2770   const unsigned int args_left = nargs - index;
2771   memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
2772   new_argc += args_left;
2773
2774   *exec_argc = new_exec_argc;
2775   *exec_argv = new_exec_argv;
2776   *v8_argc = new_v8_argc;
2777   *v8_argv = new_v8_argv;
2778
2779   // Copy new_argv over argv and update argc.
2780   memcpy(argv, new_argv, new_argc * sizeof(*argv));
2781   delete[] new_argv;
2782   *argc = static_cast<int>(new_argc);
2783 }
2784
2785
2786 // Called from the main thread.
2787 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle, int status) {
2788   v8::Debug::ProcessDebugMessages();
2789 }
2790
2791
2792 // Called from V8 Debug Agent TCP thread.
2793 static void DispatchMessagesDebugAgentCallback() {
2794   uv_async_send(&dispatch_debug_messages_async);
2795 }
2796
2797
2798 // Called from the main thread
2799 static void EmitDebugEnabledAsyncCallback(uv_async_t* handle, int status) {
2800   HandleScope handle_scope(node_isolate);
2801   Local<Object> obj = Object::New();
2802   obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "cmd"),
2803            FIXED_ONE_BYTE_STRING(node_isolate, "NODE_DEBUG_ENABLED"));
2804   Local<Value> args[] = {
2805     FIXED_ONE_BYTE_STRING(node_isolate, "internalMessage"),
2806     obj
2807   };
2808   MakeCallback(process_p, "emit", ARRAY_SIZE(args), args);
2809 }
2810
2811
2812 // Called from the signal watcher callback
2813 static void EmitDebugEnabled() {
2814   uv_async_send(&emit_debug_enabled_async);
2815 }
2816
2817
2818 static void EnableDebug(bool wait_connect) {
2819   // If we're called from another thread, make sure to enter the right
2820   // v8 isolate.
2821   node_isolate->Enter();
2822
2823   v8::Debug::SetDebugMessageDispatchHandler(DispatchMessagesDebugAgentCallback,
2824                                             false);
2825
2826   // Start the debug thread and it's associated TCP server on port 5858.
2827   bool r = v8::Debug::EnableAgent("node " NODE_VERSION,
2828                                   debug_port,
2829                                   wait_connect);
2830
2831   // Crappy check that everything went well. FIXME
2832   assert(r);
2833
2834   // Print out some information.
2835   fprintf(stderr, "debugger listening on port %d\n", debug_port);
2836   fflush(stderr);
2837
2838   debugger_running = true;
2839
2840   // Do not emit NODE_DEBUG_ENABLED when debugger is enabled before starting
2841   // the main process (i.e. when called via `node --debug`)
2842   if (!process_p.IsEmpty())
2843     EmitDebugEnabled();
2844
2845   node_isolate->Exit();
2846 }
2847
2848
2849 #ifdef __POSIX__
2850 static void EnableDebugSignalHandler(uv_signal_t* handle, int) {
2851   // Break once process will return execution to v8
2852   v8::Debug::DebugBreak(node_isolate);
2853
2854   if (!debugger_running) {
2855     fprintf(stderr, "Hit SIGUSR1 - starting debugger agent.\n");
2856     EnableDebug(false);
2857   }
2858 }
2859
2860
2861 static void RegisterSignalHandler(int signal, void (*handler)(int signal)) {
2862   struct sigaction sa;
2863
2864   memset(&sa, 0, sizeof(sa));
2865   sa.sa_handler = handler;
2866   sigfillset(&sa.sa_mask);
2867   sigaction(signal, &sa, NULL);
2868 }
2869
2870
2871 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
2872   HandleScope scope(node_isolate);
2873
2874   if (args.Length() != 1) {
2875     return ThrowError("Invalid number of arguments.");
2876   }
2877
2878   pid_t pid;
2879   int r;
2880
2881   pid = args[0]->IntegerValue();
2882   r = kill(pid, SIGUSR1);
2883   if (r != 0) {
2884     return ThrowErrnoException(errno, "kill");
2885   }
2886 }
2887 #endif  // __POSIX__
2888
2889
2890 #ifdef _WIN32
2891 DWORD WINAPI EnableDebugThreadProc(void* arg) {
2892   // Break once process will return execution to v8
2893   if (!debugger_running) {
2894     for (int i = 0; i < 1; i++) {
2895       fprintf(stderr, "Starting debugger agent.\r\n");
2896       fflush(stderr);
2897       EnableDebug(false);
2898     }
2899   }
2900
2901   v8::Debug::DebugBreak(node_isolate);
2902
2903   return 0;
2904 }
2905
2906
2907 static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
2908     size_t buf_len) {
2909   return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
2910 }
2911
2912
2913 static int RegisterDebugSignalHandler() {
2914   wchar_t mapping_name[32];
2915   HANDLE mapping_handle;
2916   DWORD pid;
2917   LPTHREAD_START_ROUTINE* handler;
2918
2919   pid = GetCurrentProcessId();
2920
2921   if (GetDebugSignalHandlerMappingName(pid,
2922                                        mapping_name,
2923                                        ARRAY_SIZE(mapping_name)) < 0) {
2924     return -1;
2925   }
2926
2927   mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
2928                                       NULL,
2929                                       PAGE_READWRITE,
2930                                       0,
2931                                       sizeof *handler,
2932                                       mapping_name);
2933   if (mapping_handle == NULL) {
2934     return -1;
2935   }
2936
2937   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
2938       MapViewOfFile(mapping_handle,
2939                     FILE_MAP_ALL_ACCESS,
2940                     0,
2941                     0,
2942                     sizeof *handler));
2943   if (handler == NULL) {
2944     CloseHandle(mapping_handle);
2945     return -1;
2946   }
2947
2948   *handler = EnableDebugThreadProc;
2949
2950   UnmapViewOfFile(static_cast<void*>(handler));
2951
2952   return 0;
2953 }
2954
2955
2956 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
2957   HandleScope scope(node_isolate);
2958   DWORD pid;
2959   HANDLE process = NULL;
2960   HANDLE thread = NULL;
2961   HANDLE mapping = NULL;
2962   wchar_t mapping_name[32];
2963   LPTHREAD_START_ROUTINE* handler = NULL;
2964
2965   if (args.Length() != 1) {
2966     ThrowError("Invalid number of arguments.");
2967     goto out;
2968   }
2969
2970   pid = (DWORD) args[0]->IntegerValue();
2971
2972   process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
2973                             PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
2974                             PROCESS_VM_READ,
2975                         FALSE,
2976                         pid);
2977   if (process == NULL) {
2978     ThrowException(WinapiErrnoException(GetLastError(), "OpenProcess"));
2979     goto out;
2980   }
2981
2982   if (GetDebugSignalHandlerMappingName(pid,
2983                                        mapping_name,
2984                                        ARRAY_SIZE(mapping_name)) < 0) {
2985     ThrowErrnoException(errno, "sprintf");
2986     goto out;
2987   }
2988
2989   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
2990   if (mapping == NULL) {
2991     ThrowException(WinapiErrnoException(GetLastError(), "OpenFileMappingW"));
2992     goto out;
2993   }
2994
2995   handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
2996       MapViewOfFile(mapping,
2997                     FILE_MAP_READ,
2998                     0,
2999                     0,
3000                     sizeof *handler));
3001   if (handler == NULL || *handler == NULL) {
3002     ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile"));
3003     goto out;
3004   }
3005
3006   thread = CreateRemoteThread(process,
3007                               NULL,
3008                               0,
3009                               *handler,
3010                               NULL,
3011                               0,
3012                               NULL);
3013   if (thread == NULL) {
3014     ThrowException(WinapiErrnoException(GetLastError(), "CreateRemoteThread"));
3015     goto out;
3016   }
3017
3018   // Wait for the thread to terminate
3019   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
3020     ThrowException(WinapiErrnoException(GetLastError(), "WaitForSingleObject"));
3021     goto out;
3022   }
3023
3024  out:
3025   if (process != NULL)
3026     CloseHandle(process);
3027   if (thread != NULL)
3028     CloseHandle(thread);
3029   if (handler != NULL)
3030     UnmapViewOfFile(handler);
3031   if (mapping != NULL)
3032     CloseHandle(mapping);
3033 }
3034 #endif  // _WIN32
3035
3036
3037 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
3038   v8::Debug::DebugBreak(node_isolate);
3039 }
3040
3041
3042 static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
3043   if (debugger_running) {
3044     v8::Debug::DisableAgent();
3045     debugger_running = false;
3046   }
3047 }
3048
3049
3050 void Init(int* argc,
3051           const char** argv,
3052           int* exec_argc,
3053           const char*** exec_argv) {
3054   // Initialize prog_start_time to get relative uptime.
3055   uv_uptime(&prog_start_time);
3056
3057   // Make inherited handles noninheritable.
3058   uv_disable_stdio_inheritance();
3059
3060   // init async debug messages dispatching
3061   uv_async_init(uv_default_loop(),
3062                 &dispatch_debug_messages_async,
3063                 DispatchDebugMessagesAsyncCallback);
3064   uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
3065
3066   // init async NODE_DEBUG_ENABLED emitter
3067   uv_async_init(uv_default_loop(),
3068                 &emit_debug_enabled_async,
3069                 EmitDebugEnabledAsyncCallback);
3070   uv_unref(reinterpret_cast<uv_handle_t*>(&emit_debug_enabled_async));
3071
3072   // Parse a few arguments which are specific to Node.
3073   int v8_argc;
3074   const char** v8_argv;
3075   ParseArgs(argc, argv, exec_argc, exec_argv, &v8_argc, &v8_argv);
3076
3077   // The const_cast doesn't violate conceptual const-ness.  V8 doesn't modify
3078   // the argv array or the elements it points to.
3079   V8::SetFlagsFromCommandLine(&v8_argc, const_cast<char**>(v8_argv), true);
3080
3081   // Anything that's still in v8_argv is not a V8 or a node option.
3082   for (int i = 1; i < v8_argc; i++) {
3083     fprintf(stderr, "%s: bad option: %s\n", argv[0], v8_argv[i]);
3084   }
3085   delete[] v8_argv;
3086   v8_argv = NULL;
3087
3088   if (v8_argc > 1) {
3089     exit(1);
3090   }
3091
3092   if (debug_wait_connect) {
3093     const char expose_debug_as[] = "--expose_debug_as=v8debug";
3094     V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
3095   }
3096
3097   const char typed_arrays_flag[] = "--harmony_typed_arrays";
3098   V8::SetFlagsFromString(typed_arrays_flag, sizeof(typed_arrays_flag) - 1);
3099   V8::SetArrayBufferAllocator(&ArrayBufferAllocator::the_singleton);
3100
3101   // Fetch a reference to the main isolate, so we have a reference to it
3102   // even when we need it to access it from another (debugger) thread.
3103   node_isolate = Isolate::GetCurrent();
3104
3105 #ifdef __POSIX__
3106   // Ignore SIGPIPE
3107   RegisterSignalHandler(SIGPIPE, SIG_IGN);
3108   RegisterSignalHandler(SIGINT, SignalExit);
3109   RegisterSignalHandler(SIGTERM, SignalExit);
3110 #endif  // __POSIX__
3111
3112   uv_check_init(uv_default_loop(), &check_immediate_watcher);
3113   uv_unref(reinterpret_cast<uv_handle_t*>(&check_immediate_watcher));
3114   uv_idle_init(uv_default_loop(), &idle_immediate_dummy);
3115
3116   V8::SetFatalErrorHandler(node::OnFatalError);
3117   V8::AddMessageListener(OnMessage);
3118
3119   // If the --debug flag was specified then initialize the debug thread.
3120   if (use_debug_agent) {
3121     EnableDebug(debug_wait_connect);
3122   } else {
3123 #ifdef _WIN32
3124     RegisterDebugSignalHandler();
3125 #else  // Posix
3126     static uv_signal_t signal_watcher;
3127     uv_signal_init(uv_default_loop(), &signal_watcher);
3128     uv_signal_start(&signal_watcher, EnableDebugSignalHandler, SIGUSR1);
3129     uv_unref(reinterpret_cast<uv_handle_t*>(&signal_watcher));
3130 #endif  // __POSIX__
3131   }
3132 }
3133
3134
3135 struct AtExitCallback {
3136   AtExitCallback* next_;
3137   void (*cb_)(void* arg);
3138   void* arg_;
3139 };
3140
3141 static AtExitCallback* at_exit_functions_;
3142
3143
3144 void RunAtExit() {
3145   AtExitCallback* p = at_exit_functions_;
3146   at_exit_functions_ = NULL;
3147
3148   while (p) {
3149     AtExitCallback* q = p->next_;
3150     p->cb_(p->arg_);
3151     delete p;
3152     p = q;
3153   }
3154 }
3155
3156
3157 void AtExit(void (*cb)(void* arg), void* arg) {
3158   AtExitCallback* p = new AtExitCallback;
3159   p->cb_ = cb;
3160   p->arg_ = arg;
3161   p->next_ = at_exit_functions_;
3162   at_exit_functions_ = p;
3163 }
3164
3165
3166 void EmitExit(v8::Handle<v8::Object> process_l) {
3167   // process.emit('exit')
3168   process_l->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_exiting"),
3169                  True(node_isolate));
3170   Local<Value> args[] = {
3171     FIXED_ONE_BYTE_STRING(node_isolate, "exit"),
3172     Integer::New(0, node_isolate)
3173   };
3174   MakeCallback(process_l, "emit", ARRAY_SIZE(args), args);
3175 }
3176
3177
3178 int Start(int argc, char** argv) {
3179   assert(argc > 0);
3180
3181   // Hack around with the argv pointer. Used for process.title = "blah".
3182   argv = uv_setup_args(argc, argv);
3183
3184   // This needs to run *before* V8::Initialize().  The const_cast is not
3185   // optional, in case you're wondering.
3186   int exec_argc;
3187   const char** exec_argv;
3188   Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
3189
3190   V8::Initialize();
3191   {
3192     Locker locker(node_isolate);
3193     HandleScope handle_scope(node_isolate);
3194
3195     // Create the one and only Context.
3196     Local<Context> context = Context::New(node_isolate);
3197     Context::Scope context_scope(context);
3198
3199     binding_cache.Reset(node_isolate, Object::New());
3200
3201     // Use original argv, as we're just copying values out of it.
3202     Local<Object> process_l =
3203         SetupProcessObject(argc, argv, exec_argc, exec_argv);
3204
3205     // Create all the objects, load modules, do everything.
3206     // so your next reading stop should be node::Load()!
3207     Load(process_l);
3208
3209     // All our arguments are loaded. We've evaluated all of the scripts. We
3210     // might even have created TCP servers. Now we enter the main eventloop. If
3211     // there are no watchers on the loop (except for the ones that were
3212     // uv_unref'd) then this function exits. As long as there are active
3213     // watchers, it blocks.
3214     uv_run(uv_default_loop(), UV_RUN_DEFAULT);
3215
3216     EmitExit(process_l);
3217     RunAtExit();
3218   }
3219
3220 #ifndef NDEBUG
3221   // Clean up. Not strictly necessary.
3222   V8::Dispose();
3223 #endif  // NDEBUG
3224
3225   delete[] exec_argv;
3226   exec_argv = NULL;
3227
3228   return 0;
3229 }
3230
3231
3232 }  // namespace node