Browse Source

API: rename node.Process to node.ChildProcess

This is to avoid confusion with the global "process" object, especially for
the instances of node.Process.
v0.7.4-release
Ryan 16 years ago
parent
commit
ad9d683f9f
  1. 6
      benchmark/process_loop.js
  2. 4
      benchmark/run.js
  3. 2
      benchmark/static_http_server.js
  4. 126
      src/child_process.cc
  5. 12
      src/child_process.h
  6. 4
      src/node.cc
  7. 12
      src/node.js
  8. 6
      test/mjsunit/test-process-buffering.js
  9. 2
      test/mjsunit/test-process-kill.js
  10. 2
      test/mjsunit/test-process-simple.js
  11. 6
      test/mjsunit/test-process-spawn-loop.js
  12. 16
      website/api.txt
  13. 2
      wscript

6
benchmark/process_loop.js

@ -1,13 +1,13 @@
function next (i) { function next (i) {
if (i <= 0) return; if (i <= 0) return;
var process = node.createProcess("echo hello"); var child = node.createChildProcess("echo hello");
process.addListener("output", function (chunk) { child.addListener("output", function (chunk) {
if (chunk) print(chunk); if (chunk) print(chunk);
}); });
process.addListener("exit", function (code) { child.addListener("exit", function (code) {
if (code != 0) node.exit(-1); if (code != 0) node.exit(-1);
next(i - 1); next(i - 1);
}); });

4
benchmark/run.js

@ -8,8 +8,8 @@ var benchmark_dir = node.path.dirname(__filename);
function exec (script, callback) { function exec (script, callback) {
var command = ARGV[0] + " " + node.path.join(benchmark_dir, script); var command = ARGV[0] + " " + node.path.join(benchmark_dir, script);
var start = new Date(); var start = new Date();
var process = node.createProcess(command); var child = node.createChildProcess(command);
process.addListener("exit", function (code) { child.addListener("exit", function (code) {
var elapsed = new Date() - start; var elapsed = new Date() - start;
callback(elapsed, code); callback(elapsed, code);
}); });

2
benchmark/static_http_server.js

@ -34,11 +34,9 @@ function responseListener (res) {
}); });
} }
function onLoad () {
for (var i = 0; i < concurrency; i++) { for (var i = 0; i < concurrency; i++) {
var client = node.http.createClient(port); var client = node.http.createClient(port);
client.id = i; client.id = i;
client.get("/").finish(responseListener); client.get("/").finish(responseListener);
requests++; requests++;
} }
}

126
src/process.cc → src/child_process.cc

@ -1,5 +1,5 @@
#include "node.h" #include "node.h"
#include "process.h" #include "child_process.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -13,65 +13,65 @@ using namespace node;
#define PID_SYMBOL String::NewSymbol("pid") #define PID_SYMBOL String::NewSymbol("pid")
Persistent<FunctionTemplate> Process::constructor_template; Persistent<FunctionTemplate> ChildProcess::constructor_template;
void void
Process::Initialize (Handle<Object> target) ChildProcess::Initialize (Handle<Object> target)
{ {
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(Process::New); Local<FunctionTemplate> t = FunctionTemplate::New(ChildProcess::New);
constructor_template = Persistent<FunctionTemplate>::New(t); constructor_template = Persistent<FunctionTemplate>::New(t);
constructor_template->Inherit(EventEmitter::constructor_template); constructor_template->Inherit(EventEmitter::constructor_template);
constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "spawn", Process::Spawn); NODE_SET_PROTOTYPE_METHOD(constructor_template, "spawn", ChildProcess::Spawn);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "write", Process::Write); NODE_SET_PROTOTYPE_METHOD(constructor_template, "write", ChildProcess::Write);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", Process::Close); NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", ChildProcess::Close);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "kill", Process::Kill); NODE_SET_PROTOTYPE_METHOD(constructor_template, "kill", ChildProcess::Kill);
target->Set(String::NewSymbol("Process"), constructor_template->GetFunction()); target->Set(String::NewSymbol("ChildProcess"), constructor_template->GetFunction());
} }
Handle<Value> Handle<Value>
Process::New (const Arguments& args) ChildProcess::New (const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
Process *p = new Process(); ChildProcess *p = new ChildProcess();
p->Wrap(args.Holder()); p->Wrap(args.Holder());
return args.This(); return args.This();
} }
Handle<Value> Handle<Value>
Process::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(String::New("Bad argument.")); return ThrowException(String::New("Bad argument."));
} }
HandleScope scope; HandleScope scope;
Process *process = ObjectWrap::Unwrap<Process>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
String::Utf8Value command(args[0]->ToString()); String::Utf8Value command(args[0]->ToString());
int r = process->Spawn(*command); int r = child->Spawn(*command);
if (r != 0) { if (r != 0) {
return ThrowException(String::New("Error spawning")); return ThrowException(String::New("Error spawning"));
} }
process->handle_->Set(PID_SYMBOL, Integer::New(process->pid_)); child->handle_->Set(PID_SYMBOL, Integer::New(child->pid_));
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value>
Process::Write (const Arguments& args) ChildProcess::Write (const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
Process *process = ObjectWrap::Unwrap<Process>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(process); assert(child);
ssize_t len; ssize_t len;
@ -109,69 +109,69 @@ Process::Write (const Arguments& args)
} }
} }
return process->Write(buf, len) == 0 ? True() : False(); return child->Write(buf, len) == 0 ? True() : False();
} }
Handle<Value> Handle<Value>
Process::Kill (const Arguments& args) ChildProcess::Kill (const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
Process *process = ObjectWrap::Unwrap<Process>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(process); assert(child);
int sig = SIGTERM; int sig = SIGTERM;
if (args[0]->IsInt32()) sig = args[0]->Int32Value(); if (args[0]->IsInt32()) sig = args[0]->Int32Value();
if (process->Kill(sig) != 0) { if (child->Kill(sig) != 0) {
return ThrowException(String::New("Process already dead")); return ThrowException(String::New("ChildProcess already dead"));
} }
return Undefined(); return Undefined();
} }
Handle<Value> Handle<Value>
Process::Close (const Arguments& args) ChildProcess::Close (const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
Process *process = ObjectWrap::Unwrap<Process>(args.Holder()); ChildProcess *child = ObjectWrap::Unwrap<ChildProcess>(args.Holder());
assert(process); assert(child);
return process->Close() == 0 ? True() : False(); return child->Close() == 0 ? True() : False();
} }
void void
Process::reader_closed (evcom_reader *r) ChildProcess::reader_closed (evcom_reader *r)
{ {
Process *process = static_cast<Process*> (r->data); ChildProcess *child = static_cast<ChildProcess*> (r->data);
if (r == &process->stdout_reader_) { if (r == &child->stdout_reader_) {
process->stdout_fd_ = -1; child->stdout_fd_ = -1;
} else { } else {
assert(r == &process->stderr_reader_); assert(r == &child->stderr_reader_);
process->stderr_fd_ = -1; child->stderr_fd_ = -1;
} }
evcom_reader_detach(r); evcom_reader_detach(r);
process->MaybeShutdown(); child->MaybeShutdown();
} }
void void
Process::stdin_closed (evcom_writer *w) ChildProcess::stdin_closed (evcom_writer *w)
{ {
Process *process = static_cast<Process*> (w->data); ChildProcess *child = static_cast<ChildProcess*> (w->data);
assert(w == &process->stdin_writer_); assert(w == &child->stdin_writer_);
process->stdin_fd_ = -1; child->stdin_fd_ = -1;
evcom_writer_detach(w); evcom_writer_detach(w);
process->MaybeShutdown(); child->MaybeShutdown();
} }
void void
Process::on_read (evcom_reader *r, const void *buf, size_t len) ChildProcess::on_read (evcom_reader *r, const void *buf, size_t len)
{ {
Process *process = static_cast<Process*> (r->data); ChildProcess *child = static_cast<ChildProcess*> (r->data);
HandleScope scope; HandleScope scope;
bool isSTDOUT = (r == &process->stdout_reader_); bool isSTDOUT = (r == &child->stdout_reader_);
Local<Value> argv[1]; Local<Value> argv[1];
enum encoding encoding = isSTDOUT ? process->stdout_encoding_ : process->stderr_encoding_; enum encoding encoding = isSTDOUT ? child->stdout_encoding_ : child->stderr_encoding_;
if (len == 0) { if (len == 0) {
argv[0] = Local<Value>::New(Null()); argv[0] = Local<Value>::New(Null());
@ -190,11 +190,11 @@ Process::on_read (evcom_reader *r, const void *buf, size_t len)
argv[0] = String::New((const char*)buf, len); argv[0] = String::New((const char*)buf, len);
} }
process->Emit(isSTDOUT ? "output" : "error", 1, argv); child->Emit(isSTDOUT ? "output" : "error", 1, argv);
process->MaybeShutdown(); child->MaybeShutdown();
} }
Process::Process () ChildProcess::ChildProcess ()
: EventEmitter() : EventEmitter()
{ {
evcom_reader_init(&stdout_reader_); evcom_reader_init(&stdout_reader_);
@ -211,7 +211,7 @@ Process::Process ()
stdin_writer_.data = this; stdin_writer_.data = this;
stdin_writer_.on_close = stdin_closed; stdin_writer_.on_close = stdin_closed;
ev_init(&child_watcher_, Process::OnCHLD); ev_init(&child_watcher_, ChildProcess::OnCHLD);
child_watcher_.data = this; child_watcher_.data = this;
stdout_fd_ = -1; stdout_fd_ = -1;
@ -227,13 +227,13 @@ Process::Process ()
pid_ = 0; pid_ = 0;
} }
Process::~Process () ChildProcess::~ChildProcess ()
{ {
Shutdown(); Shutdown();
} }
void void
Process::Shutdown () ChildProcess::Shutdown ()
{ {
if (stdin_fd_ >= 0) { if (stdin_fd_ >= 0) {
evcom_writer_close(&stdin_writer_); evcom_writer_close(&stdin_writer_);
@ -269,7 +269,7 @@ SetNonBlocking (int fd)
} }
int int
Process::Spawn (const char *command) ChildProcess::Spawn (const char *command)
{ {
assert(pid_ == 0); assert(pid_ == 0);
assert(stdout_fd_ == -1); assert(stdout_fd_ == -1);
@ -345,25 +345,25 @@ Process::Spawn (const char *command)
} }
void void
Process::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);
Process *process = static_cast<Process*>(watcher->data); ChildProcess *child = static_cast<ChildProcess*>(watcher->data);
assert(revents == EV_CHILD); assert(revents == EV_CHILD);
assert(process->pid_ == watcher->rpid); assert(child->pid_ == watcher->rpid);
assert(&process->child_watcher_ == watcher); assert(&child->child_watcher_ == watcher);
process->got_chld_ = true; child->got_chld_ = true;
process->exit_code_ = watcher->rstatus; child->exit_code_ = watcher->rstatus;
if (process->stdin_fd_ >= 0) evcom_writer_close(&process->stdin_writer_); if (child->stdin_fd_ >= 0) evcom_writer_close(&child->stdin_writer_);
process->MaybeShutdown(); child->MaybeShutdown();
} }
int int
Process::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);
@ -371,7 +371,7 @@ Process::Write (const char *str, size_t len)
} }
int int
Process::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_);
@ -379,14 +379,14 @@ Process::Close (void)
} }
int int
Process::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
Process::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;

12
src/process.h → src/child_process.h

@ -1,5 +1,5 @@
#ifndef node_process_h #ifndef node_child_process_h
#define node_process_h #define node_child_process_h
#include "node.h" #include "node.h"
#include "events.h" #include "events.h"
@ -9,7 +9,7 @@
namespace node { namespace node {
class Process : EventEmitter { class ChildProcess : EventEmitter {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize (v8::Handle<v8::Object> target);
@ -22,8 +22,8 @@ class Process : EventEmitter {
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);
Process(); ChildProcess();
~Process(); ~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);
@ -59,4 +59,4 @@ class Process : EventEmitter {
}; };
} // namespace node } // namespace node
#endif // node_process_h #endif // node_child_process_h

4
src/node.cc

@ -6,7 +6,7 @@
#include "file.h" #include "file.h"
#include "http.h" #include "http.h"
#include "timer.h" #include "timer.h"
#include "process.h" #include "child_process.h"
#include "constants.h" #include "constants.h"
#include "node_stdio.h" #include "node_stdio.h"
@ -213,7 +213,7 @@ Load (int argc, char *argv[])
Stdio::Initialize(node_obj); Stdio::Initialize(node_obj);
Timer::Initialize(node_obj); Timer::Initialize(node_obj);
Process::Initialize(node_obj); ChildProcess::Initialize(node_obj);
DefineConstants(node_obj); DefineConstants(node_obj);

12
src/node.js

@ -5,10 +5,14 @@ node.tcp.createServer = function (on_connection, options) {
return server; return server;
}; };
node.createProcess = function (command) { node.createProcess = function () {
var process = new node.Process(); throw "node.createProcess() has been changed to node.createChildProcess() update your code";
process.spawn(command); };
return process;
node.createChildProcess = function (command) {
var child = new node.ChildProcess();
child.spawn(command);
return child;
}; };
node.tcp.createConnection = function (port, host) { node.tcp.createConnection = function (port, host) {

6
test/mjsunit/test-process-buffering.js

@ -4,12 +4,12 @@ var pwd_called = false;
function pwd (callback) { function pwd (callback) {
var output = ""; var output = "";
var process = node.createProcess("pwd"); var child = node.createChildProcess("pwd");
process.addListener("output", function (s) { child.addListener("output", function (s) {
puts("stdout: " + JSON.stringify(s)); puts("stdout: " + JSON.stringify(s));
if (s) output += s; if (s) output += s;
}); });
process.addListener("exit", function (c) { child.addListener("exit", function (c) {
puts("exit: " + c); puts("exit: " + c);
assertEquals(0, c); assertEquals(0, c);
callback(output); callback(output);

2
test/mjsunit/test-process-kill.js

@ -2,7 +2,7 @@ include("mjsunit.js");
var exit_status = -1; var exit_status = -1;
var cat = node.createProcess("cat"); var cat = node.createChildProcess("cat");
cat.addListener("output", function (chunk) { assertEquals(null, chunk); }); cat.addListener("output", function (chunk) { assertEquals(null, chunk); });
cat.addListener("error", function (chunk) { assertEquals(null, chunk); }); cat.addListener("error", function (chunk) { assertEquals(null, chunk); });

2
test/mjsunit/test-process-simple.js

@ -1,6 +1,6 @@
include("mjsunit.js"); include("mjsunit.js");
var cat = node.createProcess("cat"); var cat = node.createChildProcess("cat");
var response = ""; var response = "";
var exit_status = -1; var exit_status = -1;

6
test/mjsunit/test-process-spawn-loop.js

@ -4,14 +4,14 @@ var N = 40;
var finished = false; var finished = false;
function spawn (i) { function spawn (i) {
var p = node.createProcess('python -c "print 500 * 1024 * \'C\'"'); var child = node.createChildProcess('python -c "print 500 * 1024 * \'C\'"');
var output = ""; var output = "";
p.addListener("output", function(chunk) { child.addListener("output", function(chunk) {
if (chunk) output += chunk; if (chunk) output += chunk;
}); });
p.addListener("exit", function () { child.addListener("exit", function () {
//puts(output); //puts(output);
if (i < N) if (i < N)
spawn(i+1); spawn(i+1);

16
website/api.txt

@ -313,10 +313,10 @@ Stops a interval from triggering.
=== Child Processes === Child Processes
Node provides a tridirectional +popen(3)+ facility through the class Node provides a tridirectional +popen(3)+ facility through the class
+node.Process+. It is possible to stream data through the child's +stdin+, +node.ChildProcess+. It is possible to stream data through the child's +stdin+,
+stdout+, and +stderr+ in a fully non-blocking way. +stdout+, and +stderr+ in a fully non-blocking way.
==== +node.Process+ ==== +node.ChildProcess+
[cols="1,2,10",options="header"] [cols="1,2,10",options="header"]
|========================================================= |=========================================================
@ -341,31 +341,31 @@ that the +"output"+ and +"error"+ callbacks will no longer be made.
|========================================================= |=========================================================
+node.createProcess(command)+:: +node.createChildProcess(command)+::
Launches a new process with the given +command+. For example: Launches a new process with the given +command+. For example:
+ +
---------------------------------------- ----------------------------------------
var ls = node.createProcess("ls -lh /usr"); var ls = node.createChildProcess("ls -lh /usr");
ls.addListener("output", function (data) { ls.addListener("output", function (data) {
puts(data); puts(data);
}); });
---------------------------------------- ----------------------------------------
+process.pid+ :: +child.pid+ ::
The PID of the child process. The PID of the child process.
+process.write(data, encoding="ascii")+ :: +child.write(data, encoding="ascii")+ ::
Write data to the child process's +stdin+. The second argument is optional and Write data to the child process's +stdin+. The second argument is optional and
specifies the encoding: possible values are +"utf8"+, +"ascii"+, and +"raw"+. specifies the encoding: possible values are +"utf8"+, +"ascii"+, and +"raw"+.
+process.close()+ :: +child.close()+ ::
Closes the process's +stdin+ stream. Closes the process's +stdin+ stream.
+process.kill(signal=node.SIGTERM)+ :: +child.kill(signal=node.SIGTERM)+ ::
Send a single to the child process. If no argument is given, the process Send a single to the child process. If no argument is given, the process
will be sent +node.SIGTERM+. The standard POSIX signals are defined under will be sent +node.SIGTERM+. The standard POSIX signals are defined under
the +node+ namespace (+node.SIGINT+, +node.SIGUSR1+, ...). the +node+ namespace (+node.SIGINT+, +node.SIGUSR1+, ...).

2
wscript

@ -234,7 +234,7 @@ def build(bld):
src/dns.cc src/dns.cc
src/file.cc src/file.cc
src/timer.cc src/timer.cc
src/process.cc src/child_process.cc
src/constants.cc src/constants.cc
""" """
node.includes = """ node.includes = """

Loading…
Cancel
Save