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