46d2a796c3df2206ac581f24449af26ab7fd27d5
[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
24 #include <uv.h>
25
26 #include <v8-debug.h>
27 #include <node_dtrace.h>
28
29 #include <locale.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #if defined(_MSC_VER)
33 #define snprintf _snprintf
34 #endif
35 #include <stdlib.h>
36 #include <string.h>
37 #if !defined(_MSC_VER)
38 #include <strings.h>
39 #else
40 #define strcasecmp _stricmp
41 #endif
42 #include <limits.h> /* PATH_MAX */
43 #include <assert.h>
44 #if !defined(_MSC_VER)
45 #include <unistd.h> /* setuid, getuid */
46 #else
47 #include <direct.h>
48 #define chdir _chdir
49 #define getcwd _getcwd
50 #include <process.h>
51 #define getpid _getpid
52 #include <io.h>
53 #define umask _umask
54 typedef int mode_t;
55 #endif
56 #include <errno.h>
57 #include <sys/types.h>
58
59 #if defined(__MINGW32__) || defined(_MSC_VER)
60 # include <platform_win32.h> /* winapi_perror() */
61 #endif
62
63 #ifdef __POSIX__
64 # include <dlfcn.h> /* dlopen(), dlsym() */
65 # include <pwd.h> /* getpwnam() */
66 # include <grp.h> /* getgrnam() */
67 #endif
68
69 #include "platform.h"
70 #include <node_buffer.h>
71 #ifdef __POSIX__
72 # include <node_io_watcher.h>
73 #endif
74 #include <node_file.h>
75 #include <node_http_parser.h>
76 #ifdef __POSIX__
77 # include <node_signal_watcher.h>
78 # include <node_stat_watcher.h>
79 #endif
80 #include <node_constants.h>
81 #include <node_javascript.h>
82 #include <node_version.h>
83 #include <node_string.h>
84 #if HAVE_OPENSSL
85 # include <node_crypto.h>
86 #endif
87 #include <node_script.h>
88 #include <v8_typed_array.h>
89
90 using namespace v8;
91
92 # ifdef __APPLE__
93 # include <crt_externs.h>
94 # define environ (*_NSGetEnviron())
95 # elif !defined(_MSC_VER)
96 extern char **environ;
97 # endif
98
99 namespace node {
100
101 static Persistent<Object> process;
102
103 static Persistent<String> errno_symbol;
104 static Persistent<String> syscall_symbol;
105 static Persistent<String> errpath_symbol;
106 static Persistent<String> code_symbol;
107
108 static Persistent<String> rss_symbol;
109 static Persistent<String> heap_total_symbol;
110 static Persistent<String> heap_used_symbol;
111
112 static Persistent<String> listeners_symbol;
113 static Persistent<String> uncaught_exception_symbol;
114 static Persistent<String> emit_symbol;
115
116
117 static char *eval_string = NULL;
118 static int option_end_index = 0;
119 static bool use_debug_agent = false;
120 static bool debug_wait_connect = false;
121 static int debug_port=5858;
122 static int max_stack_size = 0;
123
124 static uv_check_t check_tick_watcher;
125 static uv_prepare_t prepare_tick_watcher;
126 static uv_idle_t tick_spinner;
127 static bool need_tick_cb;
128 static Persistent<String> tick_callback_sym;
129
130
131 #ifdef OPENSSL_NPN_NEGOTIATED
132 static bool use_npn = true;
133 #else
134 static bool use_npn = false;
135 #endif
136
137 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
138 static bool use_sni = true;
139 #else
140 static bool use_sni = false;
141 #endif
142
143 // Buffer for getpwnam_r(), getgrpam_r() and other misc callers; keep this
144 // scoped at file-level rather than method-level to avoid excess stack usage.
145 static char getbuf[PATH_MAX + 1];
146
147 // We need to notify V8 when we're idle so that it can run the garbage
148 // collector. The interface to this is V8::IdleNotification(). It returns
149 // true if the heap hasn't be fully compacted, and needs to be run again.
150 // Returning false means that it doesn't have anymore work to do.
151 //
152 // A rather convoluted algorithm has been devised to determine when Node is
153 // idle. You'll have to figure it out for yourself.
154 static uv_check_t gc_check;
155 static uv_idle_t gc_idle;
156 static uv_timer_t gc_timer;
157 bool need_gc;
158
159
160 #define FAST_TICK 700.
161 #define GC_WAIT_TIME 5000.
162 #define RPM_SAMPLES 100
163 #define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]
164 static int64_t tick_times[RPM_SAMPLES];
165 static int tick_time_head;
166
167 static void CheckStatus(uv_timer_t* watcher, int status);
168
169 static void StartGCTimer () {
170   if (!uv_is_active((uv_handle_t*) &gc_timer)) {
171     uv_timer_start(&node::gc_timer, node::CheckStatus, 5000, 5000);
172   }
173 }
174
175 static void StopGCTimer () {
176   if (uv_is_active((uv_handle_t*) &gc_timer)) {
177     uv_timer_stop(&gc_timer);
178   }
179 }
180
181 static void Idle(uv_idle_t* watcher, int status) {
182   assert((uv_idle_t*) watcher == &gc_idle);
183
184   if (V8::IdleNotification()) {
185     uv_idle_stop(&gc_idle);
186     StopGCTimer();
187   }
188 }
189
190
191 // Called directly after every call to select() (or epoll, or whatever)
192 static void Check(uv_check_t* watcher, int status) {
193   assert(watcher == &gc_check);
194
195   tick_times[tick_time_head] = uv_now(uv_default_loop());
196   tick_time_head = (tick_time_head + 1) % RPM_SAMPLES;
197
198   StartGCTimer();
199
200   for (int i = 0; i < (int)(GC_WAIT_TIME/FAST_TICK); i++) {
201     double d = TICK_TIME(i+1) - TICK_TIME(i+2);
202     //printf("d = %f\n", d);
203     // If in the last 5 ticks the difference between
204     // ticks was less than 0.7 seconds, then continue.
205     if (d < FAST_TICK) {
206       //printf("---\n");
207       return;
208     }
209   }
210
211   // Otherwise start the gc!
212
213   //fprintf(stderr, "start idle 2\n");
214   uv_idle_start(&node::gc_idle, node::Idle);
215 }
216
217
218 static void Tick(void) {
219   // Avoid entering a V8 scope.
220   if (!need_tick_cb) return;
221
222   need_tick_cb = false;
223   if (uv_is_active((uv_handle_t*) &tick_spinner)) {
224     uv_idle_stop(&tick_spinner);
225     uv_unref(uv_default_loop());
226   }
227
228   HandleScope scope;
229
230   if (tick_callback_sym.IsEmpty()) {
231     // Lazily set the symbol
232     tick_callback_sym =
233       Persistent<String>::New(String::NewSymbol("_tickCallback"));
234   }
235
236   Local<Value> cb_v = process->Get(tick_callback_sym);
237   if (!cb_v->IsFunction()) return;
238   Local<Function> cb = Local<Function>::Cast(cb_v);
239
240   TryCatch try_catch;
241
242   cb->Call(process, 0, NULL);
243
244   if (try_catch.HasCaught()) {
245     FatalException(try_catch);
246   }
247 }
248
249
250 static void Spin(uv_idle_t* handle, int status) {
251   assert((uv_idle_t*) handle == &tick_spinner);
252   assert(status == 0);
253   Tick();
254 }
255
256
257 static Handle<Value> NeedTickCallback(const Arguments& args) {
258   HandleScope scope;
259   need_tick_cb = true;
260   // TODO: this tick_spinner shouldn't be necessary. An ev_prepare should be
261   // sufficent, the problem is only in the case of the very last "tick" -
262   // there is nothing left to do in the event loop and libev will exit. The
263   // ev_prepare callback isn't called before exiting. Thus we start this
264   // tick_spinner to keep the event loop alive long enough to handle it.
265   if (!uv_is_active((uv_handle_t*) &tick_spinner)) {
266     uv_idle_start(&tick_spinner, Spin);
267     uv_ref(uv_default_loop());
268   }
269   return Undefined();
270 }
271
272
273 static void PrepareTick(uv_prepare_t* handle, int status) {
274   assert(handle == &prepare_tick_watcher);
275   assert(status == 0);
276   Tick();
277 }
278
279
280 static void CheckTick(uv_check_t* handle, int status) {
281   assert(handle == &check_tick_watcher);
282   assert(status == 0);
283   Tick();
284 }
285
286 static inline const char *errno_string(int errorno) {
287 #define ERRNO_CASE(e)  case e: return #e;
288   switch (errorno) {
289
290 #ifdef EACCES
291   ERRNO_CASE(EACCES);
292 #endif
293
294 #ifdef EADDRINUSE
295   ERRNO_CASE(EADDRINUSE);
296 #endif
297
298 #ifdef EADDRNOTAVAIL
299   ERRNO_CASE(EADDRNOTAVAIL);
300 #endif
301
302 #ifdef EAFNOSUPPORT
303   ERRNO_CASE(EAFNOSUPPORT);
304 #endif
305
306 #ifdef EAGAIN
307   ERRNO_CASE(EAGAIN);
308 #endif
309
310 #ifdef EWOULDBLOCK
311 # if EAGAIN != EWOULDBLOCK
312   ERRNO_CASE(EWOULDBLOCK);
313 # endif
314 #endif
315
316 #ifdef EALREADY
317   ERRNO_CASE(EALREADY);
318 #endif
319
320 #ifdef EBADF
321   ERRNO_CASE(EBADF);
322 #endif
323
324 #ifdef EBADMSG
325   ERRNO_CASE(EBADMSG);
326 #endif
327
328 #ifdef EBUSY
329   ERRNO_CASE(EBUSY);
330 #endif
331
332 #ifdef ECANCELED
333   ERRNO_CASE(ECANCELED);
334 #endif
335
336 #ifdef ECHILD
337   ERRNO_CASE(ECHILD);
338 #endif
339
340 #ifdef ECONNABORTED
341   ERRNO_CASE(ECONNABORTED);
342 #endif
343
344 #ifdef ECONNREFUSED
345   ERRNO_CASE(ECONNREFUSED);
346 #endif
347
348 #ifdef ECONNRESET
349   ERRNO_CASE(ECONNRESET);
350 #endif
351
352 #ifdef EDEADLK
353   ERRNO_CASE(EDEADLK);
354 #endif
355
356 #ifdef EDESTADDRREQ
357   ERRNO_CASE(EDESTADDRREQ);
358 #endif
359
360 #ifdef EDOM
361   ERRNO_CASE(EDOM);
362 #endif
363
364 #ifdef EDQUOT
365   ERRNO_CASE(EDQUOT);
366 #endif
367
368 #ifdef EEXIST
369   ERRNO_CASE(EEXIST);
370 #endif
371
372 #ifdef EFAULT
373   ERRNO_CASE(EFAULT);
374 #endif
375
376 #ifdef EFBIG
377   ERRNO_CASE(EFBIG);
378 #endif
379
380 #ifdef EHOSTUNREACH
381   ERRNO_CASE(EHOSTUNREACH);
382 #endif
383
384 #ifdef EIDRM
385   ERRNO_CASE(EIDRM);
386 #endif
387
388 #ifdef EILSEQ
389   ERRNO_CASE(EILSEQ);
390 #endif
391
392 #ifdef EINPROGRESS
393   ERRNO_CASE(EINPROGRESS);
394 #endif
395
396 #ifdef EINTR
397   ERRNO_CASE(EINTR);
398 #endif
399
400 #ifdef EINVAL
401   ERRNO_CASE(EINVAL);
402 #endif
403
404 #ifdef EIO
405   ERRNO_CASE(EIO);
406 #endif
407
408 #ifdef EISCONN
409   ERRNO_CASE(EISCONN);
410 #endif
411
412 #ifdef EISDIR
413   ERRNO_CASE(EISDIR);
414 #endif
415
416 #ifdef ELOOP
417   ERRNO_CASE(ELOOP);
418 #endif
419
420 #ifdef EMFILE
421   ERRNO_CASE(EMFILE);
422 #endif
423
424 #ifdef EMLINK
425   ERRNO_CASE(EMLINK);
426 #endif
427
428 #ifdef EMSGSIZE
429   ERRNO_CASE(EMSGSIZE);
430 #endif
431
432 #ifdef EMULTIHOP
433   ERRNO_CASE(EMULTIHOP);
434 #endif
435
436 #ifdef ENAMETOOLONG
437   ERRNO_CASE(ENAMETOOLONG);
438 #endif
439
440 #ifdef ENETDOWN
441   ERRNO_CASE(ENETDOWN);
442 #endif
443
444 #ifdef ENETRESET
445   ERRNO_CASE(ENETRESET);
446 #endif
447
448 #ifdef ENETUNREACH
449   ERRNO_CASE(ENETUNREACH);
450 #endif
451
452 #ifdef ENFILE
453   ERRNO_CASE(ENFILE);
454 #endif
455
456 #ifdef ENOBUFS
457   ERRNO_CASE(ENOBUFS);
458 #endif
459
460 #ifdef ENODATA
461   ERRNO_CASE(ENODATA);
462 #endif
463
464 #ifdef ENODEV
465   ERRNO_CASE(ENODEV);
466 #endif
467
468 #ifdef ENOENT
469   ERRNO_CASE(ENOENT);
470 #endif
471
472 #ifdef ENOEXEC
473   ERRNO_CASE(ENOEXEC);
474 #endif
475
476 #ifdef ENOLINK
477   ERRNO_CASE(ENOLINK);
478 #endif
479
480 #ifdef ENOLCK
481 # if ENOLINK != ENOLCK
482   ERRNO_CASE(ENOLCK);
483 # endif
484 #endif
485
486 #ifdef ENOMEM
487   ERRNO_CASE(ENOMEM);
488 #endif
489
490 #ifdef ENOMSG
491   ERRNO_CASE(ENOMSG);
492 #endif
493
494 #ifdef ENOPROTOOPT
495   ERRNO_CASE(ENOPROTOOPT);
496 #endif
497
498 #ifdef ENOSPC
499   ERRNO_CASE(ENOSPC);
500 #endif
501
502 #ifdef ENOSR
503   ERRNO_CASE(ENOSR);
504 #endif
505
506 #ifdef ENOSTR
507   ERRNO_CASE(ENOSTR);
508 #endif
509
510 #ifdef ENOSYS
511   ERRNO_CASE(ENOSYS);
512 #endif
513
514 #ifdef ENOTCONN
515   ERRNO_CASE(ENOTCONN);
516 #endif
517
518 #ifdef ENOTDIR
519   ERRNO_CASE(ENOTDIR);
520 #endif
521
522 #ifdef ENOTEMPTY
523   ERRNO_CASE(ENOTEMPTY);
524 #endif
525
526 #ifdef ENOTSOCK
527   ERRNO_CASE(ENOTSOCK);
528 #endif
529
530 #ifdef ENOTSUP
531   ERRNO_CASE(ENOTSUP);
532 #else
533 # ifdef EOPNOTSUPP
534   ERRNO_CASE(EOPNOTSUPP);
535 # endif
536 #endif
537
538 #ifdef ENOTTY
539   ERRNO_CASE(ENOTTY);
540 #endif
541
542 #ifdef ENXIO
543   ERRNO_CASE(ENXIO);
544 #endif
545
546
547 #ifdef EOVERFLOW
548   ERRNO_CASE(EOVERFLOW);
549 #endif
550
551 #ifdef EPERM
552   ERRNO_CASE(EPERM);
553 #endif
554
555 #ifdef EPIPE
556   ERRNO_CASE(EPIPE);
557 #endif
558
559 #ifdef EPROTO
560   ERRNO_CASE(EPROTO);
561 #endif
562
563 #ifdef EPROTONOSUPPORT
564   ERRNO_CASE(EPROTONOSUPPORT);
565 #endif
566
567 #ifdef EPROTOTYPE
568   ERRNO_CASE(EPROTOTYPE);
569 #endif
570
571 #ifdef ERANGE
572   ERRNO_CASE(ERANGE);
573 #endif
574
575 #ifdef EROFS
576   ERRNO_CASE(EROFS);
577 #endif
578
579 #ifdef ESPIPE
580   ERRNO_CASE(ESPIPE);
581 #endif
582
583 #ifdef ESRCH
584   ERRNO_CASE(ESRCH);
585 #endif
586
587 #ifdef ESTALE
588   ERRNO_CASE(ESTALE);
589 #endif
590
591 #ifdef ETIME
592   ERRNO_CASE(ETIME);
593 #endif
594
595 #ifdef ETIMEDOUT
596   ERRNO_CASE(ETIMEDOUT);
597 #endif
598
599 #ifdef ETXTBSY
600   ERRNO_CASE(ETXTBSY);
601 #endif
602
603 #ifdef EXDEV
604   ERRNO_CASE(EXDEV);
605 #endif
606
607 #ifdef WSAEINTR
608   ERRNO_CASE(WSAEINTR);
609 #endif
610
611 #ifdef WSAEBADF
612   ERRNO_CASE(WSAEBADF);
613 #endif
614
615 #ifdef WSAEACCES
616   ERRNO_CASE(WSAEACCES);
617 #endif
618
619 #ifdef WSAEFAULT
620   ERRNO_CASE(WSAEFAULT);
621 #endif
622
623 #ifdef WSAEINVAL
624   ERRNO_CASE(WSAEINVAL);
625 #endif
626
627 #ifdef WSAEMFILE
628   ERRNO_CASE(WSAEMFILE);
629 #endif
630
631 #ifdef WSAEWOULDBLOCK
632   ERRNO_CASE(WSAEWOULDBLOCK);
633 #endif
634
635 #ifdef WSAEINPROGRESS
636   ERRNO_CASE(WSAEINPROGRESS);
637 #endif
638
639 #ifdef WSAEALREADY
640   ERRNO_CASE(WSAEALREADY);
641 #endif
642
643 #ifdef WSAENOTSOCK
644   ERRNO_CASE(WSAENOTSOCK);
645 #endif
646
647 #ifdef WSAEDESTADDRREQ
648   ERRNO_CASE(WSAEDESTADDRREQ);
649 #endif
650
651 #ifdef WSAEMSGSIZE
652   ERRNO_CASE(WSAEMSGSIZE);
653 #endif
654
655 #ifdef WSAEPROTOTYPE
656   ERRNO_CASE(WSAEPROTOTYPE);
657 #endif
658
659 #ifdef WSAENOPROTOOPT
660   ERRNO_CASE(WSAENOPROTOOPT);
661 #endif
662
663 #ifdef WSAEPROTONOSUPPORT
664   ERRNO_CASE(WSAEPROTONOSUPPORT);
665 #endif
666
667 #ifdef WSAESOCKTNOSUPPORT
668   ERRNO_CASE(WSAESOCKTNOSUPPORT);
669 #endif
670
671 #ifdef WSAEOPNOTSUPP
672   ERRNO_CASE(WSAEOPNOTSUPP);
673 #endif
674
675 #ifdef WSAEPFNOSUPPORT
676   ERRNO_CASE(WSAEPFNOSUPPORT);
677 #endif
678
679 #ifdef WSAEAFNOSUPPORT
680   ERRNO_CASE(WSAEAFNOSUPPORT);
681 #endif
682
683 #ifdef WSAEADDRINUSE
684   ERRNO_CASE(WSAEADDRINUSE);
685 #endif
686
687 #ifdef WSAEADDRNOTAVAIL
688   ERRNO_CASE(WSAEADDRNOTAVAIL);
689 #endif
690
691 #ifdef WSAENETDOWN
692   ERRNO_CASE(WSAENETDOWN);
693 #endif
694
695 #ifdef WSAENETUNREACH
696   ERRNO_CASE(WSAENETUNREACH);
697 #endif
698
699 #ifdef WSAENETRESET
700   ERRNO_CASE(WSAENETRESET);
701 #endif
702
703 #ifdef WSAECONNABORTED
704   ERRNO_CASE(WSAECONNABORTED);
705 #endif
706
707 #ifdef WSAECONNRESET
708   ERRNO_CASE(WSAECONNRESET);
709 #endif
710
711 #ifdef WSAENOBUFS
712   ERRNO_CASE(WSAENOBUFS);
713 #endif
714
715 #ifdef WSAEISCONN
716   ERRNO_CASE(WSAEISCONN);
717 #endif
718
719 #ifdef WSAENOTCONN
720   ERRNO_CASE(WSAENOTCONN);
721 #endif
722
723 #ifdef WSAESHUTDOWN
724   ERRNO_CASE(WSAESHUTDOWN);
725 #endif
726
727 #ifdef WSAETOOMANYREFS
728   ERRNO_CASE(WSAETOOMANYREFS);
729 #endif
730
731 #ifdef WSAETIMEDOUT
732   ERRNO_CASE(WSAETIMEDOUT);
733 #endif
734
735 #ifdef WSAECONNREFUSED
736   ERRNO_CASE(WSAECONNREFUSED);
737 #endif
738
739 #ifdef WSAELOOP
740   ERRNO_CASE(WSAELOOP);
741 #endif
742
743 #ifdef WSAENAMETOOLONG
744   ERRNO_CASE(WSAENAMETOOLONG);
745 #endif
746
747 #ifdef WSAEHOSTDOWN
748   ERRNO_CASE(WSAEHOSTDOWN);
749 #endif
750
751 #ifdef WSAEHOSTUNREACH
752   ERRNO_CASE(WSAEHOSTUNREACH);
753 #endif
754
755 #ifdef WSAENOTEMPTY
756   ERRNO_CASE(WSAENOTEMPTY);
757 #endif
758
759 #ifdef WSAEPROCLIM
760   ERRNO_CASE(WSAEPROCLIM);
761 #endif
762
763 #ifdef WSAEUSERS
764   ERRNO_CASE(WSAEUSERS);
765 #endif
766
767 #ifdef WSAEDQUOT
768   ERRNO_CASE(WSAEDQUOT);
769 #endif
770
771 #ifdef WSAESTALE
772   ERRNO_CASE(WSAESTALE);
773 #endif
774
775 #ifdef WSAEREMOTE
776   ERRNO_CASE(WSAEREMOTE);
777 #endif
778
779 #ifdef WSASYSNOTREADY
780   ERRNO_CASE(WSASYSNOTREADY);
781 #endif
782
783 #ifdef WSAVERNOTSUPPORTED
784   ERRNO_CASE(WSAVERNOTSUPPORTED);
785 #endif
786
787 #ifdef WSANOTINITIALISED
788   ERRNO_CASE(WSANOTINITIALISED);
789 #endif
790
791 #ifdef WSAEDISCON
792   ERRNO_CASE(WSAEDISCON);
793 #endif
794
795 #ifdef WSAENOMORE
796   ERRNO_CASE(WSAENOMORE);
797 #endif
798
799 #ifdef WSAECANCELLED
800   ERRNO_CASE(WSAECANCELLED);
801 #endif
802
803 #ifdef WSAEINVALIDPROCTABLE
804   ERRNO_CASE(WSAEINVALIDPROCTABLE);
805 #endif
806
807 #ifdef WSAEINVALIDPROVIDER
808   ERRNO_CASE(WSAEINVALIDPROVIDER);
809 #endif
810
811 #ifdef WSAEPROVIDERFAILEDINIT
812   ERRNO_CASE(WSAEPROVIDERFAILEDINIT);
813 #endif
814
815 #ifdef WSASYSCALLFAILURE
816   ERRNO_CASE(WSASYSCALLFAILURE);
817 #endif
818
819 #ifdef WSASERVICE_NOT_FOUND
820   ERRNO_CASE(WSASERVICE_NOT_FOUND);
821 #endif
822
823 #ifdef WSATYPE_NOT_FOUND
824   ERRNO_CASE(WSATYPE_NOT_FOUND);
825 #endif
826
827 #ifdef WSA_E_NO_MORE
828   ERRNO_CASE(WSA_E_NO_MORE);
829 #endif
830
831 #ifdef WSA_E_CANCELLED
832   ERRNO_CASE(WSA_E_CANCELLED);
833 #endif
834
835   default: return "";
836   }
837 }
838
839 const char *signo_string(int signo) {
840 #define SIGNO_CASE(e)  case e: return #e;
841   switch (signo) {
842
843 #ifdef SIGHUP
844   SIGNO_CASE(SIGHUP);
845 #endif
846
847 #ifdef SIGINT
848   SIGNO_CASE(SIGINT);
849 #endif
850
851 #ifdef SIGQUIT
852   SIGNO_CASE(SIGQUIT);
853 #endif
854
855 #ifdef SIGILL
856   SIGNO_CASE(SIGILL);
857 #endif
858
859 #ifdef SIGTRAP
860   SIGNO_CASE(SIGTRAP);
861 #endif
862
863 #ifdef SIGABRT
864   SIGNO_CASE(SIGABRT);
865 #endif
866
867 #ifdef SIGIOT
868 # if SIGABRT != SIGIOT
869   SIGNO_CASE(SIGIOT);
870 # endif
871 #endif
872
873 #ifdef SIGBUS
874   SIGNO_CASE(SIGBUS);
875 #endif
876
877 #ifdef SIGFPE
878   SIGNO_CASE(SIGFPE);
879 #endif
880
881 #ifdef SIGKILL
882   SIGNO_CASE(SIGKILL);
883 #endif
884
885 #ifdef SIGUSR1
886   SIGNO_CASE(SIGUSR1);
887 #endif
888
889 #ifdef SIGSEGV
890   SIGNO_CASE(SIGSEGV);
891 #endif
892
893 #ifdef SIGUSR2
894   SIGNO_CASE(SIGUSR2);
895 #endif
896
897 #ifdef SIGPIPE
898   SIGNO_CASE(SIGPIPE);
899 #endif
900
901 #ifdef SIGALRM
902   SIGNO_CASE(SIGALRM);
903 #endif
904
905   SIGNO_CASE(SIGTERM);
906
907 #ifdef SIGCHLD
908   SIGNO_CASE(SIGCHLD);
909 #endif
910
911 #ifdef SIGSTKFLT
912   SIGNO_CASE(SIGSTKFLT);
913 #endif
914
915
916 #ifdef SIGCONT
917   SIGNO_CASE(SIGCONT);
918 #endif
919
920 #ifdef SIGSTOP
921   SIGNO_CASE(SIGSTOP);
922 #endif
923
924 #ifdef SIGTSTP
925   SIGNO_CASE(SIGTSTP);
926 #endif
927
928 #ifdef SIGTTIN
929   SIGNO_CASE(SIGTTIN);
930 #endif
931
932 #ifdef SIGTTOU
933   SIGNO_CASE(SIGTTOU);
934 #endif
935
936 #ifdef SIGURG
937   SIGNO_CASE(SIGURG);
938 #endif
939
940 #ifdef SIGXCPU
941   SIGNO_CASE(SIGXCPU);
942 #endif
943
944 #ifdef SIGXFSZ
945   SIGNO_CASE(SIGXFSZ);
946 #endif
947
948 #ifdef SIGVTALRM
949   SIGNO_CASE(SIGVTALRM);
950 #endif
951
952 #ifdef SIGPROF
953   SIGNO_CASE(SIGPROF);
954 #endif
955
956 #ifdef SIGWINCH
957   SIGNO_CASE(SIGWINCH);
958 #endif
959
960 #ifdef SIGIO
961   SIGNO_CASE(SIGIO);
962 #endif
963
964 #ifdef SIGPOLL
965 # if SIGPOLL != SIGIO
966   SIGNO_CASE(SIGPOLL);
967 # endif
968 #endif
969
970 #ifdef SIGLOST
971   SIGNO_CASE(SIGLOST);
972 #endif
973
974 #ifdef SIGPWR
975 # if SIGPWR != SIGLOST
976   SIGNO_CASE(SIGPWR);
977 # endif
978 #endif
979
980 #ifdef SIGSYS
981   SIGNO_CASE(SIGSYS);
982 #endif
983
984   default: return "";
985   }
986 }
987
988
989 Local<Value> ErrnoException(int errorno,
990                             const char *syscall,
991                             const char *msg,
992                             const char *path) {
993   Local<Value> e;
994   Local<String> estring = String::NewSymbol(errno_string(errorno));
995   if (!msg[0]) {
996 #ifdef __POSIX__
997     msg = strerror(errorno);
998 #else // __MINGW32__
999     msg = winapi_strerror(errorno);
1000 #endif
1001   }
1002   Local<String> message = String::NewSymbol(msg);
1003
1004   Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
1005   Local<String> cons2 = String::Concat(cons1, message);
1006
1007   if (syscall_symbol.IsEmpty()) {
1008     syscall_symbol = NODE_PSYMBOL("syscall");
1009     errno_symbol = NODE_PSYMBOL("errno");
1010     errpath_symbol = NODE_PSYMBOL("path");
1011     code_symbol = NODE_PSYMBOL("code");
1012   }
1013
1014   if (path) {
1015     Local<String> cons3 = String::Concat(cons2, String::NewSymbol(" '"));
1016     Local<String> cons4 = String::Concat(cons3, String::New(path));
1017     Local<String> cons5 = String::Concat(cons4, String::NewSymbol("'"));
1018     e = Exception::Error(cons5);
1019   } else {
1020     e = Exception::Error(cons2);
1021   }
1022
1023   Local<Object> obj = e->ToObject();
1024
1025   obj->Set(errno_symbol, Integer::New(errorno));
1026   obj->Set(code_symbol, estring);
1027   if (path) obj->Set(errpath_symbol, String::New(path));
1028   if (syscall) obj->Set(syscall_symbol, String::NewSymbol(syscall));
1029   return e;
1030 }
1031
1032
1033 Handle<Value> FromConstructorTemplate(Persistent<FunctionTemplate>& t,
1034                                       const Arguments& args) {
1035   HandleScope scope;
1036
1037   const int argc = args.Length();
1038   Local<Value>* argv = new Local<Value>[argc];
1039
1040   for (int i = 0; i < argc; ++i) {
1041     argv[i] = args[i];
1042   }
1043
1044   Local<Object> instance = t->GetFunction()->NewInstance(argc, argv);
1045
1046   delete[] argv;
1047
1048   return scope.Close(instance);
1049 }
1050
1051
1052 // MakeCallback may only be made directly off the event loop.
1053 // That is there can be no JavaScript stack frames underneath it.
1054 // (Is there any way to assert that?)
1055 //
1056 // Maybe make this a method of a node::Handle super class
1057 //
1058 void MakeCallback(Handle<Object> object,
1059                   const char* method,
1060                   int argc,
1061                   Handle<Value> argv[]) {
1062   HandleScope scope;
1063
1064   Local<Value> callback_v = object->Get(String::New(method)); 
1065   if (!callback_v->IsFunction()) {
1066     fprintf(stderr, "method = %s", method);
1067   }
1068   assert(callback_v->IsFunction());
1069   Local<Function> callback = Local<Function>::Cast(callback_v);
1070
1071   // TODO Hook for long stack traces to be made here.
1072
1073   TryCatch try_catch;
1074
1075   callback->Call(object, argc, argv);
1076
1077   if (try_catch.HasCaught()) {
1078     FatalException(try_catch);
1079   }
1080 }
1081
1082
1083 void SetErrno(uv_err_t err) {
1084   HandleScope scope;
1085
1086   if (errno_symbol.IsEmpty()) {
1087     errno_symbol = NODE_PSYMBOL("errno");
1088   }
1089
1090   if (err.code == UV_UNKNOWN) {
1091     char errno_buf[100];
1092     snprintf(errno_buf, 100, "Unknown system errno %d", err.sys_errno_);
1093     Context::GetCurrent()->Global()->Set(errno_symbol, String::New(errno_buf));
1094   } else {
1095     Context::GetCurrent()->Global()->Set(errno_symbol,
1096                                          String::NewSymbol(uv_err_name(err)));
1097   }
1098 }
1099
1100
1101 enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
1102   HandleScope scope;
1103
1104   if (!encoding_v->IsString()) return _default;
1105
1106   String::Utf8Value encoding(encoding_v->ToString());
1107
1108   if (strcasecmp(*encoding, "utf8") == 0) {
1109     return UTF8;
1110   } else if (strcasecmp(*encoding, "utf-8") == 0) {
1111     return UTF8;
1112   } else if (strcasecmp(*encoding, "ascii") == 0) {
1113     return ASCII;
1114   } else if (strcasecmp(*encoding, "base64") == 0) {
1115     return BASE64;
1116   } else if (strcasecmp(*encoding, "ucs2") == 0) {
1117     return UCS2;
1118   } else if (strcasecmp(*encoding, "ucs-2") == 0) {
1119     return UCS2;
1120   } else if (strcasecmp(*encoding, "binary") == 0) {
1121     return BINARY;
1122   } else if (strcasecmp(*encoding, "hex") == 0) {
1123     return HEX;
1124   } else if (strcasecmp(*encoding, "raw") == 0) {
1125     fprintf(stderr, "'raw' (array of integers) has been removed. "
1126                     "Use 'binary'.\n");
1127     return BINARY;
1128   } else if (strcasecmp(*encoding, "raws") == 0) {
1129     fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
1130                     "Please update your code.\n");
1131     return BINARY;
1132   } else {
1133     return _default;
1134   }
1135 }
1136
1137 Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
1138   HandleScope scope;
1139
1140   if (!len) return scope.Close(String::Empty());
1141
1142   if (encoding == BINARY) {
1143     const unsigned char *cbuf = static_cast<const unsigned char*>(buf);
1144     uint16_t * twobytebuf = new uint16_t[len];
1145     for (size_t i = 0; i < len; i++) {
1146       // XXX is the following line platform independent?
1147       twobytebuf[i] = cbuf[i];
1148     }
1149     Local<String> chunk = String::New(twobytebuf, len);
1150     delete [] twobytebuf; // TODO use ExternalTwoByteString?
1151     return scope.Close(chunk);
1152   }
1153
1154   // utf8 or ascii encoding
1155   Local<String> chunk = String::New((const char*)buf, len);
1156   return scope.Close(chunk);
1157 }
1158
1159 // Returns -1 if the handle was not valid for decoding
1160 ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
1161   HandleScope scope;
1162
1163   if (val->IsArray()) {
1164     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
1165                     "Use 'binary'.\n");
1166     assert(0);
1167     return -1;
1168   }
1169
1170   Local<String> str = val->ToString();
1171
1172   if (encoding == UTF8) return str->Utf8Length();
1173   else if (encoding == UCS2) return str->Length() * 2;
1174   else if (encoding == HEX) return str->Length() / 2;
1175
1176   return str->Length();
1177 }
1178
1179 #ifndef MIN
1180 # define MIN(a, b) ((a) < (b) ? (a) : (b))
1181 #endif
1182
1183 // Returns number of bytes written.
1184 ssize_t DecodeWrite(char *buf,
1185                     size_t buflen,
1186                     v8::Handle<v8::Value> val,
1187                     enum encoding encoding) {
1188   HandleScope scope;
1189
1190   // XXX
1191   // A lot of improvement can be made here. See:
1192   // http://code.google.com/p/v8/issues/detail?id=270
1193   // http://groups.google.com/group/v8-dev/browse_thread/thread/dba28a81d9215291/ece2b50a3b4022c
1194   // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611
1195
1196   if (val->IsArray()) {
1197     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
1198                     "Use 'binary'.\n");
1199     assert(0);
1200     return -1;
1201   }
1202
1203   Local<String> str = val->ToString();
1204
1205   if (encoding == UTF8) {
1206     str->WriteUtf8(buf, buflen, NULL, String::HINT_MANY_WRITES_EXPECTED);
1207     return buflen;
1208   }
1209
1210   if (encoding == ASCII) {
1211     str->WriteAscii(buf, 0, buflen, String::HINT_MANY_WRITES_EXPECTED);
1212     return buflen;
1213   }
1214
1215   // THIS IS AWFUL!!! FIXME
1216
1217   assert(encoding == BINARY);
1218
1219   uint16_t * twobytebuf = new uint16_t[buflen];
1220
1221   str->Write(twobytebuf, 0, buflen, String::HINT_MANY_WRITES_EXPECTED);
1222
1223   for (size_t i = 0; i < buflen; i++) {
1224     unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
1225     buf[i] = b[0];
1226   }
1227
1228   delete [] twobytebuf;
1229
1230   return buflen;
1231 }
1232
1233
1234 void DisplayExceptionLine (TryCatch &try_catch) {
1235   HandleScope scope;
1236
1237   Handle<Message> message = try_catch.Message();
1238
1239   uv_tty_reset_mode();
1240
1241   fprintf(stderr, "\n");
1242
1243   if (!message.IsEmpty()) {
1244     // Print (filename):(line number): (message).
1245     String::Utf8Value filename(message->GetScriptResourceName());
1246     const char* filename_string = *filename;
1247     int linenum = message->GetLineNumber();
1248     fprintf(stderr, "%s:%i\n", filename_string, linenum);
1249     // Print line of source code.
1250     String::Utf8Value sourceline(message->GetSourceLine());
1251     const char* sourceline_string = *sourceline;
1252
1253     // HACK HACK HACK
1254     //
1255     // FIXME
1256     //
1257     // Because of how CommonJS modules work, all scripts are wrapped with a
1258     // "function (function (exports, __filename, ...) {"
1259     // to provide script local variables.
1260     //
1261     // When reporting errors on the first line of a script, this wrapper
1262     // function is leaked to the user. This HACK is to remove it. The length
1263     // of the wrapper is 62. That wrapper is defined in src/node.js
1264     //
1265     // If that wrapper is ever changed, then this number also has to be
1266     // updated. Or - someone could clean this up so that the two peices
1267     // don't need to be changed.
1268     //
1269     // Even better would be to get support into V8 for wrappers that
1270     // shouldn't be reported to users.
1271     int offset = linenum == 1 ? 62 : 0;
1272
1273     fprintf(stderr, "%s\n", sourceline_string + offset);
1274     // Print wavy underline (GetUnderline is deprecated).
1275     int start = message->GetStartColumn();
1276     for (int i = offset; i < start; i++) {
1277       fprintf(stderr, " ");
1278     }
1279     int end = message->GetEndColumn();
1280     for (int i = start; i < end; i++) {
1281       fprintf(stderr, "^");
1282     }
1283     fprintf(stderr, "\n");
1284   }
1285 }
1286
1287
1288 static void ReportException(TryCatch &try_catch, bool show_line) {
1289   HandleScope scope;
1290   Handle<Message> message = try_catch.Message();
1291
1292   if (show_line) DisplayExceptionLine(try_catch);
1293
1294   String::Utf8Value trace(try_catch.StackTrace());
1295
1296   // range errors have a trace member set to undefined
1297   if (trace.length() > 0 && !try_catch.StackTrace()->IsUndefined()) {
1298     fprintf(stderr, "%s\n", *trace);
1299   } else {
1300     // this really only happens for RangeErrors, since they're the only
1301     // kind that won't have all this info in the trace, or when non-Error
1302     // objects are thrown manually.
1303     Local<Value> er = try_catch.Exception();
1304     bool isErrorObject = er->IsObject() &&
1305       !(er->ToObject()->Get(String::New("message"))->IsUndefined()) &&
1306       !(er->ToObject()->Get(String::New("name"))->IsUndefined());
1307
1308     if (isErrorObject) {
1309       String::Utf8Value name(er->ToObject()->Get(String::New("name")));
1310       fprintf(stderr, "%s: ", *name);
1311     }
1312
1313     String::Utf8Value msg(!isErrorObject ? er->ToString()
1314                          : er->ToObject()->Get(String::New("message"))->ToString());
1315     fprintf(stderr, "%s\n", *msg);
1316   }
1317
1318   fflush(stderr);
1319 }
1320
1321 // Executes a str within the current v8 context.
1322 Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
1323   HandleScope scope;
1324   TryCatch try_catch;
1325
1326   Local<v8::Script> script = v8::Script::Compile(source, filename);
1327   if (script.IsEmpty()) {
1328     ReportException(try_catch, true);
1329     exit(1);
1330   }
1331
1332   Local<Value> result = script->Run();
1333   if (result.IsEmpty()) {
1334     ReportException(try_catch, true);
1335     exit(1);
1336   }
1337
1338   return scope.Close(result);
1339 }
1340
1341
1342 static Handle<Value> Chdir(const Arguments& args) {
1343   HandleScope scope;
1344
1345   if (args.Length() != 1 || !args[0]->IsString()) {
1346     return ThrowException(Exception::Error(String::New("Bad argument.")));
1347   }
1348
1349   String::Utf8Value path(args[0]->ToString());
1350
1351   int r = chdir(*path);
1352
1353   if (r != 0) {
1354     return ThrowException(Exception::Error(String::New(strerror(errno))));
1355   }
1356
1357   return Undefined();
1358 }
1359
1360 static Handle<Value> Cwd(const Arguments& args) {
1361   HandleScope scope;
1362   assert(args.Length() == 0);
1363
1364   char *r = getcwd(getbuf, ARRAY_SIZE(getbuf) - 1);
1365   if (r == NULL) {
1366     return ThrowException(Exception::Error(String::New(strerror(errno))));
1367   }
1368
1369   getbuf[ARRAY_SIZE(getbuf) - 1] = '\0';
1370   Local<String> cwd = String::New(r);
1371
1372   return scope.Close(cwd);
1373 }
1374
1375 static Handle<Value> Umask(const Arguments& args) {
1376   HandleScope scope;
1377   unsigned int old;
1378
1379   if (args.Length() < 1 || args[0]->IsUndefined()) {
1380     old = umask(0);
1381     umask((mode_t)old);
1382
1383   } else if(!args[0]->IsInt32() && !args[0]->IsString()) {
1384     return ThrowException(Exception::TypeError(
1385           String::New("argument must be an integer or octal string.")));
1386
1387   } else {
1388     int oct;
1389     if(args[0]->IsInt32()) {
1390       oct = args[0]->Uint32Value();
1391     } else {
1392       oct = 0;
1393       String::Utf8Value str(args[0]);
1394
1395       // Parse the octal string.
1396       for (int i = 0; i < str.length(); i++) {
1397         char c = (*str)[i];
1398         if (c > '7' || c < '0') {
1399           return ThrowException(Exception::TypeError(
1400                 String::New("invalid octal string")));
1401         }
1402         oct *= 8;
1403         oct += c - '0';
1404       }
1405     }
1406     old = umask(static_cast<mode_t>(oct));
1407   }
1408
1409   return scope.Close(Uint32::New(old));
1410 }
1411
1412
1413 #ifdef __POSIX__
1414
1415 static Handle<Value> GetUid(const Arguments& args) {
1416   HandleScope scope;
1417   assert(args.Length() == 0);
1418   int uid = getuid();
1419   return scope.Close(Integer::New(uid));
1420 }
1421
1422
1423 static Handle<Value> GetGid(const Arguments& args) {
1424   HandleScope scope;
1425   assert(args.Length() == 0);
1426   int gid = getgid();
1427   return scope.Close(Integer::New(gid));
1428 }
1429
1430
1431 static Handle<Value> SetGid(const Arguments& args) {
1432   HandleScope scope;
1433
1434   if (args.Length() < 1) {
1435     return ThrowException(Exception::Error(
1436       String::New("setgid requires 1 argument")));
1437   }
1438
1439   int gid;
1440
1441   if (args[0]->IsNumber()) {
1442     gid = args[0]->Int32Value();
1443   } else if (args[0]->IsString()) {
1444     String::Utf8Value grpnam(args[0]->ToString());
1445     struct group grp, *grpp = NULL;
1446     int err;
1447
1448     if ((err = getgrnam_r(*grpnam, &grp, getbuf, ARRAY_SIZE(getbuf), &grpp)) ||
1449         grpp == NULL) {
1450       if (errno == 0)
1451         return ThrowException(Exception::Error(
1452           String::New("setgid group id does not exist")));
1453       else
1454         return ThrowException(ErrnoException(errno, "getgrnam_r"));
1455     }
1456
1457     gid = grpp->gr_gid;
1458   } else {
1459     return ThrowException(Exception::Error(
1460       String::New("setgid argument must be a number or a string")));
1461   }
1462
1463   int result;
1464   if ((result = setgid(gid)) != 0) {
1465     return ThrowException(ErrnoException(errno, "setgid"));
1466   }
1467   return Undefined();
1468 }
1469
1470
1471 static Handle<Value> SetUid(const Arguments& args) {
1472   HandleScope scope;
1473
1474   if (args.Length() < 1) {
1475     return ThrowException(Exception::Error(
1476           String::New("setuid requires 1 argument")));
1477   }
1478
1479   int uid;
1480
1481   if (args[0]->IsNumber()) {
1482     uid = args[0]->Int32Value();
1483   } else if (args[0]->IsString()) {
1484     String::Utf8Value pwnam(args[0]->ToString());
1485     struct passwd pwd, *pwdp = NULL;
1486     int err;
1487
1488     if ((err = getpwnam_r(*pwnam, &pwd, getbuf, ARRAY_SIZE(getbuf), &pwdp)) ||
1489         pwdp == NULL) {
1490       if (errno == 0)
1491         return ThrowException(Exception::Error(
1492           String::New("setuid user id does not exist")));
1493       else
1494         return ThrowException(ErrnoException(errno, "getpwnam_r"));
1495     }
1496
1497     uid = pwdp->pw_uid;
1498   } else {
1499     return ThrowException(Exception::Error(
1500       String::New("setuid argument must be a number or a string")));
1501   }
1502
1503   int result;
1504   if ((result = setuid(uid)) != 0) {
1505     return ThrowException(ErrnoException(errno, "setuid"));
1506   }
1507   return Undefined();
1508 }
1509
1510
1511 #endif // __POSIX__
1512
1513
1514 v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
1515   HandleScope scope;
1516   exit(args[0]->IntegerValue());
1517   return Undefined();
1518 }
1519
1520
1521 static void CheckStatus(uv_timer_t* watcher, int status) {
1522   assert(watcher == &gc_timer);
1523
1524   // check memory
1525   if (!uv_is_active((uv_handle_t*) &gc_idle)) {
1526     HeapStatistics stats;
1527     V8::GetHeapStatistics(&stats);
1528     if (stats.total_heap_size() > 1024 * 1024 * 128) {
1529       // larger than 128 megs, just start the idle watcher
1530       uv_idle_start(&node::gc_idle, node::Idle);
1531       return;
1532     }
1533   }
1534
1535   double d = uv_now(uv_default_loop()) - TICK_TIME(3);
1536
1537   //printfb("timer d = %f\n", d);
1538
1539   if (d  >= GC_WAIT_TIME - 1.) {
1540     //fprintf(stderr, "start idle\n");
1541     uv_idle_start(&node::gc_idle, node::Idle);
1542   }
1543 }
1544
1545 static Handle<Value> Uptime(const Arguments& args) {
1546   HandleScope scope;
1547   assert(args.Length() == 0);
1548
1549   double uptime =  Platform::GetUptime(true);
1550
1551   if (uptime < 0) {
1552     return Undefined();
1553   }
1554
1555   return scope.Close(Number::New(uptime));
1556 }
1557
1558
1559 v8::Handle<v8::Value> UVCounters(const v8::Arguments& args) {
1560   HandleScope scope;
1561
1562   uv_counters_t* c = &uv_default_loop()->counters;
1563
1564   Local<Object> obj = Object::New();
1565
1566 #define setc(name) obj->Set(String::New(#name), Integer::New(c->name));
1567
1568   setc(eio_init)
1569   setc(req_init)
1570   setc(handle_init)
1571   setc(stream_init)
1572   setc(tcp_init)
1573   setc(udp_init)
1574   setc(pipe_init)
1575   setc(tty_init)
1576   setc(prepare_init)
1577   setc(check_init)
1578   setc(idle_init)
1579   setc(async_init)
1580   setc(timer_init)
1581   setc(process_init)
1582   setc(fs_event_init)
1583
1584 #undef setc
1585
1586   return scope.Close(obj);
1587 }
1588
1589
1590 v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) {
1591   HandleScope scope;
1592   assert(args.Length() == 0);
1593
1594   size_t rss;
1595
1596   int r = Platform::GetMemory(&rss);
1597
1598   if (r != 0) {
1599     return ThrowException(Exception::Error(String::New(strerror(errno))));
1600   }
1601
1602   Local<Object> info = Object::New();
1603
1604   if (rss_symbol.IsEmpty()) {
1605     rss_symbol = NODE_PSYMBOL("rss");
1606     heap_total_symbol = NODE_PSYMBOL("heapTotal");
1607     heap_used_symbol = NODE_PSYMBOL("heapUsed");
1608   }
1609
1610   info->Set(rss_symbol, Integer::NewFromUnsigned(rss));
1611
1612   // V8 memory usage
1613   HeapStatistics v8_heap_stats;
1614   V8::GetHeapStatistics(&v8_heap_stats);
1615   info->Set(heap_total_symbol,
1616             Integer::NewFromUnsigned(v8_heap_stats.total_heap_size()));
1617   info->Set(heap_used_symbol,
1618             Integer::NewFromUnsigned(v8_heap_stats.used_heap_size()));
1619
1620   return scope.Close(info);
1621 }
1622
1623
1624 #ifdef __POSIX__
1625
1626 Handle<Value> Kill(const Arguments& args) {
1627   HandleScope scope;
1628
1629   if (args.Length() != 2) {
1630     return ThrowException(Exception::Error(String::New("Bad argument.")));
1631   }
1632
1633   pid_t pid = args[0]->IntegerValue();
1634   int sig = args[1]->Int32Value();
1635   int r = kill(pid, sig);
1636
1637   if (r != 0) return ThrowException(ErrnoException(errno, "kill"));
1638
1639   return Undefined();
1640 }
1641
1642
1643 typedef void (*extInit)(Handle<Object> exports);
1644
1645 // DLOpen is node.dlopen(). Used to load 'module.node' dynamically shared
1646 // objects.
1647 Handle<Value> DLOpen(const v8::Arguments& args) {
1648   node_module_struct compat_mod;
1649   HandleScope scope;
1650
1651   if (args.Length() < 2) return Undefined();
1652
1653   String::Utf8Value filename(args[0]->ToString()); // Cast
1654   Local<Object> target = args[1]->ToObject(); // Cast
1655
1656   // Actually call dlopen().
1657   // FIXME: This is a blocking function and should be called asynchronously!
1658   // This function should be moved to file.cc and use libeio to make this
1659   // system call.
1660   void *handle = dlopen(*filename, RTLD_LAZY);
1661
1662   // Handle errors.
1663   if (handle == NULL) {
1664     Local<Value> exception = Exception::Error(String::New(dlerror()));
1665     return ThrowException(exception);
1666   }
1667
1668   String::Utf8Value symbol(args[0]->ToString());
1669   char *symstr = NULL;
1670   {
1671     char *sym = *symbol;
1672     char *p = strrchr(sym, '/');
1673     if (p != NULL) {
1674       sym = p+1;
1675     }
1676
1677     p = strrchr(sym, '.');
1678     if (p != NULL) {
1679       *p = '\0';
1680     }
1681
1682     size_t slen = strlen(sym);
1683     symstr = static_cast<char*>(calloc(1, slen + sizeof("_module") + 1));
1684     memcpy(symstr, sym, slen);
1685     memcpy(symstr+slen, "_module", sizeof("_module") + 1);
1686   }
1687
1688   // Get the init() function from the dynamically shared object.
1689   node_module_struct *mod = static_cast<node_module_struct *>(dlsym(handle, symstr));
1690   free(symstr);
1691   symstr = NULL;
1692
1693   // Error out if not found.
1694   if (mod == NULL) {
1695     /* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */
1696     memset(&compat_mod, 0, sizeof compat_mod);
1697
1698     mod = &compat_mod;
1699     mod->version = NODE_MODULE_VERSION;
1700
1701     void *init_handle = dlsym(handle, "init");
1702     if (init_handle == NULL) {
1703       dlclose(handle);
1704       Local<Value> exception =
1705         Exception::Error(String::New("No module symbol found in module."));
1706       return ThrowException(exception);
1707     }
1708     mod->register_func = (extInit)(init_handle);
1709     /* End Compatibility hack */
1710   }
1711
1712   if (mod->version != NODE_MODULE_VERSION) {
1713     Local<Value> exception =
1714       Exception::Error(String::New("Module version mismatch, refusing to load."));
1715     return ThrowException(exception);
1716   }
1717
1718   // Execute the C++ module
1719   mod->register_func(target);
1720
1721   // Tell coverity that 'handle' should not be freed when we return.
1722   // coverity[leaked_storage]
1723   return Undefined();
1724 }
1725
1726 #endif // __POSIX__
1727
1728
1729 // TODO remove me before 0.4
1730 Handle<Value> Compile(const Arguments& args) {
1731   HandleScope scope;
1732
1733
1734   if (args.Length() < 2) {
1735     return ThrowException(Exception::TypeError(
1736           String::New("needs two arguments.")));
1737   }
1738
1739   static bool shown_error_message = false;
1740
1741   if (!shown_error_message) {
1742     shown_error_message = true;
1743     fprintf(stderr, "(node) process.compile should not be used. "
1744                     "Use require('vm').runInThisContext instead.\n");
1745   }
1746
1747   Local<String> source = args[0]->ToString();
1748   Local<String> filename = args[1]->ToString();
1749
1750   TryCatch try_catch;
1751
1752   Local<v8::Script> script = v8::Script::Compile(source, filename);
1753   if (try_catch.HasCaught()) {
1754     // Hack because I can't get a proper stacktrace on SyntaxError
1755     ReportException(try_catch, true);
1756     exit(1);
1757   }
1758
1759   Local<Value> result = script->Run();
1760   if (try_catch.HasCaught()) {
1761     ReportException(try_catch, false);
1762     exit(1);
1763   }
1764
1765   return scope.Close(result);
1766 }
1767
1768 static void OnFatalError(const char* location, const char* message) {
1769   if (location) {
1770     fprintf(stderr, "FATAL ERROR: %s %s\n", location, message);
1771   } else {
1772     fprintf(stderr, "FATAL ERROR: %s\n", message);
1773   }
1774   exit(1);
1775 }
1776
1777 static int uncaught_exception_counter = 0;
1778
1779 void FatalException(TryCatch &try_catch) {
1780   HandleScope scope;
1781
1782   // Check if uncaught_exception_counter indicates a recursion
1783   if (uncaught_exception_counter > 0) {
1784     ReportException(try_catch, true);
1785     exit(1);
1786   }
1787
1788   if (listeners_symbol.IsEmpty()) {
1789     listeners_symbol = NODE_PSYMBOL("listeners");
1790     uncaught_exception_symbol = NODE_PSYMBOL("uncaughtException");
1791     emit_symbol = NODE_PSYMBOL("emit");
1792   }
1793
1794   Local<Value> listeners_v = process->Get(listeners_symbol);
1795   assert(listeners_v->IsFunction());
1796
1797   Local<Function> listeners = Local<Function>::Cast(listeners_v);
1798
1799   Local<String> uncaught_exception_symbol_l = Local<String>::New(uncaught_exception_symbol);
1800   Local<Value> argv[1] = { uncaught_exception_symbol_l  };
1801   Local<Value> ret = listeners->Call(process, 1, argv);
1802
1803   assert(ret->IsArray());
1804
1805   Local<Array> listener_array = Local<Array>::Cast(ret);
1806
1807   uint32_t length = listener_array->Length();
1808   // Report and exit if process has no "uncaughtException" listener
1809   if (length == 0) {
1810     ReportException(try_catch, true);
1811     exit(1);
1812   }
1813
1814   // Otherwise fire the process "uncaughtException" event
1815   Local<Value> emit_v = process->Get(emit_symbol);
1816   assert(emit_v->IsFunction());
1817
1818   Local<Function> emit = Local<Function>::Cast(emit_v);
1819
1820   Local<Value> error = try_catch.Exception();
1821   Local<Value> event_argv[2] = { uncaught_exception_symbol_l, error };
1822
1823   uncaught_exception_counter++;
1824   emit->Call(process, 2, event_argv);
1825   // Decrement so we know if the next exception is a recursion or not
1826   uncaught_exception_counter--;
1827 }
1828
1829
1830 static uv_async_t debug_watcher;
1831
1832 static void DebugMessageCallback(uv_async_t* watcher, int status) {
1833   HandleScope scope;
1834   assert(watcher == &debug_watcher);
1835   Debug::ProcessDebugMessages();
1836 }
1837
1838 static void DebugMessageDispatch(void) {
1839   // This function is called from V8's debug thread when a debug TCP client
1840   // has sent a message.
1841
1842   // Send a signal to our main thread saying that it should enter V8 to
1843   // handle the message.
1844   uv_async_send(&debug_watcher);
1845 }
1846
1847 static void DebugBreakMessageHandler(const Debug::Message& message) {
1848   // do nothing with debug messages.
1849   // The message handler will get changed by DebuggerAgent::CreateSession in
1850   // debug-agent.cc of v8/src when a new session is created
1851 }
1852
1853
1854 Persistent<Object> binding_cache;
1855 Persistent<Array> module_load_list;
1856
1857 static Handle<Value> Binding(const Arguments& args) {
1858   HandleScope scope;
1859
1860   Local<String> module = args[0]->ToString();
1861   String::Utf8Value module_v(module);
1862   node_module_struct* modp;
1863
1864   if (binding_cache.IsEmpty()) {
1865     binding_cache = Persistent<Object>::New(Object::New());
1866   }
1867
1868   Local<Object> exports;
1869
1870   if (binding_cache->Has(module)) {
1871     exports = binding_cache->Get(module)->ToObject();
1872     return scope.Close(exports);
1873   }
1874
1875   // Append a string to process.moduleLoadList
1876   char buf[1024];
1877   snprintf(buf, 1024, "Binding %s", *module_v);
1878   uint32_t l = module_load_list->Length();
1879   module_load_list->Set(l, String::New(buf));
1880
1881   if ((modp = get_builtin_module(*module_v)) != NULL) {
1882     exports = Object::New();
1883     modp->register_func(exports);
1884     binding_cache->Set(module, exports);
1885
1886   } else if (!strcmp(*module_v, "constants")) {
1887     exports = Object::New();
1888     DefineConstants(exports);
1889     binding_cache->Set(module, exports);
1890
1891 #ifdef __POSIX__
1892   } else if (!strcmp(*module_v, "io_watcher")) {
1893     exports = Object::New();
1894     IOWatcher::Initialize(exports);
1895     binding_cache->Set(module, exports);
1896 #endif
1897
1898   } else if (!strcmp(*module_v, "natives")) {
1899     exports = Object::New();
1900     DefineJavaScript(exports);
1901     binding_cache->Set(module, exports);
1902
1903   } else {
1904
1905     return ThrowException(Exception::Error(String::New("No such module")));
1906   }
1907
1908   return scope.Close(exports);
1909 }
1910
1911
1912 static Handle<Value> ProcessTitleGetter(Local<String> property,
1913                                         const AccessorInfo& info) {
1914   HandleScope scope;
1915   int len;
1916   const char *s = Platform::GetProcessTitle(&len);
1917   return scope.Close(s ? String::New(s, len) : String::Empty());
1918 }
1919
1920
1921 static void ProcessTitleSetter(Local<String> property,
1922                                Local<Value> value,
1923                                const AccessorInfo& info) {
1924   HandleScope scope;
1925   String::Utf8Value title(value->ToString());
1926   Platform::SetProcessTitle(*title);
1927 }
1928
1929
1930 static Handle<Value> EnvGetter(Local<String> property,
1931                                const AccessorInfo& info) {
1932   String::Utf8Value key(property);
1933   const char* val = getenv(*key);
1934   if (val) {
1935     HandleScope scope;
1936     return scope.Close(String::New(val));
1937   }
1938   return Undefined();
1939 }
1940
1941
1942 static Handle<Value> EnvSetter(Local<String> property,
1943                                Local<Value> value,
1944                                const AccessorInfo& info) {
1945   HandleScope scope;
1946   String::Utf8Value key(property);
1947   String::Utf8Value val(value);
1948
1949 #ifdef __POSIX__
1950   setenv(*key, *val, 1);
1951 #else  // __WIN32__
1952   int n = key.length() + val.length() + 2;
1953   char* pair = new char[n];
1954   snprintf(pair, n, "%s=%s", *key, *val);
1955   int r = _putenv(pair);
1956   if (r) {
1957     fprintf(stderr, "error putenv: '%s'\n", pair);
1958   }
1959   delete [] pair;
1960 #endif
1961
1962   return value;
1963 }
1964
1965
1966 static Handle<Integer> EnvQuery(Local<String> property,
1967                                 const AccessorInfo& info) {
1968   String::Utf8Value key(property);
1969   if (getenv(*key)) {
1970     HandleScope scope;
1971     return scope.Close(Integer::New(None));
1972   }
1973   return Handle<Integer>();
1974 }
1975
1976
1977 static Handle<Boolean> EnvDeleter(Local<String> property,
1978                                   const AccessorInfo& info) {
1979   HandleScope scope;
1980
1981   String::Utf8Value key(property);
1982
1983   if (getenv(*key)) {
1984 #ifdef __POSIX__
1985     unsetenv(*key);     // prototyped as `void unsetenv(const char*)` on some platforms
1986 #else
1987     int n = key.length() + 2;
1988     char* pair = new char[n];
1989     snprintf(pair, n, "%s=", *key);
1990     int r = _putenv(pair);
1991     if (r) {
1992       fprintf(stderr, "error unsetenv: '%s'\n", pair);
1993     }
1994     delete [] pair;
1995 #endif
1996     return True();
1997   }
1998
1999   return False();
2000 }
2001
2002
2003 static Handle<Array> EnvEnumerator(const AccessorInfo& info) {
2004   HandleScope scope;
2005
2006   int size = 0;
2007   while (environ[size]) size++;
2008
2009   Local<Array> env = Array::New(size);
2010
2011   for (int i = 0; i < size; ++i) {
2012     const char* var = environ[i];
2013     const char* s = strchr(var, '=');
2014     const int length = s ? s - var : strlen(var);
2015     env->Set(i, String::New(var, length));
2016   }
2017
2018   return scope.Close(env);
2019 }
2020
2021
2022 static Handle<Object> GetFeatures() {
2023   HandleScope scope;
2024
2025   Local<Object> obj = Object::New();
2026   obj->Set(String::NewSymbol("debug"),
2027 #if defined(DEBUG) && DEBUG
2028     True()
2029 #else
2030     False()
2031 #endif
2032   );
2033
2034   obj->Set(String::NewSymbol("uv"), True());
2035   obj->Set(String::NewSymbol("ipv6"), True()); // TODO ping libuv
2036   obj->Set(String::NewSymbol("tls_npn"), Boolean::New(use_npn));
2037   obj->Set(String::NewSymbol("tls_sni"), Boolean::New(use_sni));
2038   obj->Set(String::NewSymbol("tls"),
2039       Boolean::New(get_builtin_module("crypto") != NULL));
2040
2041   return scope.Close(obj);
2042 }
2043
2044
2045 Handle<Object> SetupProcessObject(int argc, char *argv[]) {
2046   HandleScope scope;
2047
2048   int i, j;
2049
2050   Local<FunctionTemplate> process_template = FunctionTemplate::New();
2051
2052   process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());
2053
2054
2055   process->SetAccessor(String::New("title"),
2056                        ProcessTitleGetter,
2057                        ProcessTitleSetter);
2058
2059   // process.version
2060   process->Set(String::NewSymbol("version"), String::New(NODE_VERSION));
2061
2062 #ifdef NODE_PREFIX
2063   // process.installPrefix
2064   process->Set(String::NewSymbol("installPrefix"), String::New(NODE_PREFIX));
2065 #endif
2066
2067   // process.moduleLoadList
2068   module_load_list = Persistent<Array>::New(Array::New());
2069   process->Set(String::NewSymbol("moduleLoadList"), module_load_list);
2070
2071   Local<Object> versions = Object::New();
2072   char buf[20];
2073   process->Set(String::NewSymbol("versions"), versions);
2074   // +1 to get rid of the leading 'v'
2075   versions->Set(String::NewSymbol("node"), String::New(NODE_VERSION+1));
2076   versions->Set(String::NewSymbol("v8"), String::New(V8::GetVersion()));
2077   versions->Set(String::NewSymbol("ares"), String::New(ARES_VERSION_STR));
2078   snprintf(buf, 20, "%d.%d", UV_VERSION_MAJOR, UV_VERSION_MINOR);
2079   versions->Set(String::NewSymbol("uv"), String::New(buf));
2080 #if HAVE_OPENSSL
2081   // Stupid code to slice out the version string.
2082   int c, l = strlen(OPENSSL_VERSION_TEXT);
2083   for (i = j = 0; i < l; i++) {
2084     c = OPENSSL_VERSION_TEXT[i];
2085     if ('0' <= c && c <= '9') {
2086       for (j = i + 1; j < l; j++) {
2087         c = OPENSSL_VERSION_TEXT[j];
2088         if (c == ' ') break;
2089       }
2090       break;
2091     }
2092   }
2093   versions->Set(String::NewSymbol("openssl"),
2094                 String::New(OPENSSL_VERSION_TEXT + i, j - i));
2095 #endif
2096
2097
2098
2099   // process.arch
2100   process->Set(String::NewSymbol("arch"), String::New(ARCH));
2101
2102   // process.platform
2103   process->Set(String::NewSymbol("platform"), String::New(PLATFORM));
2104
2105   // process.argv
2106   Local<Array> arguments = Array::New(argc - option_end_index + 1);
2107   arguments->Set(Integer::New(0), String::New(argv[0]));
2108   for (j = 1, i = option_end_index; i < argc; j++, i++) {
2109     Local<String> arg = String::New(argv[i]);
2110     arguments->Set(Integer::New(j), arg);
2111   }
2112   // assign it
2113   process->Set(String::NewSymbol("argv"), arguments);
2114
2115   // create process.env
2116   Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
2117   envTemplate->SetNamedPropertyHandler(EnvGetter,
2118                                        EnvSetter,
2119                                        EnvQuery,
2120                                        EnvDeleter,
2121                                        EnvEnumerator,
2122                                        Undefined());
2123   Local<Object> env = envTemplate->NewInstance();
2124   process->Set(String::NewSymbol("env"), env);
2125
2126   process->Set(String::NewSymbol("pid"), Integer::New(getpid()));
2127   process->Set(String::NewSymbol("features"), GetFeatures());
2128
2129   // -e, --eval
2130   if (eval_string) {
2131     process->Set(String::NewSymbol("_eval"), String::New(eval_string));
2132   }
2133
2134   size_t size = 2*PATH_MAX;
2135   char* execPath = new char[size];
2136   if (uv_exepath(execPath, &size) != 0) {
2137     // as a last ditch effort, fallback on argv[0] ?
2138     process->Set(String::NewSymbol("execPath"), String::New(argv[0]));
2139   } else {
2140     process->Set(String::NewSymbol("execPath"), String::New(execPath, size));
2141   }
2142   delete [] execPath;
2143
2144
2145   // define various internal methods
2146   NODE_SET_METHOD(process, "compile", Compile);
2147   NODE_SET_METHOD(process, "_needTickCallback", NeedTickCallback);
2148   NODE_SET_METHOD(process, "reallyExit", Exit);
2149   NODE_SET_METHOD(process, "chdir", Chdir);
2150   NODE_SET_METHOD(process, "cwd", Cwd);
2151
2152   NODE_SET_METHOD(process, "umask", Umask);
2153
2154 #ifdef __POSIX__
2155   NODE_SET_METHOD(process, "getuid", GetUid);
2156   NODE_SET_METHOD(process, "setuid", SetUid);
2157
2158   NODE_SET_METHOD(process, "setgid", SetGid);
2159   NODE_SET_METHOD(process, "getgid", GetGid);
2160
2161   NODE_SET_METHOD(process, "dlopen", DLOpen);
2162   NODE_SET_METHOD(process, "_kill", Kill);
2163 #endif // __POSIX__
2164
2165   NODE_SET_METHOD(process, "uptime", Uptime);
2166   NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
2167   NODE_SET_METHOD(process, "uvCounters", UVCounters);
2168
2169   NODE_SET_METHOD(process, "binding", Binding);
2170
2171   return process;
2172 }
2173
2174
2175 static void AtExit() {
2176   uv_tty_reset_mode();
2177 }
2178
2179
2180 static void SignalExit(int signal) {
2181   uv_tty_reset_mode();
2182   _exit(1);
2183 }
2184
2185
2186 void Load(Handle<Object> process) {
2187   // Compile, execute the src/node.js file. (Which was included as static C
2188   // string in node_natives.h. 'natve_node' is the string containing that
2189   // source code.)
2190
2191   // The node.js file returns a function 'f'
2192
2193   atexit(AtExit);
2194
2195   TryCatch try_catch;
2196
2197   Local<Value> f_value = ExecuteString(MainSource(),
2198                                        IMMUTABLE_STRING("node.js"));
2199   if (try_catch.HasCaught())  {
2200     ReportException(try_catch, true);
2201     exit(10);
2202   }
2203   assert(f_value->IsFunction());
2204   Local<Function> f = Local<Function>::Cast(f_value);
2205
2206   // Now we call 'f' with the 'process' variable that we've built up with
2207   // all our bindings. Inside node.js we'll take care of assigning things to
2208   // their places.
2209
2210   // We start the process this way in order to be more modular. Developers
2211   // who do not like how 'src/node.js' setups the module system but do like
2212   // Node's I/O bindings may want to replace 'f' with their own function.
2213
2214   // Add a reference to the global object
2215   Local<Object> global = v8::Context::GetCurrent()->Global();
2216   Local<Value> args[1] = { Local<Value>::New(process) };
2217
2218 #ifdef HAVE_DTRACE
2219   InitDTrace(global);
2220 #endif
2221
2222   f->Call(global, 1, args);
2223
2224   if (try_catch.HasCaught())  {
2225     ReportException(try_catch, true);
2226     exit(11);
2227   }
2228 }
2229
2230 static void PrintHelp();
2231
2232 static void ParseDebugOpt(const char* arg) {
2233   const char *p = 0;
2234
2235   use_debug_agent = true;
2236   if (!strcmp (arg, "--debug-brk")) {
2237     debug_wait_connect = true;
2238     return;
2239   } else if (!strcmp(arg, "--debug")) {
2240     return;
2241   } else if (strstr(arg, "--debug-brk=") == arg) {
2242     debug_wait_connect = true;
2243     p = 1 + strchr(arg, '=');
2244     debug_port = atoi(p);
2245   } else if (strstr(arg, "--debug=") == arg) {
2246     p = 1 + strchr(arg, '=');
2247     debug_port = atoi(p);
2248   }
2249   if (p && debug_port > 1024 && debug_port <  65536)
2250       return;
2251
2252   fprintf(stderr, "Bad debug option.\n");
2253   if (p) fprintf(stderr, "Debug port must be in range 1025 to 65535.\n");
2254
2255   PrintHelp();
2256   exit(1);
2257 }
2258
2259 static void PrintHelp() {
2260   printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
2261          "       node debug script.js [arguments] \n"
2262          "       node cluster script.js [arguments] \n"
2263          "\n"
2264          "Options:\n"
2265          "  -v, --version        print node's version\n"
2266          "  -e, --eval script    evaluate script\n"
2267          "  --v8-options         print v8 command line options\n"
2268          "  --vars               print various compiled-in variables\n"
2269          "  --max-stack-size=val set max v8 stack size (bytes)\n"
2270          "\n"
2271          "Enviromental variables:\n"
2272          "NODE_PATH              ':'-separated list of directories\n"
2273          "                       prefixed to the module search path.\n"
2274          "NODE_MODULE_CONTEXTS   Set to 1 to load modules in their own\n"
2275          "                       global contexts.\n"
2276          "NODE_DISABLE_COLORS    Set to 1 to disable colors in the REPL\n"
2277          "\n"
2278          "Documentation can be found at http://nodejs.org/\n");
2279 }
2280
2281 // Parse node command line arguments.
2282 static void ParseArgs(int argc, char **argv) {
2283   int i;
2284
2285   // TODO use parse opts
2286   for (i = 1; i < argc; i++) {
2287     const char *arg = argv[i];
2288     if (strstr(arg, "--debug") == arg) {
2289       ParseDebugOpt(arg);
2290       argv[i] = const_cast<char*>("");
2291     } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
2292       printf("%s\n", NODE_VERSION);
2293       exit(0);
2294     } else if (strcmp(arg, "--vars") == 0) {
2295 #ifdef NODE_PREFIX
2296       printf("NODE_PREFIX: %s\n", NODE_PREFIX);
2297 #endif
2298 #ifdef NODE_CFLAGS
2299       printf("NODE_CFLAGS: %s\n", NODE_CFLAGS);
2300 #endif
2301       exit(0);
2302     } else if (strstr(arg, "--max-stack-size=") == arg) {
2303       const char *p = 0;
2304       p = 1 + strchr(arg, '=');
2305       max_stack_size = atoi(p);
2306       argv[i] = const_cast<char*>("");
2307     } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
2308       PrintHelp();
2309       exit(0);
2310     } else if (strcmp(arg, "--eval") == 0 || strcmp(arg, "-e") == 0) {
2311       if (argc <= i + 1) {
2312         fprintf(stderr, "Error: --eval requires an argument\n");
2313         exit(1);
2314       }
2315       argv[i] = const_cast<char*>("");
2316       eval_string = argv[++i];
2317     } else if (strcmp(arg, "--v8-options") == 0) {
2318       argv[i] = const_cast<char*>("--help");
2319     } else if (argv[i][0] != '-') {
2320       break;
2321     }
2322   }
2323
2324   option_end_index = i;
2325 }
2326
2327 static volatile bool debugger_running = false;
2328
2329 static void EnableDebug(bool wait_connect) {
2330   // Start the debug thread and it's associated TCP server on port 5858.
2331   bool r = Debug::EnableAgent("node " NODE_VERSION, debug_port);
2332
2333   if (wait_connect) {
2334     // Set up an empty handler so v8 will not continue until a debugger
2335     // attaches. This is the same behavior as Debug::EnableAgent(_,_,true)
2336     // except we don't break at the beginning of the script.
2337     // see Debugger::StartAgent in debug.cc of v8/src
2338     Debug::SetMessageHandler2(node::DebugBreakMessageHandler);
2339   }
2340
2341   // Crappy check that everything went well. FIXME
2342   assert(r);
2343
2344   // Print out some information.
2345   fprintf(stderr, "debugger listening on port %d\n", debug_port);
2346
2347   debugger_running = true;
2348 }
2349
2350
2351 #ifdef __POSIX__
2352 static void EnableDebugSignalHandler(int signal) {
2353   // Break once process will return execution to v8
2354   v8::Debug::DebugBreak();
2355
2356   if (!debugger_running) {
2357     fprintf(stderr, "Hit SIGUSR1 - starting debugger agent.\n");
2358     EnableDebug(false);
2359   }
2360 }
2361 #endif // __POSIX__
2362
2363 #if defined(__MINGW32__) || defined(_MSC_VER)
2364 static bool EnableDebugSignalHandler(DWORD signal) {
2365   if (signal == CTRL_C_EVENT) exit(1);
2366   if (signal != CTRL_BREAK_EVENT) return false;
2367
2368   // Break once process will return execution to v8
2369   v8::Debug::DebugBreak();
2370
2371   if (!debugger_running) {
2372     fprintf(stderr, "Hit Ctrl+Break - starting debugger agent.\n");
2373     EnableDebug(false);
2374     return true;
2375   } else {
2376     // Run default system action (terminate)
2377     return false;
2378   }
2379
2380 }
2381 #endif
2382
2383
2384 #ifdef __POSIX__
2385
2386 static int RegisterSignalHandler(int signal, void (*handler)(int)) {
2387   struct sigaction sa;
2388
2389   memset(&sa, 0, sizeof(sa));
2390   sa.sa_handler = handler;
2391   sigfillset(&sa.sa_mask);
2392   return sigaction(signal, &sa, NULL);
2393 }
2394 #endif // __POSIX__
2395
2396
2397 char** Init(int argc, char *argv[]) {
2398   // Hack aroung with the argv pointer. Used for process.title = "blah".
2399   argv = node::Platform::SetupArgs(argc, argv);
2400
2401   // Parse a few arguments which are specific to Node.
2402   node::ParseArgs(argc, argv);
2403   // Parse the rest of the args (up to the 'option_end_index' (where '--' was
2404   // in the command line))
2405   int v8argc = node::option_end_index;
2406   char **v8argv = argv;
2407
2408   if (node::debug_wait_connect) {
2409     // v8argv is a copy of argv up to the script file argument +2 if --debug-brk
2410     // to expose the v8 debugger js object so that node.js can set
2411     // a breakpoint on the first line of the startup script
2412     v8argc += 2;
2413     v8argv = new char*[v8argc];
2414     memcpy(v8argv, argv, sizeof(argv) * node::option_end_index);
2415     v8argv[node::option_end_index] = const_cast<char*>("--expose_debug_as");
2416     v8argv[node::option_end_index + 1] = const_cast<char*>("v8debug");
2417   }
2418
2419   // For the normal stack which moves from high to low addresses when frames
2420   // are pushed, we can compute the limit as stack_size bytes below the
2421   // the address of a stack variable (e.g. &stack_var) as an approximation
2422   // of the start of the stack (we're assuming that we haven't pushed a lot
2423   // of frames yet).
2424   if (node::max_stack_size != 0) {
2425     uint32_t stack_var;
2426     ResourceConstraints constraints;
2427
2428     uint32_t *stack_limit = &stack_var - (node::max_stack_size / sizeof(uint32_t));
2429     constraints.set_stack_limit(stack_limit);
2430     SetResourceConstraints(&constraints); // Must be done before V8::Initialize
2431   }
2432   V8::SetFlagsFromCommandLine(&v8argc, v8argv, false);
2433
2434 #ifdef __POSIX__
2435   // Ignore SIGPIPE
2436   RegisterSignalHandler(SIGPIPE, SIG_IGN);
2437   RegisterSignalHandler(SIGINT, SignalExit);
2438   RegisterSignalHandler(SIGTERM, SignalExit);
2439 #endif // __POSIX__
2440
2441   uv_prepare_init(uv_default_loop(), &node::prepare_tick_watcher);
2442   uv_prepare_start(&node::prepare_tick_watcher, PrepareTick);
2443   uv_unref(uv_default_loop());
2444
2445   uv_check_init(uv_default_loop(), &node::check_tick_watcher);
2446   uv_check_start(&node::check_tick_watcher, node::CheckTick);
2447   uv_unref(uv_default_loop());
2448
2449   uv_idle_init(uv_default_loop(), &node::tick_spinner);
2450   uv_unref(uv_default_loop());
2451
2452   uv_check_init(uv_default_loop(), &node::gc_check);
2453   uv_check_start(&node::gc_check, node::Check);
2454   uv_unref(uv_default_loop());
2455
2456   uv_idle_init(uv_default_loop(), &node::gc_idle);
2457   uv_unref(uv_default_loop());
2458
2459   uv_timer_init(uv_default_loop(), &node::gc_timer);
2460   uv_unref(uv_default_loop());
2461
2462   V8::SetFatalErrorHandler(node::OnFatalError);
2463
2464
2465   // Set the callback DebugMessageDispatch which is called from the debug
2466   // thread.
2467   Debug::SetDebugMessageDispatchHandler(node::DebugMessageDispatch);
2468   // Initialize the async watcher. DebugMessageCallback() is called from the
2469   // main thread to execute a random bit of javascript - which will give V8
2470   // control so it can handle whatever new message had been received on the
2471   // debug thread.
2472   uv_async_init(uv_default_loop(), &node::debug_watcher,
2473       node::DebugMessageCallback);
2474   // unref it so that we exit the event loop despite it being active.
2475   uv_unref(uv_default_loop());
2476
2477
2478   // If the --debug flag was specified then initialize the debug thread.
2479   if (node::use_debug_agent) {
2480     EnableDebug(debug_wait_connect);
2481   } else {
2482 #ifdef __POSIX__
2483     RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler);
2484 #endif // __POSIX__
2485 #if defined(__MINGW32__) || defined(_MSC_VER)
2486     SetConsoleCtrlHandler((PHANDLER_ROUTINE) EnableDebugSignalHandler, TRUE);
2487 #endif
2488   }
2489
2490   return argv;
2491 }
2492
2493
2494 void EmitExit(v8::Handle<v8::Object> process) {
2495   // process.emit('exit')
2496   Local<Value> emit_v = process->Get(String::New("emit"));
2497   assert(emit_v->IsFunction());
2498   Local<Function> emit = Local<Function>::Cast(emit_v);
2499   Local<Value> args[] = { String::New("exit") };
2500   TryCatch try_catch;
2501   emit->Call(process, 1, args);
2502   if (try_catch.HasCaught()) {
2503     FatalException(try_catch);
2504   }
2505 }
2506
2507
2508 int Start(int argc, char *argv[]) {
2509   // This needs to run *before* V8::Initialize()
2510   argv = Init(argc, argv);
2511
2512   v8::V8::Initialize();
2513   v8::HandleScope handle_scope;
2514
2515   // Create the one and only Context.
2516   Persistent<v8::Context> context = v8::Context::New();
2517   v8::Context::Scope context_scope(context);
2518
2519   Handle<Object> process = SetupProcessObject(argc, argv);
2520   v8_typed_array::AttachBindings(context->Global());
2521
2522   // Create all the objects, load modules, do everything.
2523   // so your next reading stop should be node::Load()!
2524   Load(process);
2525
2526   // All our arguments are loaded. We've evaluated all of the scripts. We
2527   // might even have created TCP servers. Now we enter the main eventloop. If
2528   // there are no watchers on the loop (except for the ones that were
2529   // uv_unref'd) then this function exits. As long as there are active
2530   // watchers, it blocks.
2531   uv_run(uv_default_loop());
2532
2533   EmitExit(process);
2534
2535 #ifndef NDEBUG
2536   // Clean up.
2537   context.Dispose();
2538   V8::Dispose();
2539 #endif  // NDEBUG
2540
2541   return 0;
2542 }
2543
2544
2545 }  // namespace node