Browse Source

Added external interface for signal handlers.

Also process.pid and node.kill().
v0.7.4-release
Brandon Beacher 15 years ago
committed by Ryan Dahl
parent
commit
334d56d2be
  1. 9
      doc/api.txt
  2. 21
      src/node.cc
  3. 19
      src/node.js
  4. 50
      test/mjsunit/test-signal-handler.js

9
doc/api.txt

@ -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

@ -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

@ -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) {

50
test/mjsunit/test-signal-handler.js

@ -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!!!");
puts("process.pid: " + process.pid);
} else {
var first = 0,
second = 0;
var child = node.createChildProcess(ARGV[0], ['--', ARGV[1], '-child']);
var output = "";
process.addListener('SIGUSR1', function () {
puts("Interrupted by SIGUSR1");
first += 1;
});
child.addListener('output', function (chunk) {
puts("Child (stdout) said: " + JSON.stringify(chunk));
if (chunk) { output += chunk };
process.addListener('SIGUSR1', function () {
second += 1;
setTimeout(function () {
puts("End.");
process.exit(0);
}, 5);
});
child.addListener('error', function (chunk) {
if (/CHILD!!!/.exec(chunk)) {
puts("Sending SIGUSR1 to " + child.pid);
child.kill(node.SIGUSR1)
i = 0;
setInterval(function () {
puts("running process..." + ++i);
if (i == 5) {
node.kill(process.pid, node.SIGUSR1);
}
puts("Child (stderr) said: " + JSON.stringify(chunk));
});
}, 1);
process.addListener("exit", function () {
assertEquals("handled SIGUSR1", output);
assertEquals(1, first);
assertEquals(1, second);
});
}

Loading…
Cancel
Save