This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Add signal handlers so we clean up before exiting.

Add SIGTERM and SIGINT signal handlers so that we run the exit handlers
before exiting when getting these signals. Fixes an issue where we
couldn't run vi after CTRL+C'ing node because the stdin fd was left
non-blocking.

Also the test from ceb5331a64e813f3a982c702fea5dcd2db2e7a290
  • Loading branch information...
1 parent ddb06cb commit 1e932ea9306a24f75bfd381c09e5b91ab6bbcbea @thughes thughes committed with ry Oct 12, 2010
Showing with 54 additions and 4 deletions.
  1. +18 −4 src/node.cc
  2. +36 −0 test/simple/test-sigint-infinite-loop.js
View
@@ -1803,6 +1803,21 @@ static void ParseArgs(int *argc, char **argv) {
}
+static void SignalExit(int signal) {
+ exit(1);
+}
+
+
+static int RegisterSignalHandler(int signal, void (*handler)(int)) {
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler;
+ sigfillset(&sa.sa_mask);
+ return sigaction(signal, &sa, NULL);
+}
+
+
static void AtExit() {
node::Stdio::Flush();
node::Stdio::DisableRawMode(STDIN_FILENO);
@@ -1850,10 +1865,9 @@ int main(int argc, char *argv[]) {
V8::SetFlagsFromCommandLine(&v8argc, v8argv, false);
// Ignore SIGPIPE
- struct sigaction sa;
- bzero(&sa, sizeof(sa));
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
+ node::RegisterSignalHandler(SIGPIPE, SIG_IGN);
+ node::RegisterSignalHandler(SIGINT, node::SignalExit);
+ node::RegisterSignalHandler(SIGTERM, node::SignalExit);
// Initialize the default ev loop.
@@ -0,0 +1,36 @@
+// This test is to assert that we can SIGINT a script which loops forever.
+// ref: http://groups.google.com/group/nodejs-dev/browse_thread/thread/e20f2f8df0296d3f
+var common = require('../common');
+var assert = require('assert');
+var spawn = require('child_process').spawn;
+
+console.log("start");
+
+var c = spawn(process.execPath, ['-e', 'while(true) { console.log("hi"); }']);
+
+var sentKill = false;
+var gotChildExit = true;
+
+c.stdout.on('data', function (s) {
+ // Prevent race condition:
+ // Wait for the first bit of output from the child process
+ // so that we're sure that it's in the V8 event loop and not
+ // just in the startup phase of execution.
+ if (!sentKill) {
+ c.kill('SIGINT')
+ console.log("SIGINT infinite-loop.js");
+ sentKill = true;
+ }
+});
+
+c.on('exit', function (code) {
+ assert.ok(code !== 0);
+ console.log("killed infinite-loop.js");
+ gotChildExit = true;
+});
+
+process.on('exit', function () {
+ assert.ok(sentKill);
+ assert.ok(gotChildExit);
+});
+

0 comments on commit 1e932ea

Please sign in to comment.