#include <stdio.h>
#include <stdlib.h>
+#include <strings.h>
#include <string.h>
#include <limits.h> /* PATH_MAX */
#include <assert.h>
#include <node_net2.h>
#include <node_events.h>
#include <node_cares.h>
-#include <node_net.h>
#include <node_file.h>
#if 0
// not in use
# include <node_idle_watcher.h>
#endif
-#include <node_http.h>
#include <node_http_parser.h>
#include <node_signal_watcher.h>
#include <node_stat_watcher.h>
#include <node_stdio.h>
#include <node_natives.h>
#include <node_version.h>
+#ifdef HAVE_OPENSSL
+#include <node_crypto.h>
+#endif
+#include <node_script.h>
#include <v8-debug.h>
static Persistent<Object> process;
+static Persistent<String> errno_symbol;
+static Persistent<String> syscall_symbol;
+
static Persistent<String> dev_symbol;
static Persistent<String> ino_symbol;
static Persistent<String> mode_symbol;
// true if the heap hasn't be fully compacted, and needs to be run again.
// Returning false means that it doesn't have anymore work to do.
//
-// We try to wait for a period of GC_INTERVAL (2 seconds) of idleness, where
-// idleness means that no libev watchers have been executed. Since
-// everything in node uses libev watchers, this is a pretty good measure of
-// idleness. This is done with gc_check, which records the timestamp
-// last_active on every tick of the event loop, and with gc_timer which
-// executes every few seconds to measure if
-// last_active + GC_INTERVAL < ev_now()
-// If we do find a period of idleness, then we start the gc_idle timer which
-// will very repaidly call IdleNotification until the heap is fully
-// compacted.
-static ev_tstamp last_active;
-static ev_timer gc_timer;
+// A rather convoluted algorithm has been devised to determine when Node is
+// idle. You'll have to figure it out for yourself.
static ev_check gc_check;
static ev_idle gc_idle;
-#define GC_INTERVAL 1.0
+static ev_timer gc_timer;
+bool need_gc;
+
-static void gc_timer_start () {
+#define FAST_TICK 0.7
+#define GC_WAIT_TIME 5.
+#define RPM_SAMPLES 100
+#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]
+static ev_tstamp tick_times[RPM_SAMPLES];
+static int tick_time_head;
+
+static void StartGCTimer () {
if (!ev_is_active(&gc_timer)) {
ev_timer_start(EV_DEFAULT_UC_ &gc_timer);
ev_unref(EV_DEFAULT_UC);
}
}
-static void gc_timer_stop () {
+static void StopGCTimer () {
if (ev_is_active(&gc_timer)) {
ev_ref(EV_DEFAULT_UC);
ev_timer_stop(EV_DEFAULT_UC_ &gc_timer);
}
}
-
-static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
- assert(watcher == &gc_timer);
- assert(revents == EV_TIMER);
-
- //fprintf(stderr, "check idle\n");
-
- ev_tstamp idle_time = ev_now(EV_DEFAULT_UC) - last_active;
-
- if (idle_time > GC_INTERVAL) {
- if (!V8::IdleNotification()) {
- ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
- }
- gc_timer_stop();
- }
-}
-
-
-static void NotifyIdleness(EV_P_ ev_idle *watcher, int revents) {
+static void Idle(EV_P_ ev_idle *watcher, int revents) {
assert(watcher == &gc_idle);
assert(revents == EV_IDLE);
- //fprintf(stderr, "notify idle\n");
+ //fprintf(stderr, "idle\n");
if (V8::IdleNotification()) {
ev_idle_stop(EV_A_ watcher);
- gc_timer_stop();
+ StopGCTimer();
}
}
-static void Activity(EV_P_ ev_check *watcher, int revents) {
+// Called directly after every call to select() (or epoll, or whatever)
+static void Check(EV_P_ ev_check *watcher, int revents) {
assert(watcher == &gc_check);
assert(revents == EV_CHECK);
- int pending = ev_pending_count(EV_DEFAULT_UC);
-
- // Don't count GC watchers as activity.
+ tick_times[tick_time_head] = ev_now(EV_DEFAULT_UC);
+ tick_time_head = (tick_time_head + 1) % RPM_SAMPLES;
- if (ev_is_pending(&gc_timer)) pending--;
- if (ev_is_pending(&gc_idle)) pending--;
- if (ev_is_pending(&gc_check)) pending--;
+ StartGCTimer();
- assert(pending >= 0);
+ for (int i = 0; i < (int)(GC_WAIT_TIME/FAST_TICK); i++) {
+ double d = TICK_TIME(i+1) - TICK_TIME(i+2);
+ //printf("d = %f\n", d);
+ // If in the last 5 ticks the difference between
+ // ticks was less than 0.7 seconds, then continue.
+ if (d < FAST_TICK) {
+ //printf("---\n");
+ return;
+ }
+ }
- //fprintf(stderr, "activity, pending: %d\n", pending);
+ // Otherwise start the gc!
- if (pending) {
- last_active = ev_now(EV_DEFAULT_UC);
- ev_idle_stop(EV_DEFAULT_UC_ &gc_idle);
- gc_timer_start();
- }
+ //fprintf(stderr, "start idle 2\n");
+ ev_idle_start(EV_A_ &gc_idle);
}
}
+static inline const char *errno_string(int errorno) {
+#define ERRNO_CASE(e) case e: return #e;
+ switch (errorno) {
+
+#ifdef EACCES
+ ERRNO_CASE(EACCES);
+#endif
+
+#ifdef EADDRINUSE
+ ERRNO_CASE(EADDRINUSE);
+#endif
+
+#ifdef EADDRNOTAVAIL
+ ERRNO_CASE(EADDRNOTAVAIL);
+#endif
+
+#ifdef EAFNOSUPPORT
+ ERRNO_CASE(EAFNOSUPPORT);
+#endif
+
+#ifdef EAGAIN
+ ERRNO_CASE(EAGAIN);
+#endif
+
+#ifdef EWOULDBLOCK
+# if EAGAIN != EWOULDBLOCK
+ ERRNO_CASE(EWOULDBLOCK);
+# endif
+#endif
+
+#ifdef EALREADY
+ ERRNO_CASE(EALREADY);
+#endif
+
+#ifdef EBADF
+ ERRNO_CASE(EBADF);
+#endif
+
+#ifdef EBADMSG
+ ERRNO_CASE(EBADMSG);
+#endif
+
+#ifdef EBUSY
+ ERRNO_CASE(EBUSY);
+#endif
+
+#ifdef ECANCELED
+ ERRNO_CASE(ECANCELED);
+#endif
+
+#ifdef ECHILD
+ ERRNO_CASE(ECHILD);
+#endif
+
+#ifdef ECONNABORTED
+ ERRNO_CASE(ECONNABORTED);
+#endif
+
+#ifdef ECONNREFUSED
+ ERRNO_CASE(ECONNREFUSED);
+#endif
+
+#ifdef ECONNRESET
+ ERRNO_CASE(ECONNRESET);
+#endif
+
+#ifdef EDEADLK
+ ERRNO_CASE(EDEADLK);
+#endif
+
+#ifdef EDESTADDRREQ
+ ERRNO_CASE(EDESTADDRREQ);
+#endif
+
+#ifdef EDOM
+ ERRNO_CASE(EDOM);
+#endif
+
+#ifdef EDQUOT
+ ERRNO_CASE(EDQUOT);
+#endif
+
+#ifdef EEXIST
+ ERRNO_CASE(EEXIST);
+#endif
+
+#ifdef EFAULT
+ ERRNO_CASE(EFAULT);
+#endif
+
+#ifdef EFBIG
+ ERRNO_CASE(EFBIG);
+#endif
+
+#ifdef EHOSTUNREACH
+ ERRNO_CASE(EHOSTUNREACH);
+#endif
+
+#ifdef EIDRM
+ ERRNO_CASE(EIDRM);
+#endif
+
+#ifdef EILSEQ
+ ERRNO_CASE(EILSEQ);
+#endif
+
+#ifdef EINPROGRESS
+ ERRNO_CASE(EINPROGRESS);
+#endif
+
+#ifdef EINTR
+ ERRNO_CASE(EINTR);
+#endif
+
+#ifdef EINVAL
+ ERRNO_CASE(EINVAL);
+#endif
+
+#ifdef EIO
+ ERRNO_CASE(EIO);
+#endif
+
+#ifdef EISCONN
+ ERRNO_CASE(EISCONN);
+#endif
+
+#ifdef EISDIR
+ ERRNO_CASE(EISDIR);
+#endif
+
+#ifdef ELOOP
+ ERRNO_CASE(ELOOP);
+#endif
+
+#ifdef EMFILE
+ ERRNO_CASE(EMFILE);
+#endif
+
+#ifdef EMLINK
+ ERRNO_CASE(EMLINK);
+#endif
+
+#ifdef EMSGSIZE
+ ERRNO_CASE(EMSGSIZE);
+#endif
+
+#ifdef EMULTIHOP
+ ERRNO_CASE(EMULTIHOP);
+#endif
+
+#ifdef ENAMETOOLONG
+ ERRNO_CASE(ENAMETOOLONG);
+#endif
+
+#ifdef ENETDOWN
+ ERRNO_CASE(ENETDOWN);
+#endif
+
+#ifdef ENETRESET
+ ERRNO_CASE(ENETRESET);
+#endif
+
+#ifdef ENETUNREACH
+ ERRNO_CASE(ENETUNREACH);
+#endif
+
+#ifdef ENFILE
+ ERRNO_CASE(ENFILE);
+#endif
+
+#ifdef ENOBUFS
+ ERRNO_CASE(ENOBUFS);
+#endif
+
+#ifdef ENODATA
+ ERRNO_CASE(ENODATA);
+#endif
+
+#ifdef ENODEV
+ ERRNO_CASE(ENODEV);
+#endif
+
+#ifdef ENOENT
+ ERRNO_CASE(ENOENT);
+#endif
+
+#ifdef ENOEXEC
+ ERRNO_CASE(ENOEXEC);
+#endif
+
+#ifdef ENOLINK
+ ERRNO_CASE(ENOLINK);
+#endif
+
+#ifdef ENOLCK
+# if ENOLINK != ENOLCK
+ ERRNO_CASE(ENOLCK);
+# endif
+#endif
+
+#ifdef ENOMEM
+ ERRNO_CASE(ENOMEM);
+#endif
+
+#ifdef ENOMSG
+ ERRNO_CASE(ENOMSG);
+#endif
+
+#ifdef ENOPROTOOPT
+ ERRNO_CASE(ENOPROTOOPT);
+#endif
+
+#ifdef ENOSPC
+ ERRNO_CASE(ENOSPC);
+#endif
+
+#ifdef ENOSR
+ ERRNO_CASE(ENOSR);
+#endif
+
+#ifdef ENOSTR
+ ERRNO_CASE(ENOSTR);
+#endif
+
+#ifdef ENOSYS
+ ERRNO_CASE(ENOSYS);
+#endif
+
+#ifdef ENOTCONN
+ ERRNO_CASE(ENOTCONN);
+#endif
+
+#ifdef ENOTDIR
+ ERRNO_CASE(ENOTDIR);
+#endif
+
+#ifdef ENOTEMPTY
+ ERRNO_CASE(ENOTEMPTY);
+#endif
+
+#ifdef ENOTSOCK
+ ERRNO_CASE(ENOTSOCK);
+#endif
+
+#ifdef ENOTSUP
+ ERRNO_CASE(ENOTSUP);
+#else
+# ifdef EOPNOTSUPP
+ ERRNO_CASE(EOPNOTSUPP);
+# endif
+#endif
+
+#ifdef ENOTTY
+ ERRNO_CASE(ENOTTY);
+#endif
+
+#ifdef ENXIO
+ ERRNO_CASE(ENXIO);
+#endif
+
+
+#ifdef EOVERFLOW
+ ERRNO_CASE(EOVERFLOW);
+#endif
+
+#ifdef EPERM
+ ERRNO_CASE(EPERM);
+#endif
+
+#ifdef EPIPE
+ ERRNO_CASE(EPIPE);
+#endif
+
+#ifdef EPROTO
+ ERRNO_CASE(EPROTO);
+#endif
+
+#ifdef EPROTONOSUPPORT
+ ERRNO_CASE(EPROTONOSUPPORT);
+#endif
+
+#ifdef EPROTOTYPE
+ ERRNO_CASE(EPROTOTYPE);
+#endif
+
+#ifdef ERANGE
+ ERRNO_CASE(ERANGE);
+#endif
+
+#ifdef EROFS
+ ERRNO_CASE(EROFS);
+#endif
+
+#ifdef ESPIPE
+ ERRNO_CASE(ESPIPE);
+#endif
+
+#ifdef ESRCH
+ ERRNO_CASE(ESRCH);
+#endif
+
+#ifdef ESTALE
+ ERRNO_CASE(ESTALE);
+#endif
+
+#ifdef ETIME
+ ERRNO_CASE(ETIME);
+#endif
+
+#ifdef ETIMEDOUT
+ ERRNO_CASE(ETIMEDOUT);
+#endif
+
+#ifdef ETXTBSY
+ ERRNO_CASE(ETXTBSY);
+#endif
+
+#ifdef EXDEV
+ ERRNO_CASE(EXDEV);
+#endif
+
+ default: return "";
+ }
+}
+
+const char *signo_string(int signo) {
+#define SIGNO_CASE(e) case e: return #e;
+ switch (signo) {
+
+#ifdef SIGHUP
+ SIGNO_CASE(SIGHUP);
+#endif
+
+#ifdef SIGINT
+ SIGNO_CASE(SIGINT);
+#endif
+
+#ifdef SIGQUIT
+ SIGNO_CASE(SIGQUIT);
+#endif
+
+#ifdef SIGILL
+ SIGNO_CASE(SIGILL);
+#endif
+
+#ifdef SIGTRAP
+ SIGNO_CASE(SIGTRAP);
+#endif
+
+#ifdef SIGABRT
+ SIGNO_CASE(SIGABRT);
+#endif
+
+#ifdef SIGIOT
+# if SIGABRT != SIGIOT
+ SIGNO_CASE(SIGIOT);
+# endif
+#endif
+
+#ifdef SIGBUS
+ SIGNO_CASE(SIGBUS);
+#endif
+
+#ifdef SIGFPE
+ SIGNO_CASE(SIGFPE);
+#endif
+
+#ifdef SIGKILL
+ SIGNO_CASE(SIGKILL);
+#endif
+
+#ifdef SIGUSR1
+ SIGNO_CASE(SIGUSR1);
+#endif
+
+#ifdef SIGSEGV
+ SIGNO_CASE(SIGSEGV);
+#endif
+
+#ifdef SIGUSR2
+ SIGNO_CASE(SIGUSR2);
+#endif
+
+#ifdef SIGPIPE
+ SIGNO_CASE(SIGPIPE);
+#endif
+
+#ifdef SIGALRM
+ SIGNO_CASE(SIGALRM);
+#endif
+
+ SIGNO_CASE(SIGTERM);
+ SIGNO_CASE(SIGCHLD);
+
+#ifdef SIGSTKFLT
+ SIGNO_CASE(SIGSTKFLT);
+#endif
+
+
+#ifdef SIGCONT
+ SIGNO_CASE(SIGCONT);
+#endif
+
+#ifdef SIGSTOP
+ SIGNO_CASE(SIGSTOP);
+#endif
+
+#ifdef SIGTSTP
+ SIGNO_CASE(SIGTSTP);
+#endif
+
+#ifdef SIGTTIN
+ SIGNO_CASE(SIGTTIN);
+#endif
+
+#ifdef SIGTTOU
+ SIGNO_CASE(SIGTTOU);
+#endif
+
+#ifdef SIGURG
+ SIGNO_CASE(SIGURG);
+#endif
+
+#ifdef SIGXCPU
+ SIGNO_CASE(SIGXCPU);
+#endif
+
+#ifdef SIGXFSZ
+ SIGNO_CASE(SIGXFSZ);
+#endif
+
+#ifdef SIGVTALRM
+ SIGNO_CASE(SIGVTALRM);
+#endif
+
+#ifdef SIGPROF
+ SIGNO_CASE(SIGPROF);
+#endif
+
+#ifdef SIGWINCH
+ SIGNO_CASE(SIGWINCH);
+#endif
+
+#ifdef SIGIO
+ SIGNO_CASE(SIGIO);
+#endif
+
+#ifdef SIGPOLL
+# if SIGPOLL != SIGIO
+ SIGNO_CASE(SIGPOLL);
+# endif
+#endif
+
+#ifdef SIGLOST
+ SIGNO_CASE(SIGLOST);
+#endif
+
+#ifdef SIGPWR
+ SIGNO_CASE(SIGPWR);
+#endif
+
+#ifdef SIGSYS
+ SIGNO_CASE(SIGSYS);
+#endif
+
+ default: return "";
+ }
+}
+
+
+Local<Value> ErrnoException(int errorno,
+ const char *syscall,
+ const char *msg) {
+ Local<String> estring = String::NewSymbol(errno_string(errorno));
+ if (!msg[0]) msg = strerror(errorno);
+ Local<String> message = String::NewSymbol(msg);
+
+ Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
+ Local<String> cons2 = String::Concat(cons1, message);
+
+ Local<Value> e = Exception::Error(cons2);
+
+ Local<Object> obj = e->ToObject();
+
+ if (errno_symbol.IsEmpty()) {
+ syscall_symbol = NODE_PSYMBOL("syscall");
+ errno_symbol = NODE_PSYMBOL("errno");
+ }
+
+ obj->Set(errno_symbol, Integer::New(errorno));
+ if (syscall) obj->Set(syscall_symbol, String::NewSymbol(syscall));
+ return e;
+}
+
+
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
HandleScope scope;
stats->Set(rdev_symbol, Integer::New(s->st_rdev));
/* total size, in bytes */
- stats->Set(size_symbol, Integer::New(s->st_size));
+ stats->Set(size_symbol, Number::New(s->st_size));
/* blocksize for filesystem I/O */
stats->Set(blksize_symbol, Integer::New(s->st_blksize));
return *value ? *value : "<str conversion failed>";
}
-static void ReportException(TryCatch &try_catch, bool show_line = false) {
+static void ReportException(TryCatch &try_catch, bool show_line) {
Handle<Message> message = try_catch.Message();
Handle<Value> error = try_catch.Exception();
// Print line of source code.
String::Utf8Value sourceline(message->GetSourceLine());
const char* sourceline_string = ToCString(sourceline);
- fprintf(stderr, "%s\n", sourceline_string);
+
+ // HACK HACK HACK
+ //
+ // FIXME
+ //
+ // Because of how CommonJS modules work, all scripts are wrapped with a
+ // "function (function (exports, __filename, ...) {"
+ // to provide script local variables.
+ //
+ // When reporting errors on the first line of a script, this wrapper
+ // function is leaked to the user. This HACK is to remove it. The length
+ // of the wrapper is 62. That wrapper is defined in lib/module.js
+ //
+ // If that wrapper is ever changed, then this number also has to be
+ // updated. Or - someone could clean this up so that the two peices
+ // don't need to be changed.
+ //
+ // Even better would be to get support into V8 for wrappers that
+ // shouldn't be reported to users.
+ int offset = linenum == 1 ? 62 : 0;
+
+ fprintf(stderr, "%s\n", sourceline_string + offset);
// Print wavy underline (GetUnderline is deprecated).
int start = message->GetStartColumn();
- for (int i = 0; i < start; i++) {
+ for (int i = offset; i < start; i++) {
fprintf(stderr, " ");
}
int end = message->GetEndColumn();
HandleScope scope;
TryCatch try_catch;
- Local<Script> script = Script::Compile(source, filename);
+ Local<v8::Script> script = v8::Script::Compile(source, filename);
if (script.IsEmpty()) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(1);
}
Local<Value> result = script->Run();
if (result.IsEmpty()) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(1);
}
}
#endif // __linux__
+
+static void CheckStatus(EV_P_ ev_timer *watcher, int revents) {
+ assert(watcher == &gc_timer);
+ assert(revents == EV_TIMER);
+
+#if HAVE_GETMEM
+ // check memory
+ size_t rss, vsize;
+ if (!ev_is_active(&gc_idle) && getmem(&rss, &vsize) == 0) {
+ if (rss > 1024*1024*128) {
+ // larger than 128 megs, just start the idle watcher
+ ev_idle_start(EV_A_ &gc_idle);
+ return;
+ }
+ }
+#endif // HAVE_GETMEM
+
+ double d = ev_now(EV_DEFAULT_UC) - TICK_TIME(3);
+
+ //printfb("timer d = %f\n", d);
+
+ if (d >= GC_WAIT_TIME - 1.) {
+ //fprintf(stderr, "start idle\n");
+ ev_idle_start(EV_A_ &gc_idle);
+ }
+}
+
+
v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) {
HandleScope scope;
assert(args.Length() == 0);
return Undefined();
}
-// evalcx(code, sandbox={})
-// Executes code in a new context
-Handle<Value> EvalCX(const Arguments& args) {
- HandleScope scope;
-
- Local<String> code = args[0]->ToString();
- Local<Object> sandbox = args.Length() > 1 ? args[1]->ToObject()
- : Object::New();
- Local<String> filename = args.Length() > 2 ? args[2]->ToString()
- : String::New("evalcx");
- // Create the new context
- Persistent<Context> context = Context::New();
-
- // Enter and compile script
- context->Enter();
-
- // Copy objects from global context, to our brand new context
- Handle<Array> keys = sandbox->GetPropertyNames();
-
- unsigned int i;
- for (i = 0; i < keys->Length(); i++) {
- Handle<String> key = keys->Get(Integer::New(i))->ToString();
- Handle<Value> value = sandbox->Get(key);
- context->Global()->Set(key, value);
- }
-
- // Catch errors
- TryCatch try_catch;
-
- Local<Script> script = Script::Compile(code, filename);
- Handle<Value> result;
-
- if (script.IsEmpty()) {
- result = ThrowException(try_catch.Exception());
- } else {
- result = script->Run();
- if (result.IsEmpty()) {
- result = ThrowException(try_catch.Exception());
- } else {
- // success! copy changes back onto the sandbox object.
- keys = context->Global()->GetPropertyNames();
- for (i = 0; i < keys->Length(); i++) {
- Handle<String> key = keys->Get(Integer::New(i))->ToString();
- Handle<Value> value = context->Global()->Get(key);
- sandbox->Set(key, value);
- }
- }
- }
-
- // Clean up, clean up, everybody everywhere!
- context->DetachGlobal();
- context->Exit();
- context.Dispose();
-
- return scope.Close(result);
-}
Handle<Value> Compile(const Arguments& args) {
HandleScope scope;
TryCatch try_catch;
- Local<Script> script = Script::Compile(source, filename);
+ Local<v8::Script> script = v8::Script::Compile(source, filename);
if (try_catch.HasCaught()) {
// Hack because I can't get a proper stacktrace on SyntaxError
ReportException(try_catch, true);
}
Local<Value> result = script->Run();
- if (try_catch.HasCaught()) return try_catch.ReThrow();
+ if (try_catch.HasCaught()) {
+ ReportException(try_catch, false);
+ exit(1);
+ }
return scope.Close(result);
}
// Check if uncaught_exception_counter indicates a recursion
if (uncaught_exception_counter > 0) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(1);
}
uint32_t length = listener_array->Length();
// Report and exit if process has no "uncaughtException" listener
if (length == 0) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(1);
}
binding_cache->Set(module, exports);
}
- } else if (!strcmp(*module_v, "http")) {
- if (binding_cache->Has(module)) {
- exports = binding_cache->Get(module)->ToObject();
- } else {
- // Warning: When calling requireBinding('http') from javascript then
- // be sure that you call requireBinding('tcp') before it.
- assert(binding_cache->Has(String::New("tcp")));
- exports = Object::New();
- HTTPServer::Initialize(exports);
- HTTPConnection::Initialize(exports);
- binding_cache->Set(module, exports);
- }
-
- } else if (!strcmp(*module_v, "tcp")) {
- if (binding_cache->Has(module)) {
- exports = binding_cache->Get(module)->ToObject();
- } else {
- exports = Object::New();
- Server::Initialize(exports);
- Connection::Initialize(exports);
- binding_cache->Set(module, exports);
- }
-
} else if (!strcmp(*module_v, "cares")) {
if (binding_cache->Has(module)) {
exports = binding_cache->Get(module)->ToObject();
Buffer::Initialize(exports);
binding_cache->Set(module, exports);
}
+ #ifdef HAVE_OPENSSL
+ } else if (!strcmp(*module_v, "crypto")) {
+ if (binding_cache->Has(module)) {
+ exports = binding_cache->Get(module)->ToObject();
+ } else {
+ exports = Object::New();
+ InitCrypto(exports);
+ binding_cache->Set(module, exports);
+ }
+ #endif
+ } else if (!strcmp(*module_v, "evals")) {
+ if (binding_cache->Has(module)) {
+ exports = binding_cache->Get(module)->ToObject();
+ } else {
+ exports = Object::New();
+ node::Script::Initialize(exports);
+ binding_cache->Set(module, exports);
+ }
} else if (!strcmp(*module_v, "natives")) {
if (binding_cache->Has(module)) {
exports->Set(String::New("freelist"), String::New(native_freelist));
exports->Set(String::New("fs"), String::New(native_fs));
exports->Set(String::New("http"), String::New(native_http));
- exports->Set(String::New("http_old"), String::New(native_http_old));
+ exports->Set(String::New("crypto"), String::New(native_crypto));
exports->Set(String::New("ini"), String::New(native_ini));
exports->Set(String::New("mjsunit"), String::New(native_mjsunit));
exports->Set(String::New("net"), String::New(native_net));
exports->Set(String::New("repl"), String::New(native_repl));
exports->Set(String::New("sys"), String::New(native_sys));
exports->Set(String::New("tcp"), String::New(native_tcp));
- exports->Set(String::New("tcp_old"), String::New(native_tcp_old));
exports->Set(String::New("uri"), String::New(native_uri));
exports->Set(String::New("url"), String::New(native_url));
exports->Set(String::New("utils"), String::New(native_utils));
+ exports->Set(String::New("path"), String::New(native_path));
+ exports->Set(String::New("module"), String::New(native_module));
binding_cache->Set(module, exports);
}
} else {
- assert(0);
return ThrowException(Exception::Error(String::New("No such module")));
}
// define various internal methods
NODE_SET_METHOD(process, "loop", Loop);
NODE_SET_METHOD(process, "unloop", Unloop);
- NODE_SET_METHOD(process, "evalcx", EvalCX);
NODE_SET_METHOD(process, "compile", Compile);
NODE_SET_METHOD(process, "_byteLength", ByteLength);
NODE_SET_METHOD(process, "_needTickCallback", NeedTickCallback);
// The node.js file returns a function 'f'
-#ifndef NDEBUG
TryCatch try_catch;
-#endif
Local<Value> f_value = ExecuteString(String::New(native_node),
String::New("node.js"));
-#ifndef NDEBUG
if (try_catch.HasCaught()) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(10);
}
-#endif
assert(f_value->IsFunction());
Local<Function> f = Local<Function>::Cast(f_value);
f->Call(global, 1, args);
-#ifndef NDEBUG
if (try_catch.HasCaught()) {
- ReportException(try_catch);
+ ReportException(try_catch, true);
exit(11);
}
-#endif
}
static void PrintHelp();
return 1;
}
- // Ignore the SIGPIPE
- evcom_ignore_sigpipe();
+
+ // Ignore SIGPIPE
+ struct sigaction sa;
+ bzero(&sa, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+
// Initialize the default ev loop.
#ifdef __sun
ev_idle_init(&node::tick_spinner, node::Spin);
- ev_timer_init(&node::gc_timer, node::CheckIdleness, 2*GC_INTERVAL, 2*GC_INTERVAL);
-
- ev_check_init(&node::gc_check, node::Activity);
+ ev_check_init(&node::gc_check, node::Check);
ev_check_start(EV_DEFAULT_UC_ &node::gc_check);
ev_unref(EV_DEFAULT_UC);
- ev_idle_init(&node::gc_idle, node::NotifyIdleness);
+ ev_idle_init(&node::gc_idle, node::Idle);
+ ev_timer_init(&node::gc_timer, node::CheckStatus, 5., 5.);
// Setup the EIO thread pool