Added external interface for signal handlers.
Also process.pid and node.kill().
This commit is contained in:
parent
0283e68129
commit
334d56d2be
@ -53,6 +53,10 @@ These objects are available to all programs.
|
||||
+node.cwd()+::
|
||||
Returns the current working directory of the process.
|
||||
|
||||
+node.kill(pid, signal)+ ::
|
||||
See kill(2). The standard POSIX signals are defined under the +node+
|
||||
namespace (+node.SIGINT+, +node.SIGUSR1+, ...).
|
||||
|
||||
+node.compile(source, scriptOrigin)+::
|
||||
Just like +eval()+ except that you can specify a +scriptOrigin+ for better
|
||||
error reporting.
|
||||
@ -101,6 +105,9 @@ the global scope. +process+ is an instance of +node.EventEmitter+.
|
||||
+
|
||||
The parameter +code+ is the integer exit code
|
||||
passed to +process.exit()+.
|
||||
| +"SIGINT"+, +"SIGUSR1"+, ... | (none) | Emitted when the processes receives a signal.
|
||||
See sigaction(2) for a list of standard POSIX
|
||||
signal names such as SIGINT, SIGUSR1, etc.
|
||||
|=========================================================
|
||||
|
||||
+process.exit(code=0)+::
|
||||
@ -113,6 +120,8 @@ An array containing the command line arguments.
|
||||
+process.ENV+ ::
|
||||
An object containing the user environment. See environ(7).
|
||||
|
||||
+process.pid+ ::
|
||||
The PID of the process.
|
||||
|
||||
=== System module
|
||||
|
||||
|
21
src/node.cc
21
src/node.cc
@ -250,6 +250,25 @@ v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Kill(const v8::Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsInt32()) {
|
||||
return ThrowException(Exception::Error(String::New("Bad argument.")));
|
||||
}
|
||||
|
||||
pid_t pid = args[0]->IntegerValue();
|
||||
int sig = args[1]->Int32Value();
|
||||
|
||||
int r = kill(pid, sig);
|
||||
|
||||
if (r != 0) {
|
||||
return ThrowException(Exception::Error(String::New(strerror(errno))));
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
typedef void (*extInit)(Handle<Object> exports);
|
||||
|
||||
// DLOpen is node.dlopen(). Used to load 'module.node' dynamically shared
|
||||
@ -420,12 +439,14 @@ static Local<Object> Load(int argc, char *argv[]) {
|
||||
}
|
||||
// assign process.ENV
|
||||
process->Set(String::NewSymbol("ENV"), env);
|
||||
process->Set(String::NewSymbol("pid"), Integer::New(getpid()));
|
||||
|
||||
// define various internal methods
|
||||
NODE_SET_METHOD(node_obj, "compile", Compile);
|
||||
NODE_SET_METHOD(node_obj, "reallyExit", Exit);
|
||||
NODE_SET_METHOD(node_obj, "cwd", Cwd);
|
||||
NODE_SET_METHOD(node_obj, "dlopen", DLOpen);
|
||||
NODE_SET_METHOD(node_obj, "kill", Kill);
|
||||
|
||||
// Assign the EventEmitter. It was created in main().
|
||||
node_obj->Set(String::NewSymbol("EventEmitter"),
|
||||
|
19
src/node.js
19
src/node.js
@ -98,6 +98,25 @@ node.mixin = function() {
|
||||
return target;
|
||||
};
|
||||
|
||||
// Signal Handlers
|
||||
|
||||
(function () { // anonymous namespace
|
||||
|
||||
function isSignal (event) {
|
||||
return event.slice(0, 3) === 'SIG' && node.hasOwnProperty(event);
|
||||
};
|
||||
|
||||
process.addListener("newListener", function (event) {
|
||||
if (isSignal(event) && process.listeners(event).length === 0) {
|
||||
var handler = new node.SignalHandler(node[event]);
|
||||
handler.addListener("signal", function () {
|
||||
process.emit(event);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
})(); // anonymous namespace
|
||||
|
||||
// Timers
|
||||
|
||||
function setTimeout (callback, after) {
|
||||
|
@ -1,38 +1,34 @@
|
||||
node.mixin(require("common.js"));
|
||||
|
||||
if (process.ARGV[2] === "-child") {
|
||||
node.stdio.open();
|
||||
var handler = new node.SignalHandler(node.SIGUSR1);
|
||||
handler.addListener("signal", function() {
|
||||
node.stdio.write("handled SIGUSR1");
|
||||
setTimeout(function () {
|
||||
// Allow some time for the write to go through the pipez
|
||||
process.exit(0);
|
||||
}, 50);
|
||||
});
|
||||
debug("CHILD!!!");
|
||||
|
||||
} else {
|
||||
puts("process.pid: " + process.pid);
|
||||
|
||||
var child = node.createChildProcess(ARGV[0], ['--', ARGV[1], '-child']);
|
||||
var first = 0,
|
||||
second = 0;
|
||||
|
||||
var output = "";
|
||||
|
||||
child.addListener('output', function (chunk) {
|
||||
puts("Child (stdout) said: " + JSON.stringify(chunk));
|
||||
if (chunk) { output += chunk };
|
||||
});
|
||||
process.addListener('SIGUSR1', function () {
|
||||
puts("Interrupted by SIGUSR1");
|
||||
first += 1;
|
||||
});
|
||||
|
||||
child.addListener('error', function (chunk) {
|
||||
if (/CHILD!!!/.exec(chunk)) {
|
||||
puts("Sending SIGUSR1 to " + child.pid);
|
||||
child.kill(node.SIGUSR1)
|
||||
}
|
||||
puts("Child (stderr) said: " + JSON.stringify(chunk));
|
||||
});
|
||||
process.addListener('SIGUSR1', function () {
|
||||
second += 1;
|
||||
setTimeout(function () {
|
||||
puts("End.");
|
||||
process.exit(0);
|
||||
}, 5);
|
||||
});
|
||||
|
||||
process.addListener("exit", function () {
|
||||
assertEquals("handled SIGUSR1", output);
|
||||
});
|
||||
|
||||
}
|
||||
i = 0;
|
||||
setInterval(function () {
|
||||
puts("running process..." + ++i);
|
||||
|
||||
if (i == 5) {
|
||||
node.kill(process.pid, node.SIGUSR1);
|
||||
}
|
||||
}, 1);
|
||||
|
||||
|
||||
process.addListener("exit", function () {
|
||||
assertEquals(1, first);
|
||||
assertEquals(1, second);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user