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