Browse Source

Lint

v0.7.4-release
Ryan 16 years ago
parent
commit
227638bac1
  1. 118
      src/child_process.cc
  2. 49
      src/child_process.h
  3. 13
      src/constants.cc
  4. 11
      src/constants.h
  5. 84
      src/dns.cc
  6. 10
      src/dns.h
  7. 80
      src/events.cc
  8. 48
      src/events.h
  9. 190
      src/net.cc
  10. 173
      src/net.h
  11. 2
      src/node.cc

118
src/child_process.cc

@ -1,5 +1,5 @@
#include "node.h" // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#include "child_process.h" #include <child_process.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -8,16 +8,15 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
namespace node {
using namespace v8; using namespace v8;
using namespace node;
#define PID_SYMBOL String::NewSymbol("pid") #define PID_SYMBOL String::NewSymbol("pid")
Persistent<FunctionTemplate> ChildProcess::constructor_template; Persistent<FunctionTemplate> ChildProcess::constructor_template;
void void ChildProcess::Initialize(Handle<Object> target) {
ChildProcess::Initialize (Handle<Object> target)
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(ChildProcess::New); Local<FunctionTemplate> t = FunctionTemplate::New(ChildProcess::New);
@ -30,12 +29,11 @@ ChildProcess::Initialize (Handle<Object> target)
NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", ChildProcess::Close); NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", ChildProcess::Close);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "kill", ChildProcess::Kill); NODE_SET_PROTOTYPE_METHOD(constructor_template, "kill", ChildProcess::Kill);
target->Set(String::NewSymbol("ChildProcess"), constructor_template->GetFunction()); target->Set(String::NewSymbol("ChildProcess"),
constructor_template->GetFunction());
} }
Handle<Value> Handle<Value> ChildProcess::New(const Arguments& args) {
ChildProcess::New (const Arguments& args)
{
HandleScope scope; HandleScope scope;
ChildProcess *p = new ChildProcess(); ChildProcess *p = new ChildProcess();
@ -44,9 +42,7 @@ ChildProcess::New (const Arguments& args)
return args.This(); return args.This();
} }
Handle<Value> Handle<Value> ChildProcess::Spawn(const Arguments& args) {
ChildProcess::Spawn (const Arguments& args)
{
if (args.Length() == 0 || !args[0]->IsString()) { if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowException(Exception::Error(String::New("Bad argument."))); return ThrowException(Exception::Error(String::New("Bad argument.")));
} }
@ -66,9 +62,7 @@ ChildProcess::Spawn (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> ChildProcess::Write(const Arguments& args) {
ChildProcess::Write (const Arguments& args)
{
HandleScope scope; HandleScope scope;
ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(child); assert(child);
@ -81,17 +75,16 @@ ChildProcess::Write (const Arguments& args)
return ThrowException(exception); return ThrowException(exception);
} }
char buf[len]; char * buf = new char[len];
ssize_t written = DecodeWrite(buf, len, args[0], enc); ssize_t written = DecodeWrite(buf, len, args[0], enc);
assert(written == len); assert(written == len);
int r = child->Write(buf, len);
delete buf;
return child->Write(buf, len) == 0 ? True() : False(); return r == 0 ? True() : False();
} }
Handle<Value> Handle<Value> ChildProcess::Kill(const Arguments& args) {
ChildProcess::Kill (const Arguments& args)
{
HandleScope scope; HandleScope scope;
ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(child); assert(child);
@ -100,25 +93,22 @@ ChildProcess::Kill (const Arguments& args)
if (args[0]->IsInt32()) sig = args[0]->Int32Value(); if (args[0]->IsInt32()) sig = args[0]->Int32Value();
if (child->Kill(sig) != 0) { if (child->Kill(sig) != 0) {
return ThrowException(Exception::Error(String::New("ChildProcess already dead"))); return ThrowException(Exception::Error(
String::New("ChildProcess already dead")));
} }
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> ChildProcess::Close(const Arguments& args) {
ChildProcess::Close (const Arguments& args)
{
HandleScope scope; HandleScope scope;
ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(child); assert(child);
return child->Close() == 0 ? True() : False(); return child->Close() == 0 ? True() : False();
} }
void void ChildProcess::reader_closed(evcom_reader *r) {
ChildProcess::reader_closed (evcom_reader *r) ChildProcess *child = static_cast<ChildProcess*>(r->data);
{
ChildProcess *child = static_cast<ChildProcess*> (r->data);
if (r == &child->stdout_reader_) { if (r == &child->stdout_reader_) {
child->stdout_fd_ = -1; child->stdout_fd_ = -1;
} else { } else {
@ -129,33 +119,28 @@ ChildProcess::reader_closed (evcom_reader *r)
child->MaybeShutdown(); child->MaybeShutdown();
} }
void void ChildProcess::stdin_closed(evcom_writer *w) {
ChildProcess::stdin_closed (evcom_writer *w) ChildProcess *child = static_cast<ChildProcess*>(w->data);
{
ChildProcess *child = static_cast<ChildProcess*> (w->data);
assert(w == &child->stdin_writer_); assert(w == &child->stdin_writer_);
child->stdin_fd_ = -1; child->stdin_fd_ = -1;
evcom_writer_detach(w); evcom_writer_detach(w);
child->MaybeShutdown(); child->MaybeShutdown();
} }
void void ChildProcess::on_read(evcom_reader *r, const void *buf, size_t len) {
ChildProcess::on_read (evcom_reader *r, const void *buf, size_t len) ChildProcess *child = static_cast<ChildProcess*>(r->data);
{
ChildProcess *child = static_cast<ChildProcess*> (r->data);
HandleScope scope; HandleScope scope;
bool isSTDOUT = (r == &child->stdout_reader_); bool isSTDOUT = (r == &child->stdout_reader_);
enum encoding encoding = isSTDOUT ? child->stdout_encoding_ : child->stderr_encoding_; enum encoding encoding = isSTDOUT ?
child->stdout_encoding_ : child->stderr_encoding_;
Local<Value> data = Encode(buf, len, encoding); Local<Value> data = Encode(buf, len, encoding);
child->Emit(isSTDOUT ? "output" : "error", 1, &data); child->Emit(isSTDOUT ? "output" : "error", 1, &data);
child->MaybeShutdown(); child->MaybeShutdown();
} }
ChildProcess::ChildProcess () ChildProcess::ChildProcess() : EventEmitter() {
: EventEmitter()
{
evcom_reader_init(&stdout_reader_); evcom_reader_init(&stdout_reader_);
stdout_reader_.data = this; stdout_reader_.data = this;
stdout_reader_.on_read = on_read; stdout_reader_.on_read = on_read;
@ -186,14 +171,11 @@ ChildProcess::ChildProcess ()
pid_ = 0; pid_ = 0;
} }
ChildProcess::~ChildProcess () ChildProcess::~ChildProcess() {
{
Shutdown(); Shutdown();
} }
void void ChildProcess::Shutdown() {
ChildProcess::Shutdown ()
{
if (stdin_fd_ >= 0) { if (stdin_fd_ >= 0) {
evcom_writer_close(&stdin_writer_); evcom_writer_close(&stdin_writer_);
} }
@ -216,9 +198,7 @@ ChildProcess::Shutdown ()
pid_ = 0; pid_ = 0;
} }
static inline int static inline int SetNonBlocking(int fd) {
SetNonBlocking (int fd)
{
int flags = fcntl(fd, F_GETFL, 0); int flags = fcntl(fd, F_GETFL, 0);
int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK); int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (r != 0) { if (r != 0) {
@ -227,9 +207,7 @@ SetNonBlocking (int fd)
return r; return r;
} }
int int ChildProcess::Spawn(const char *command) {
ChildProcess::Spawn (const char *command)
{
assert(pid_ == 0); assert(pid_ == 0);
assert(stdout_fd_ == -1); assert(stdout_fd_ == -1);
assert(stderr_fd_ == -1); assert(stderr_fd_ == -1);
@ -254,21 +232,21 @@ ChildProcess::Spawn (const char *command)
} }
switch (pid_ = vfork()) { switch (pid_ = vfork()) {
case -1: // Error. case -1: // Error.
Shutdown(); Shutdown();
return -4; return -4;
case 0: // Child. case 0: // Child.
close(stdout_pipe[0]); // close read end close(stdout_pipe[0]); // close read end
dup2(stdout_pipe[1], STDOUT_FILENO); dup2(stdout_pipe[1], STDOUT_FILENO);
close(stderr_pipe[0]); // close read end close(stderr_pipe[0]); // close read end
dup2(stderr_pipe[1], STDERR_FILENO); dup2(stderr_pipe[1], STDERR_FILENO);
close(stdin_pipe[1]); // close write end close(stdin_pipe[1]); // close write end
dup2(stdin_pipe[0], STDIN_FILENO); dup2(stdin_pipe[0], STDIN_FILENO);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); execl("/bin/sh", "sh", "-c", command, NULL);
_exit(127); _exit(127);
} }
@ -303,9 +281,7 @@ ChildProcess::Spawn (const char *command)
return 0; return 0;
} }
void void ChildProcess::OnCHLD(EV_P_ ev_child *watcher, int revents) {
ChildProcess::OnCHLD (EV_P_ ev_child *watcher, int revents)
{
ev_child_stop(EV_A_ watcher); ev_child_stop(EV_A_ watcher);
ChildProcess *child = static_cast<ChildProcess*>(watcher->data); ChildProcess *child = static_cast<ChildProcess*>(watcher->data);
@ -321,32 +297,24 @@ ChildProcess::OnCHLD (EV_P_ ev_child *watcher, int revents)
child->MaybeShutdown(); child->MaybeShutdown();
} }
int int ChildProcess::Write(const char *str, size_t len) {
ChildProcess::Write (const char *str, size_t len)
{
if (stdin_fd_ < 0 || got_chld_) return -1; if (stdin_fd_ < 0 || got_chld_) return -1;
evcom_writer_write(&stdin_writer_, str, len); evcom_writer_write(&stdin_writer_, str, len);
return 0; return 0;
} }
int int ChildProcess::Close(void) {
ChildProcess::Close (void)
{
if (stdin_fd_ < 0 || got_chld_) return -1; if (stdin_fd_ < 0 || got_chld_) return -1;
evcom_writer_close(EV_DEFAULT_UC_ &stdin_writer_); evcom_writer_close(EV_DEFAULT_UC_ &stdin_writer_);
return 0; return 0;
} }
int int ChildProcess::Kill(int sig) {
ChildProcess::Kill (int sig)
{
if (got_chld_ || pid_ == 0) return -1; if (got_chld_ || pid_ == 0) return -1;
return kill(pid_, sig); return kill(pid_, sig);
} }
void void ChildProcess::MaybeShutdown(void) {
ChildProcess::MaybeShutdown (void)
{
if (stdout_fd_ < 0 && stderr_fd_ < 0 && got_chld_) { if (stdout_fd_ < 0 && stderr_fd_ < 0 && got_chld_) {
HandleScope scope; HandleScope scope;
Handle<Value> argv[1] = { Integer::New(exit_code_) }; Handle<Value> argv[1] = { Integer::New(exit_code_) };
@ -355,3 +323,5 @@ ChildProcess::MaybeShutdown (void)
Detach(); Detach();
} }
} }
} // namespace node

49
src/child_process.h

@ -1,8 +1,10 @@
#ifndef node_child_process_h // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#define node_child_process_h #ifndef SRC_CHILD_PROCESS_H_
#define SRC_CHILD_PROCESS_H_
#include <node.h>
#include <events.h>
#include "node.h"
#include "events.h"
#include <v8.h> #include <v8.h>
#include <ev.h> #include <ev.h>
#include <evcom.h> #include <evcom.h>
@ -11,33 +13,34 @@ namespace node {
class ChildProcess : EventEmitter { class ChildProcess : EventEmitter {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
protected: protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> New (const v8::Arguments& args); static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Spawn (const v8::Arguments& args); static v8::Handle<v8::Value> Spawn(const v8::Arguments& args);
static v8::Handle<v8::Value> Write (const v8::Arguments& args); static v8::Handle<v8::Value> Write(const v8::Arguments& args);
static v8::Handle<v8::Value> Close (const v8::Arguments& args); static v8::Handle<v8::Value> Close(const v8::Arguments& args);
static v8::Handle<v8::Value> Kill (const v8::Arguments& args); static v8::Handle<v8::Value> Kill(const v8::Arguments& args);
static v8::Handle<v8::Value> PIDGetter (v8::Local<v8::String> _, const v8::AccessorInfo& info); static v8::Handle<v8::Value> PIDGetter(v8::Local<v8::String> _,
const v8::AccessorInfo& info);
ChildProcess(); ChildProcess();
~ChildProcess(); ~ChildProcess();
int Spawn (const char *command); int Spawn(const char *command);
int Write (const char *str, size_t len); int Write(const char *str, size_t len);
int Close (void); int Close(void);
int Kill (int sig); int Kill(int sig);
private: private:
static void on_read (evcom_reader *r, const void *buf, size_t len); static void on_read(evcom_reader *r, const void *buf, size_t len);
static void reader_closed (evcom_reader *r); static void reader_closed(evcom_reader *r);
static void stdin_closed (evcom_writer *w); static void stdin_closed(evcom_writer *w);
static void OnCHLD (EV_P_ ev_child *watcher, int revents); static void OnCHLD(EV_P_ ev_child *watcher, int revents);
void MaybeShutdown (void); void MaybeShutdown(void);
void Shutdown (void); void Shutdown(void);
evcom_reader stdout_reader_; evcom_reader stdout_reader_;
evcom_reader stderr_reader_; evcom_reader stderr_reader_;
@ -58,5 +61,5 @@ class ChildProcess : EventEmitter {
int exit_code_; int exit_code_;
}; };
} // namespace node } // namespace node
#endif // node_child_process_h #endif // SRC_CHILD_PROCESS_H_

13
src/constants.cc

@ -1,5 +1,5 @@
#include "node.h" // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#include "constants.h" #include <constants.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -8,12 +8,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
namespace node {
using namespace v8; using namespace v8;
using namespace node;
void void DefineConstants(Handle<Object> target) {
node::DefineConstants (Handle<Object> target)
{
NODE_DEFINE_CONSTANT(target, RAW); NODE_DEFINE_CONSTANT(target, RAW);
NODE_DEFINE_CONSTANT(target, UTF8); NODE_DEFINE_CONSTANT(target, UTF8);
NODE_DEFINE_CONSTANT(target, ASCII); NODE_DEFINE_CONSTANT(target, ASCII);
@ -571,6 +570,6 @@ node::DefineConstants (Handle<Object> target)
#ifdef SIGUNUSED #ifdef SIGUNUSED
NODE_DEFINE_CONSTANT(target, SIGUNUSED); NODE_DEFINE_CONSTANT(target, SIGUNUSED);
#endif #endif
} }
} // namespace node

11
src/constants.h

@ -1,11 +1,12 @@
#ifndef node_constants_h // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#define node_constants_h #ifndef SRC_CONSTANTS_H_
#define SRC_CONSTANTS_H_
#include <node.h>
#include <v8.h> #include <v8.h>
namespace node { namespace node {
void DefineConstants(v8::Handle<v8::Object> target); void DefineConstants(v8::Handle<v8::Object> target);
} // namespace node
} // namespace node #endif // SRC_CONSTANTS_H_
#endif // node_constants_h

84
src/dns.cc

@ -1,26 +1,27 @@
#include "node.h" // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#include "dns.h" #include <dns.h>
#include "events.h"
#include <stdlib.h> /* exit() */ #include <stdlib.h> /* exit() */
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <assert.h>
#include <events.h>
#include <v8.h> #include <v8.h>
#include <ev.h> #include <ev.h>
#include <udns.h> #include <udns.h>
namespace node {
using namespace v8; using namespace v8;
using namespace node;
static ev_io io_watcher; static ev_io io_watcher;
static ev_timer timer_watcher; static ev_timer timer_watcher;
static inline void static inline void set_timeout() {
set_timeout ()
{
int maxwait = 20; int maxwait = 20;
int wait = dns_timeouts(NULL, maxwait, ev_now(EV_DEFAULT_UC)); int wait = dns_timeouts(NULL, maxwait, ev_now(EV_DEFAULT_UC));
@ -29,21 +30,17 @@ set_timeout ()
if (!dns_active(NULL)) return; if (!dns_active(NULL)) return;
if (wait >= 0) { if (wait >= 0) {
ev_timer_set(&timer_watcher, (double)wait, 0.0); ev_timer_set(&timer_watcher, static_cast<double>(wait), 0.0);
ev_timer_start(EV_DEFAULT_UC_ &timer_watcher); ev_timer_start(EV_DEFAULT_UC_ &timer_watcher);
} }
} }
static inline void static inline void maybe_start() {
maybe_start ()
{
ev_io_start(EV_DEFAULT_UC_ &io_watcher); ev_io_start(EV_DEFAULT_UC_ &io_watcher);
set_timeout(); set_timeout();
} }
static void static void ioevent(EV_P_ ev_io *_watcher, int revents) {
ioevent (EV_P_ ev_io *_watcher, int revents)
{
assert(revents == EV_READ); assert(revents == EV_READ);
assert(_watcher == &io_watcher); assert(_watcher == &io_watcher);
dns_ioevent(NULL, ev_now(EV_DEFAULT_UC)); dns_ioevent(NULL, ev_now(EV_DEFAULT_UC));
@ -51,17 +48,13 @@ ioevent (EV_P_ ev_io *_watcher, int revents)
set_timeout(); set_timeout();
} }
static void static void timeout(EV_P_ ev_timer *_watcher, int revents) {
timeout (EV_P_ ev_timer *_watcher, int revents)
{
assert(revents == EV_TIMEOUT); assert(revents == EV_TIMEOUT);
assert(_watcher == &timer_watcher); assert(_watcher == &timer_watcher);
set_timeout(); set_timeout();
} }
static void static void ResolveError(Promise *promise) {
ResolveError (Promise *promise)
{
HandleScope scope; HandleScope scope;
int status = dns_status(NULL); int status = dns_status(NULL);
assert(status < 0); assert(status < 0);
@ -72,9 +65,9 @@ ResolveError (Promise *promise)
promise->EmitError(2, argv); promise->EmitError(2, argv);
} }
static void static void AfterResolveA4(struct dns_ctx *ctx,
AfterResolveA4 (struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data) struct dns_rr_a4 *result,
{ void *data) {
assert(ctx == &dns_defctx); assert(ctx == &dns_defctx);
HandleScope scope; HandleScope scope;
@ -108,9 +101,9 @@ AfterResolveA4 (struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data)
promise->EmitSuccess(3, argv); promise->EmitSuccess(3, argv);
} }
static void static void AfterResolveA6(struct dns_ctx *ctx,
AfterResolveA6 (struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data) struct dns_rr_a6 *result,
{ void *data) {
assert(ctx == &dns_defctx); assert(ctx == &dns_defctx);
HandleScope scope; HandleScope scope;
@ -144,14 +137,12 @@ AfterResolveA6 (struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data)
promise->EmitSuccess(3, argv); promise->EmitSuccess(3, argv);
} }
static Handle<Value> ResolveA(int type, const Arguments& args) {
static Handle<Value>
ResolveA (int type, const Arguments& args)
{
HandleScope scope; HandleScope scope;
if (args.Length() == 0 || !args[0]->IsString()) { if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowException(Exception::Error(String::New("Argument must be a string."))); return ThrowException(Exception::Error(
String::New("Argument must be a string.")));
} }
String::Utf8Value name(args[0]->ToString()); String::Utf8Value name(args[0]->ToString());
@ -171,28 +162,24 @@ ResolveA (int type, const Arguments& args)
return ThrowException(Exception::Error(String::New("Unsupported type"))); return ThrowException(Exception::Error(String::New("Unsupported type")));
} }
assert(query); // TODO better error handling. assert(query); // TODO(ry) better error handling.
maybe_start(); maybe_start();
return scope.Close(promise->Handle()); return scope.Close(promise->Handle());
} }
static Handle<Value> static Handle<Value> ResolveA4(const Arguments& args) {
ResolveA4 (const Arguments& args)
{
return ResolveA(DNS_T_A, args); return ResolveA(DNS_T_A, args);
} }
static Handle<Value> static Handle<Value> ResolveA6(const Arguments& args) {
ResolveA6 (const Arguments& args)
{
return ResolveA(DNS_T_AAAA, args); return ResolveA(DNS_T_AAAA, args);
} }
static void static void AfterReverse(struct dns_ctx *ctx,
AfterReverse (struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data) struct dns_rr_ptr *result,
{ void *data) {
assert(ctx == &dns_defctx); assert(ctx == &dns_defctx);
HandleScope scope; HandleScope scope;
@ -224,13 +211,12 @@ AfterReverse (struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data)
promise->EmitSuccess(3, argv); promise->EmitSuccess(3, argv);
} }
static Handle<Value> static Handle<Value> Reverse(const Arguments& args) {
Reverse (const Arguments& args)
{
HandleScope scope; HandleScope scope;
if (args.Length() == 0 || !args[0]->IsString()) { if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowException(Exception::Error(String::New("Argument must be a string."))); return ThrowException(Exception::Error(
String::New("Argument must be a string.")));
} }
String::Utf8Value ip_address(args[0]->ToString()); String::Utf8Value ip_address(args[0]->ToString());
@ -260,16 +246,14 @@ Reverse (const Arguments& args)
query = dns_submit_a6ptr(NULL, &a.addr6, AfterReverse, promise); query = dns_submit_a6ptr(NULL, &a.addr6, AfterReverse, promise);
} }
assert(query); // TODO better error handling. assert(query); // TODO(ry) better error handling.
maybe_start(); maybe_start();
return scope.Close(promise->Handle()); return scope.Close(promise->Handle());
} }
void void DNS::Initialize(Handle<Object> target) {
DNS::Initialize (Handle<Object> target)
{
if (dns_init(NULL, 0) < 0) { if (dns_init(NULL, 0) < 0) {
fprintf(stderr, "Error initializing UDNS context\n"); fprintf(stderr, "Error initializing UDNS context\n");
exit(-2); exit(-2);
@ -298,3 +282,5 @@ DNS::Initialize (Handle<Object> target)
Local<FunctionTemplate> reverse = FunctionTemplate::New(Reverse); Local<FunctionTemplate> reverse = FunctionTemplate::New(Reverse);
target->Set(String::NewSymbol("reverse"), reverse->GetFunction()); target->Set(String::NewSymbol("reverse"), reverse->GetFunction());
} }
} // namespace node

10
src/dns.h

@ -1,6 +1,8 @@
#ifndef node_dns_h // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#define node_dns_h #ifndef SRC_DNS_H_
#define SRC_DNS_H_
#include <node.h>
#include <v8.h> #include <v8.h>
namespace node { namespace node {
@ -10,5 +12,5 @@ class DNS {
static void Initialize(v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
}; };
} // namespace node } // namespace node
#endif // node_dns_h #endif // SRC_DNS_H_

80
src/events.cc

@ -1,6 +1,5 @@
#include "events.h" // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#include <ev.h> #include <events.h>
#include <v8.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -13,36 +12,41 @@
#include <arpa/inet.h> /* inet_ntop */ #include <arpa/inet.h> /* inet_ntop */
#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */ #include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
#include <node.h>
#include <ev.h>
#include <v8.h>
namespace node {
#ifndef RAMP #ifndef RAMP
# define RAMP(x) ((x) > 0 ? (x) : 0) # define RAMP(x) ((x) > 0 ? (x) : 0)
#endif #endif
using namespace v8; using namespace v8;
using namespace node;
Persistent<FunctionTemplate> EventEmitter::constructor_template; Persistent<FunctionTemplate> EventEmitter::constructor_template;
/* Poor Man's coroutines */ /* Poor Man's coroutines */
static Promise *coroutine_top; static Promise *coroutine_top;
void void EventEmitter::Initialize(Local<FunctionTemplate> ctemplate) {
EventEmitter::Initialize (Local<FunctionTemplate> ctemplate)
{
HandleScope scope; HandleScope scope;
constructor_template = Persistent<FunctionTemplate>::New(ctemplate); constructor_template = Persistent<FunctionTemplate>::New(ctemplate);
Local<FunctionTemplate> __emit = FunctionTemplate::New(Emit); Local<FunctionTemplate> __emit = FunctionTemplate::New(Emit);
constructor_template->PrototypeTemplate()->Set(String::NewSymbol("emit"), __emit); constructor_template->PrototypeTemplate()->Set(String::NewSymbol("emit"),
__emit);
// All other prototype methods are defined in events.js // All other prototype methods are defined in events.js
coroutine_top = NULL; coroutine_top = NULL;
} }
static bool static bool ReallyEmit(Handle<Object> self,
ReallyEmit (Handle<Object> self, Handle<String> event, int argc, Handle<Value> argv[]) Handle<String> event,
{ int argc,
Handle<Value> argv[]) {
HandleScope scope; HandleScope scope;
Local<Value> events_v = self->Get(String::NewSymbol("_events")); Local<Value> events_v = self->Get(String::NewSymbol("_events"));
@ -73,9 +77,7 @@ ReallyEmit (Handle<Object> self, Handle<String> event, int argc, Handle<Value> a
return true; return true;
} }
Handle<Value> Handle<Value> EventEmitter::Emit(const Arguments& args) {
EventEmitter::Emit (const Arguments& args)
{
HandleScope scope; HandleScope scope;
if (args.Length() == 0) { if (args.Length() == 0) {
@ -97,9 +99,7 @@ EventEmitter::Emit (const Arguments& args)
return scope.Close(r ? True() : False()); return scope.Close(r ? True() : False());
} }
bool bool EventEmitter::Emit(const char *event_s, int argc, Handle<Value> argv[]) {
EventEmitter::Emit (const char *event_s, int argc, Handle<Value> argv[])
{
HandleScope scope; HandleScope scope;
Local<String> event = String::NewSymbol(event_s); Local<String> event = String::NewSymbol(event_s);
return ReallyEmit(handle_, event, argc, argv); return ReallyEmit(handle_, event, argc, argv);
@ -107,9 +107,7 @@ EventEmitter::Emit (const char *event_s, int argc, Handle<Value> argv[])
Persistent<FunctionTemplate> Promise::constructor_template; Persistent<FunctionTemplate> Promise::constructor_template;
void void Promise::Initialize(v8::Handle<v8::Object> target) {
Promise::Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New); Local<FunctionTemplate> t = FunctionTemplate::New(New);
@ -125,9 +123,7 @@ Promise::Initialize (v8::Handle<v8::Object> target)
constructor_template->GetFunction()); constructor_template->GetFunction());
} }
v8::Handle<v8::Value> v8::Handle<v8::Value> Promise::New(const v8::Arguments& args) {
Promise::New (const v8::Arguments& args)
{
HandleScope scope; HandleScope scope;
Promise *promise = new Promise(); Promise *promise = new Promise();
@ -137,18 +133,14 @@ Promise::New (const v8::Arguments& args)
return args.This(); return args.This();
} }
Handle<Value> Handle<Value> Promise::Block(const Arguments& args) {
Promise::Block (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder()); Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder());
promise->Block(); promise->Block();
return Undefined(); return Undefined();
} }
v8::Handle<v8::Value> v8::Handle<v8::Value> Promise::EmitSuccess(const v8::Arguments& args) {
Promise::EmitSuccess (const v8::Arguments& args)
{
HandleScope scope; HandleScope scope;
Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder()); Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder());
@ -163,9 +155,7 @@ Promise::EmitSuccess (const v8::Arguments& args)
return r ? True() : False(); return r ? True() : False();
} }
v8::Handle<v8::Value> v8::Handle<v8::Value> Promise::EmitError(const v8::Arguments& args) {
Promise::EmitError (const v8::Arguments& args)
{
HandleScope scope; HandleScope scope;
Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder()); Promise *promise = ObjectWrap::Unwrap<Promise>(args.Holder());
@ -180,9 +170,7 @@ Promise::EmitError (const v8::Arguments& args)
return r ? True() : False(); return r ? True() : False();
} }
void void Promise::Block(void) {
Promise::Block (void)
{
blocking_ = true; blocking_ = true;
assert(prev_ == NULL); assert(prev_ == NULL);
@ -194,18 +182,14 @@ Promise::Block (void)
assert(!blocking_); assert(!blocking_);
} }
void void Promise::Destack() {
Promise::Destack ()
{
assert(coroutine_top == this); assert(coroutine_top == this);
ev_unloop(EV_DEFAULT_ EVUNLOOP_ONE); ev_unloop(EV_DEFAULT_ EVUNLOOP_ONE);
coroutine_top = prev_; coroutine_top = prev_;
prev_ = NULL; prev_ = NULL;
} }
void void Promise::Detach(void) {
Promise::Detach (void)
{
/* Poor Man's coroutines */ /* Poor Man's coroutines */
blocking_ = false; blocking_ = false;
while (coroutine_top && !coroutine_top->blocking_) { while (coroutine_top && !coroutine_top->blocking_) {
@ -215,9 +199,7 @@ Promise::Detach (void)
ObjectWrap::Detach(); ObjectWrap::Detach();
} }
bool bool Promise::EmitSuccess(int argc, v8::Handle<v8::Value> argv[]) {
Promise::EmitSuccess (int argc, v8::Handle<v8::Value> argv[])
{
bool r = Emit("success", argc, argv); bool r = Emit("success", argc, argv);
Detach(); Detach();
@ -225,9 +207,7 @@ Promise::EmitSuccess (int argc, v8::Handle<v8::Value> argv[])
return r; return r;
} }
bool bool Promise::EmitError(int argc, v8::Handle<v8::Value> argv[]) {
Promise::EmitError (int argc, v8::Handle<v8::Value> argv[])
{
bool r = Emit("error", argc, argv); bool r = Emit("error", argc, argv);
Detach(); Detach();
@ -235,9 +215,7 @@ Promise::EmitError (int argc, v8::Handle<v8::Value> argv[])
return r; return r;
} }
Promise* Promise* Promise::Create(void) {
Promise::Create (void)
{
HandleScope scope; HandleScope scope;
Local<Object> handle = Local<Object> handle =
@ -249,3 +227,5 @@ Promise::Create (void)
return promise; return promise;
} }
} // namespace node

48
src/events.h

@ -1,57 +1,57 @@
#ifndef node_events_h // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#define node_events_h #ifndef SRC_EVENTS_H_
#define SRC_EVENTS_H_
#include "node.h" #include <object_wrap.h>
#include <v8.h> #include <v8.h>
namespace node { namespace node {
class EventEmitter : public ObjectWrap { class EventEmitter : public ObjectWrap {
public: public:
static void Initialize (v8::Local<v8::FunctionTemplate> ctemplate); static void Initialize(v8::Local<v8::FunctionTemplate> ctemplate);
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
bool Emit (const char *event, int argc, v8::Handle<v8::Value> argv[]); bool Emit(const char *event, int argc, v8::Handle<v8::Value> argv[]);
protected: protected:
static v8::Handle<v8::Value> Emit (const v8::Arguments& args); static v8::Handle<v8::Value> Emit(const v8::Arguments& args);
EventEmitter () : ObjectWrap () { } EventEmitter() : ObjectWrap () { }
}; };
class Promise : public EventEmitter { class Promise : public EventEmitter {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
static Promise* Create (void); static Promise* Create(void);
bool EmitSuccess (int argc, v8::Handle<v8::Value> argv[]); bool EmitSuccess(int argc, v8::Handle<v8::Value> argv[]);
bool EmitError (int argc, v8::Handle<v8::Value> argv[]); bool EmitError(int argc, v8::Handle<v8::Value> argv[]);
void Block (); void Block();
v8::Handle<v8::Object> Handle () v8::Handle<v8::Object> Handle() {
{
return handle_; return handle_;
} }
protected: protected:
static v8::Handle<v8::Value> New (const v8::Arguments& args); static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Block (const v8::Arguments& args); static v8::Handle<v8::Value> Block(const v8::Arguments& args);
static v8::Handle<v8::Value> EmitSuccess (const v8::Arguments& args); static v8::Handle<v8::Value> EmitSuccess(const v8::Arguments& args);
static v8::Handle<v8::Value> EmitError (const v8::Arguments& args); static v8::Handle<v8::Value> EmitError(const v8::Arguments& args);
virtual void Detach (void); virtual void Detach(void);
bool blocking_; bool blocking_;
Promise *prev_; /* for the prev in the Poor Man's coroutine stack */ Promise *prev_; /* for the prev in the Poor Man's coroutine stack */
void Destack (); void Destack();
Promise () : EventEmitter() Promise() : EventEmitter() {
{
blocking_ = false; blocking_ = false;
prev_ = NULL; prev_ = NULL;
} }
}; };
} // namespace node
#endif } // namespace node
#endif // SRC_EVENTS_H_

190
src/net.cc

@ -1,7 +1,5 @@
#include "net.h" // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#include "events.h" #include <net.h>
#include <udns.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -15,7 +13,8 @@
#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */ #include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
using namespace v8; using namespace v8;
using namespace node;
namespace node {
#define UTF8_SYMBOL String::NewSymbol("utf8") #define UTF8_SYMBOL String::NewSymbol("utf8")
#define RAW_SYMBOL String::NewSymbol("raw") #define RAW_SYMBOL String::NewSymbol("raw")
@ -49,9 +48,7 @@ static const struct addrinfo client_tcp_hints =
Persistent<FunctionTemplate> Connection::constructor_template; Persistent<FunctionTemplate> Connection::constructor_template;
void void Connection::Initialize(v8::Handle<v8::Object> target) {
Connection::Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New); Local<FunctionTemplate> t = FunctionTemplate::New(New);
@ -73,12 +70,12 @@ Connection::Initialize (v8::Handle<v8::Object> target)
READY_STATE_SYMBOL, READY_STATE_SYMBOL,
ReadyStateGetter); ReadyStateGetter);
target->Set(String::NewSymbol("Connection"), constructor_template->GetFunction()); target->Set(String::NewSymbol("Connection"),
constructor_template->GetFunction());
} }
Handle<Value> Handle<Value> Connection::ReadyStateGetter(Local<String> property,
Connection::ReadyStateGetter (Local<String> property, const AccessorInfo& info) const AccessorInfo& info) {
{
Connection *connection = ObjectWrap::Unwrap<Connection>(info.This()); Connection *connection = ObjectWrap::Unwrap<Connection>(info.This());
assert(connection); assert(connection);
@ -99,12 +96,11 @@ Connection::ReadyStateGetter (Local<String> property, const AccessorInfo& info)
} }
assert(0 && "This shouldnt happen"); assert(0 && "This shouldnt happen");
return ThrowException(Exception::Error(String::New("This shouldn't happen."))); return ThrowException(Exception::Error(
String::New("This shouldn't happen.")));
} }
void void Connection::Init() {
Connection::Init (void)
{
resolving_ = false; resolving_ = false;
evcom_stream_init(&stream_); evcom_stream_init(&stream_);
stream_.on_connect = Connection::on_connect; stream_.on_connect = Connection::on_connect;
@ -114,15 +110,12 @@ Connection::Init (void)
stream_.data = this; stream_.data = this;
} }
Connection::~Connection () Connection::~Connection() {
{
assert(stream_.recvfd < 0 && "garbage collecting open Connection"); assert(stream_.recvfd < 0 && "garbage collecting open Connection");
assert(stream_.sendfd < 0 && "garbage collecting open Connection"); assert(stream_.sendfd < 0 && "garbage collecting open Connection");
} }
Handle<Value> Handle<Value> Connection::New(const Arguments& args) {
Connection::New (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = new Connection(); Connection *connection = new Connection();
@ -131,9 +124,7 @@ Connection::New (const Arguments& args)
return args.This(); return args.This();
} }
Handle<Value> Handle<Value> Connection::Connect(const Arguments& args) {
Connection::Connect (const Arguments& args)
{
Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder());
assert(connection); assert(connection);
@ -141,12 +132,13 @@ Connection::Connect (const Arguments& args)
HandleScope scope; HandleScope scope;
if (connection->ReadyState() == EVCOM_CLOSED) { if (connection->ReadyState() == EVCOM_CLOSED) {
connection->Init(); // in case we're reusing the socket connection->Init(); // in case we're reusing the socket
assert(connection->ReadyState() == EVCOM_INITIALIZED); assert(connection->ReadyState() == EVCOM_INITIALIZED);
} }
if (connection->ReadyState() != EVCOM_INITIALIZED) { if (connection->ReadyState() != EVCOM_INITIALIZED) {
Local<Value> exception = Exception::Error(String::New("Socket is not in CLOSED state.")); Local<Value> exception = Exception::Error(
String::New("Socket is not in CLOSED state."));
return ThrowException(exception); return ThrowException(exception);
} }
@ -154,7 +146,8 @@ Connection::Connect (const Arguments& args)
assert(connection->stream_.sendfd < 0); assert(connection->stream_.sendfd < 0);
if (args.Length() == 0) { if (args.Length() == 0) {
Local<Value> exception = Exception::TypeError(String::New("First argument must be a port number")); Local<Value> exception = Exception::TypeError(
String::New("First argument must be a port number"));
return ThrowException(exception); return ThrowException(exception);
} }
@ -179,18 +172,13 @@ Connection::Connect (const Arguments& args)
* In the future I will move to a system using adns or udns: * In the future I will move to a system using adns or udns:
* http://lists.schmorp.de/pipermail/libev/2009q1/000632.html * http://lists.schmorp.de/pipermail/libev/2009q1/000632.html
*/ */
eio_custom( Connection::Resolve eio_custom(Connection::Resolve, EIO_PRI_DEFAULT, Connection::AfterResolve,
, EIO_PRI_DEFAULT connection);
, Connection::AfterResolve
, connection
);
return Undefined(); return Undefined();
} }
int int Connection::Resolve(eio_req *req) {
Connection::Resolve (eio_req *req)
{
Connection *connection = static_cast<Connection*> (req->data); Connection *connection = static_cast<Connection*> (req->data);
struct addrinfo *address = NULL; struct addrinfo *address = NULL;
@ -210,9 +198,7 @@ Connection::Resolve (eio_req *req)
return 0; return 0;
} }
static struct addrinfo * static struct addrinfo * AddressDefaultToIPv4(struct addrinfo *address_list) {
AddressDefaultToIPv4 (struct addrinfo *address_list)
{
struct addrinfo *address = NULL; struct addrinfo *address = NULL;
for (address = address_list; address != NULL; address = address->ai_next) { for (address = address_list; address != NULL; address = address->ai_next) {
@ -222,9 +208,7 @@ AddressDefaultToIPv4 (struct addrinfo *address_list)
return address == NULL ? address_list : address; return address == NULL ? address_list : address;
} }
int int Connection::AfterResolve(eio_req *req) {
Connection::AfterResolve (eio_req *req)
{
ev_unref(EV_DEFAULT_UC); ev_unref(EV_DEFAULT_UC);
Connection *connection = static_cast<Connection*> (req->data); Connection *connection = static_cast<Connection*> (req->data);
@ -246,7 +230,7 @@ Connection::AfterResolve (eio_req *req)
// no error. return. // no error. return.
if (req->result == 0) { if (req->result == 0) {
evcom_stream_attach (EV_DEFAULT_UC_ &connection->stream_); evcom_stream_attach(EV_DEFAULT_UC_ &connection->stream_);
goto out; goto out;
} }
@ -262,13 +246,11 @@ Connection::AfterResolve (eio_req *req)
connection->Detach(); connection->Detach();
out: out:
return 0; return 0;
} }
Handle<Value> Handle<Value> Connection::SetEncoding(const Arguments& args) {
Connection::SetEncoding (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.This()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
@ -296,11 +278,12 @@ Connection::SetEncoding (const Arguments& args)
connection->encoding_ = RAWS; connection->encoding_ = RAWS;
return scope.Close(RAWS_SYMBOL); return scope.Close(RAWS_SYMBOL);
} }
assert(0 && "this shouldn't happen");
return ThrowException(Exception::Error(
String::New("Could not parse encoding. This is a Node bug.")));
} }
Handle<Value> Handle<Value> Connection::ReadPause(const Arguments& args) {
Connection::ReadPause (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.This()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
@ -311,9 +294,7 @@ Connection::ReadPause (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> Connection::ReadResume(const Arguments& args) {
Connection::ReadResume (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.This()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
@ -324,9 +305,7 @@ Connection::ReadResume (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> Connection::SetTimeout(const Arguments& args) {
Connection::SetTimeout (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.This()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
@ -339,9 +318,7 @@ Connection::SetTimeout (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> Connection::Close(const Arguments& args) {
Connection::Close (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder());
assert(connection); assert(connection);
@ -350,9 +327,7 @@ Connection::Close (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> Connection::ForceClose(const Arguments& args) {
Connection::ForceClose (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder());
assert(connection); assert(connection);
@ -362,19 +337,15 @@ Connection::ForceClose (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Connection::Send(const Arguments& args) {
Handle<Value>
Connection::Send (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder()); Connection *connection = ObjectWrap::Unwrap<Connection>(args.Holder());
assert(connection); assert(connection);
if ( connection->ReadyState() != EVCOM_CONNECTED_RW if (connection->ReadyState() != EVCOM_CONNECTED_RW &&
&& connection->ReadyState() != EVCOM_CONNECTED_WO connection->ReadyState() != EVCOM_CONNECTED_WO) {
) Local<Value> exception = Exception::Error(
{ String::New("Socket is not open for writing"));
Local<Value> exception = Exception::Error(String::New("Socket is not open for writing"));
return ThrowException(exception); return ThrowException(exception);
} }
@ -386,27 +357,22 @@ Connection::Send (const Arguments& args)
return ThrowException(exception); return ThrowException(exception);
} }
char buf[len]; char * buf = new char[len];
ssize_t written = DecodeWrite(buf, len, args[0], enc); ssize_t written = DecodeWrite(buf, len, args[0], enc);
assert(written == len); assert(written == len);
connection->Send(buf, written); connection->Send(buf, written);
delete buf;
return scope.Close(Integer::New(written)); return scope.Close(Integer::New(written));
} }
void void Connection::OnReceive(const void *buf, size_t len) {
Connection::OnReceive (const void *buf, size_t len)
{
HandleScope scope; HandleScope scope;
Local<Value> data = Encode(buf, len, encoding_); Local<Value> data = Encode(buf, len, encoding_);
Emit("receive", 1, &data); Emit("receive", 1, &data);
} }
void void Connection::OnClose() {
Connection::OnClose ()
{
HandleScope scope; HandleScope scope;
Handle<Value> argv[1]; Handle<Value> argv[1];
@ -416,10 +382,10 @@ Connection::OnClose ()
} }
#define DEFINE_SIMPLE_CALLBACK(name, type) \ #define DEFINE_SIMPLE_CALLBACK(name, type) \
void name () \ void name() \
{ \ { \
HandleScope scope; \ HandleScope scope; \
Emit (type, 0, NULL); \ Emit(type, 0, NULL); \
} }
DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, "connect") DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, "connect")
@ -428,9 +394,7 @@ DEFINE_SIMPLE_CALLBACK(Connection::OnEOF, "eof")
Persistent<FunctionTemplate> Server::constructor_template; Persistent<FunctionTemplate> Server::constructor_template;
void void Server::Initialize(Handle<Object> target) {
Server::Initialize (Handle<Object> target)
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New); Local<FunctionTemplate> t = FunctionTemplate::New(New);
@ -444,10 +408,7 @@ Server::Initialize (Handle<Object> target)
target->Set(String::NewSymbol("Server"), constructor_template->GetFunction()); target->Set(String::NewSymbol("Server"), constructor_template->GetFunction());
} }
static Local<String> GetAddressString(struct sockaddr *addr) {
static Local<String>
GetAddressString (struct sockaddr *addr)
{
HandleScope scope; HandleScope scope;
char ip[INET6_ADDRSTRLEN]; char ip[INET6_ADDRSTRLEN];
Local<String> remote_address; Local<String> remote_address;
@ -462,27 +423,23 @@ GetAddressString (struct sockaddr *addr)
inet_ntop(AF_INET6, &(sa6->sin6_addr), ip, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &(sa6->sin6_addr), ip, INET6_ADDRSTRLEN);
remote_address = String::New(ip); remote_address = String::New(ip);
} else assert(0 && "received a bad sa_family"); } else {
assert(0 && "received a bad sa_family");
}
return scope.Close(remote_address); return scope.Close(remote_address);
} }
Handle<FunctionTemplate> Handle<FunctionTemplate> Server::GetConnectionTemplate() {
Server::GetConnectionTemplate (void)
{
return Connection::constructor_template; return Connection::constructor_template;
} }
Connection* Connection* Server::UnwrapConnection(Local<Object> connection) {
Server::UnwrapConnection (Local<Object> connection)
{
HandleScope scope; HandleScope scope;
return ObjectWrap::Unwrap<Connection>(connection); return ObjectWrap::Unwrap<Connection>(connection);
} }
Connection* Connection* Server::OnConnection(struct sockaddr *addr) {
Server::OnConnection (struct sockaddr *addr)
{
HandleScope scope; HandleScope scope;
TryCatch try_catch; TryCatch try_catch;
@ -511,9 +468,7 @@ Server::OnConnection (struct sockaddr *addr)
return connection; return connection;
} }
void void Server::OnClose(int errorno) {
Server::OnClose (int errorno)
{
HandleScope scope; HandleScope scope;
Handle<Value> argv[1] = { Integer::New(errorno) }; Handle<Value> argv[1] = { Integer::New(errorno) };
@ -521,12 +476,7 @@ Server::OnClose (int errorno)
Emit("close", 1, argv); Emit("close", 1, argv);
} }
// TODO Server->SetOptions Handle<Value> Server::New(const Arguments& args) {
// TODO Server -> Server rename
Handle<Value>
Server::New (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Server *server = new Server(); Server *server = new Server();
@ -535,21 +485,24 @@ Server::New (const Arguments& args)
return args.This(); return args.This();
} }
Handle<Value> Handle<Value> Server::Listen(const Arguments& args) {
Server::Listen (const Arguments& args)
{
Server *server = ObjectWrap::Unwrap<Server>(args.Holder()); Server *server = ObjectWrap::Unwrap<Server>(args.Holder());
assert(server); assert(server);
HandleScope scope; HandleScope scope;
if (args.Length() == 0) { if (args.Length() == 0) {
Local<Value> exception = Exception::TypeError(String::New("First argument must be a port number")); Local<Value> exception = Exception::TypeError(
String::New("First argument must be a port number"));
return ThrowException(exception); return ThrowException(exception);
} }
String::AsciiValue port(args[0]->ToString()); String::AsciiValue port(args[0]->ToString());
#ifndef DNS_MAXNAME
# define DNS_MAXNAME 1024
#endif
char host[DNS_MAXNAME+1] = "\0"; char host[DNS_MAXNAME+1] = "\0";
int backlog = 1024; int backlog = 1024;
@ -575,9 +528,12 @@ Server::Listen (const Arguments& args)
// For servers call getaddrinfo inline. This is blocking but it shouldn't // For servers call getaddrinfo inline. This is blocking but it shouldn't
// matter much. If someone actually complains then simply swap it out // matter much. If someone actually complains then simply swap it out
// with a libeio call. // with a libeio call.
struct addrinfo *address = NULL, struct addrinfo * address = NULL,
*address_list = NULL; * address_list = NULL;
int r = getaddrinfo(strlen(host) ? host : NULL, *port, &server_tcp_hints, &address_list);
int r = getaddrinfo(strlen(host) ?
host : NULL, *port, &server_tcp_hints, &address_list);
if (r != 0) { if (r != 0) {
Local<Value> exception = Exception::Error(String::New(strerror(errno))); Local<Value> exception = Exception::Error(String::New(strerror(errno)));
return ThrowException(exception); return ThrowException(exception);
@ -592,12 +548,12 @@ Server::Listen (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value> Server::Close(const Arguments& args) {
Server::Close (const Arguments& args)
{
Server *server = ObjectWrap::Unwrap<Server>(args.Holder()); Server *server = ObjectWrap::Unwrap<Server>(args.Holder());
assert(server); assert(server);
server->Close(); server->Close();
return Undefined(); return Undefined();
} }
} // namespace node

173
src/net.h

@ -1,40 +1,38 @@
#ifndef node_net_h // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#define node_net_h #ifndef SRC_NET_H_
#define SRC_NET_H_
#include "node.h" #include <node.h>
#include "events.h" #include <events.h>
#include <v8.h> #include <v8.h>
#include <evcom.h> #include <evcom.h>
#include <string.h>
namespace node { namespace node {
class Server; class Server;
class Connection : public EventEmitter { class Connection : public EventEmitter {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
protected: protected:
/* v8 interface */ /* v8 interface */
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> New (const v8::Arguments& args); static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Connect (const v8::Arguments& args); static v8::Handle<v8::Value> Connect(const v8::Arguments& args);
static v8::Handle<v8::Value> Send (const v8::Arguments& args); static v8::Handle<v8::Value> Send(const v8::Arguments& args);
static v8::Handle<v8::Value> SendUtf8 (const v8::Arguments& args); static v8::Handle<v8::Value> SendUtf8(const v8::Arguments& args);
static v8::Handle<v8::Value> Close (const v8::Arguments& args); static v8::Handle<v8::Value> Close(const v8::Arguments& args);
static v8::Handle<v8::Value> ForceClose (const v8::Arguments& args); static v8::Handle<v8::Value> ForceClose(const v8::Arguments& args);
static v8::Handle<v8::Value> SetEncoding (const v8::Arguments& args); static v8::Handle<v8::Value> SetEncoding(const v8::Arguments& args);
static v8::Handle<v8::Value> ReadPause (const v8::Arguments& args); static v8::Handle<v8::Value> ReadPause(const v8::Arguments& args);
static v8::Handle<v8::Value> ReadResume (const v8::Arguments& args); static v8::Handle<v8::Value> ReadResume(const v8::Arguments& args);
static v8::Handle<v8::Value> SetTimeout (const v8::Arguments& args); static v8::Handle<v8::Value> SetTimeout(const v8::Arguments& args);
static v8::Handle<v8::Value> ReadyStateGetter (v8::Local<v8::String> _, static v8::Handle<v8::Value> ReadyStateGetter(v8::Local<v8::String> _,
const v8::AccessorInfo& info); const v8::AccessorInfo& info);
Connection (void) : EventEmitter() Connection() : EventEmitter() {
{
encoding_ = RAW; encoding_ = RAW;
host_ = NULL; host_ = NULL;
@ -42,47 +40,61 @@ protected:
Init(); Init();
} }
virtual ~Connection (void); virtual ~Connection();
int Connect(struct sockaddr *address) {
return evcom_stream_connect(&stream_, address);
}
void Send(const char *buf, size_t len) {
evcom_stream_write(&stream_, buf, len);
}
void Close() {
evcom_stream_close(&stream_);
}
int Connect (struct sockaddr *address) { void ForceClose() {
return evcom_stream_connect (&stream_, address); evcom_stream_force_close(&stream_);
} }
void Send (const char *buf, size_t len) { evcom_stream_write(&stream_, buf, len); }
void Close (void) { evcom_stream_close(&stream_); } void ReadPause() {
void ForceClose (void) { evcom_stream_force_close(&stream_); } evcom_stream_read_pause(&stream_);
void ReadPause (void) { evcom_stream_read_pause(&stream_); } }
void ReadResume (void) { evcom_stream_read_resume(&stream_); }
void SetTimeout (float timeout) void ReadResume() {
{ evcom_stream_read_resume(&stream_);
}
void SetTimeout(float timeout) {
evcom_stream_reset_timeout(&stream_, timeout); evcom_stream_reset_timeout(&stream_, timeout);
} }
virtual void OnConnect (void); virtual void OnConnect();
virtual void OnReceive (const void *buf, size_t len); virtual void OnReceive(const void *buf, size_t len);
virtual void OnEOF (void); virtual void OnEOF();
virtual void OnClose (void); virtual void OnClose();
virtual void OnTimeout (void); virtual void OnTimeout();
v8::Local<v8::Object> GetProtocol (void); v8::Local<v8::Object> GetProtocol();
enum evcom_stream_state ReadyState ( ) { enum evcom_stream_state ReadyState() {
return evcom_stream_state(&stream_); return evcom_stream_state(&stream_);
} }
enum encoding encoding_; enum encoding encoding_;
bool resolving_; bool resolving_;
private: private:
/* liboi callbacks */ /* liboi callbacks */
static void on_connect (evcom_stream *s) { static void on_connect(evcom_stream *s) {
Connection *connection = static_cast<Connection*> (s->data); Connection *connection = static_cast<Connection*>(s->data);
connection->OnConnect(); connection->OnConnect();
} }
static void on_read (evcom_stream *s, const void *buf, size_t len) { static void on_read(evcom_stream *s, const void *buf, size_t len) {
Connection *connection = static_cast<Connection*> (s->data); Connection *connection = static_cast<Connection*>(s->data);
assert(connection->attached_); assert(connection->attached_);
if (len == 0) if (len == 0)
connection->OnEOF(); connection->OnEOF();
@ -90,8 +102,8 @@ private:
connection->OnReceive(buf, len); connection->OnReceive(buf, len);
} }
static void on_close (evcom_stream *s) { static void on_close(evcom_stream *s) {
Connection *connection = static_cast<Connection*> (s->data); Connection *connection = static_cast<Connection*>(s->data);
evcom_stream_detach(s); evcom_stream_detach(s);
@ -105,15 +117,15 @@ private:
connection->Detach(); connection->Detach();
} }
static void on_timeout (evcom_stream *s) { static void on_timeout(evcom_stream *s) {
Connection *connection = static_cast<Connection*> (s->data); Connection *connection = static_cast<Connection*>(s->data);
connection->OnTimeout(); connection->OnTimeout();
} }
void Init (void); // constructor helper. void Init(); // constructor helper.
static int Resolve (eio_req *req); static int Resolve(eio_req *req);
static int AfterResolve (eio_req *req); static int AfterResolve(eio_req *req);
char *host_; char *host_;
char *port_; char *port_;
evcom_stream stream_; evcom_stream stream_;
@ -122,53 +134,54 @@ private:
}; };
class Server : public EventEmitter { class Server : public EventEmitter {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
protected: protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> New (const v8::Arguments& args); static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Listen (const v8::Arguments& args); static v8::Handle<v8::Value> Listen(const v8::Arguments& args);
static v8::Handle<v8::Value> Close (const v8::Arguments& args); static v8::Handle<v8::Value> Close(const v8::Arguments& args);
Server (void) : EventEmitter() Server() : EventEmitter() {
{
evcom_server_init(&server_); evcom_server_init(&server_);
server_.on_connection = Server::on_connection; server_.on_connection = Server::on_connection;
server_.on_close = Server::on_close; server_.on_close = Server::on_close;
server_.data = this; server_.data = this;
} }
virtual ~Server () { virtual ~Server() {
assert(server_.fd >= 0); assert(server_.fd >= 0);
} }
int Listen (struct sockaddr *address, int backlog) { int Listen(struct sockaddr *address, int backlog) {
int r = evcom_server_listen (&server_, address, backlog); int r = evcom_server_listen(&server_, address, backlog);
if(r != 0) return r; if (r != 0) return r;
evcom_server_attach (EV_DEFAULT_ &server_); evcom_server_attach(EV_DEFAULT_ &server_);
Attach(); Attach();
return 0; return 0;
} }
void Close ( ) { void Close() {
evcom_server_close (&server_); evcom_server_close(&server_);
} }
virtual v8::Handle<v8::FunctionTemplate> GetConnectionTemplate (void); virtual v8::Handle<v8::FunctionTemplate> GetConnectionTemplate();
virtual Connection* UnwrapConnection (v8::Local<v8::Object> connection); virtual Connection* UnwrapConnection(v8::Local<v8::Object> connection);
private:
Connection* OnConnection(struct sockaddr *addr);
private: static evcom_stream* on_connection(evcom_server *s, struct sockaddr *addr) {
Connection* OnConnection (struct sockaddr *addr); Server *server = static_cast<Server*>(s->data);
static evcom_stream* on_connection (evcom_server *s, struct sockaddr *addr) { Connection *connection = server->OnConnection(addr);
Server *server = static_cast<Server*> (s->data);
Connection *connection = server->OnConnection (addr);
return &connection->stream_; return &connection->stream_;
} }
void OnClose (int errorno); void OnClose(int errorno);
static void on_close (evcom_server *s) {
Server *server = static_cast<Server*> (s->data); static void on_close(evcom_server *s) {
Server *server = static_cast<Server*>(s->data);
evcom_server_detach(s); evcom_server_detach(s);
server->OnClose(s->errorno); server->OnClose(s->errorno);
server->Detach(); server->Detach();
@ -177,5 +190,5 @@ private:
evcom_server server_; evcom_server server_;
}; };
} // namespace node } // namespace node
#endif #endif // SRC_NET_H_

2
src/node.cc

@ -3,7 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <strings.h> #include <string.h>
#include <limits.h> /* PATH_MAX */ #include <limits.h> /* PATH_MAX */
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>

Loading…
Cancel
Save