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