diff --git a/README.md b/README.md index 5517247..44e0c0d 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This library also exposes a higher level facility through javascript for startin // Your awesome code here - daemon.run('somefile.log', '/tmp/yourprogram.pid', function (err, started) { + daemon.daemonize('somefile.log', '/tmp/yourprogram.pid', function (err, started) { // We are now in the daemon process if (err) return sys.puts('Error starting daemon: ' + err); diff --git a/example/bindings.js b/example/bindings.js index fe74cf0..d3f4b28 100644 --- a/example/bindings.js +++ b/example/bindings.js @@ -19,36 +19,36 @@ catch (ex) { } var config = { - lockFile: '/tmp/testd.pid', // Location of lockFile - logFile: '/tmp/testd.log' // Location of logFile + lockFile: '/tmp/testd.pid', // Location of lockFile + logFile: '/tmp/testd.log' // Location of logFile }; var args = process.argv; // Handle start stop commands switch(args[2]) { - case "stop": - process.kill(parseInt(fs.readFileSync(config.lockFile))); - process.exit(0); - break; - - case "start": + case "stop": + process.kill(parseInt(fs.readFileSync(config.lockFile))); + process.exit(0); + break; + + case "start": fs.open(config.logFile, 'w+', function (err, fd) { if (err) return sys.puts('Error starting daemon: ' + err); daemon.start(fd); - daemon.lock(config.lockFile); + daemon.lock(config.lockFile); }); - break; - - default: - sys.puts('Usage: [start|stop]'); - process.exit(0); + break; + + default: + sys.puts('Usage: [start|stop]'); + process.exit(0); } // Start HTTP Server http.createServer(function(req, res) { - res.writeHead(200, { 'Content-Type': 'text/html' }); - res.write('

Hello, World!

'); - res.end(); + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.write('

Hello, World!

'); + res.end(); }).listen(8000); diff --git a/example/wrapper.js b/example/wrapper.js index b5a01a8..beb16f4 100644 --- a/example/wrapper.js +++ b/example/wrapper.js @@ -19,38 +19,41 @@ catch (ex) { } var config = { - lockFile: '/tmp/testd.pid', // Location of lockFile - logFile: '/tmp/testd.log' // Location of logFile + lockFile: '/tmp/testd.pid', // Location of lockFile + logFile: '/tmp/testd.log' // Location of logFile }; var args = process.argv; // Handle start stop commands switch(args[2]) { - case "stop": - daemon.stop(config.lockFile, function (err, pid) { - if (err) return sys.puts('Error stopping daemon: ' + err); - sys.puts('Successfully stopped daemon with pid: ' + pid); - }); - break; - - case "start": - // Start HTTP Server + case "stop": + daemon.kill(config.lockFile, function (err, pid) { + if (err) return sys.puts('Error stopping daemon: ' + err); + sys.puts('Successfully stopped daemon with pid: ' + pid); + }); + break; + + case "start": + // Start HTTP Server http.createServer(function(req, res) { // sys.puts('Incoming request for: ' + req.url); - res.writeHead(200, { 'Content-Type': 'text/html' }); - res.write('

Hello, World!

'); - res.end(); + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.write('

Hello, World!

'); + res.end(); }).listen(8000); - daemon.run(config.logFile, config.lockFile, function (err, started) { - if (err) return sys.puts('Error starting daemon: ' + err); + daemon.daemonize(config.logFile, config.lockFile, function (err, started) { + if (err) { + console.dir(err.stack); + return sys.puts('Error starting daemon: ' + err); + } sys.puts('Successfully started daemon'); }); break; - - default: - sys.puts('Usage: [start|stop]'); - break; + + default: + sys.puts('Usage: [start|stop]'); + break; } diff --git a/lib/daemon.js b/lib/daemon.js index c61d13c..ea23e1a 100644 --- a/lib/daemon.js +++ b/lib/daemon.js @@ -20,12 +20,12 @@ Object.keys(binding).forEach(function (k) { daemon[k] = binding[k] }); // Run is designed to encapsulate the basic daemon operation in a single async call. // When the callback returns you are in the the child process. // -daemon.run = function (out, lock, callback) { +daemon.daemonize = function (out, lock, callback) { fs.open(out, 'w+', function (err, fd) { if (err) return callback(err); try { - daemon.start(fd); + binding.daemonize(fd); daemon.lock(lock); callback(null, true); } @@ -36,11 +36,11 @@ daemon.run = function (out, lock, callback) { }; // -// function lock (lock, callback) +// function kill (lock, callback) // Asynchronously stop the process in the lock file and // remove the lock file // -daemon.stop = function (lock, callback) { +daemon.kill = function (lock, callback) { fs.readFile(lock, function (err, data) { if (err) return callback(err); diff --git a/src/daemon.cc b/src/daemon.cc index 9e8389d..768b3fc 100644 --- a/src/daemon.cc +++ b/src/daemon.cc @@ -30,9 +30,9 @@ using namespace node; // // Go through special routines to become a daemon. -// if successful, returns daemon's PID +// if successful, returns daemon pid // -Handle Start(const Arguments& args) { +Handle Daemonize(const Arguments& args) { HandleScope scope; pid_t pid, sid; int i, new_fd; @@ -83,6 +83,15 @@ Handle CloseStdout(const Arguments& args) { freopen("/dev/null", "w", stdout); } +// +// Closes all stdio by redirecting to /dev/null +// +Handle CloseStdio(const Arguments& args) { + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stderr); + freopen("/dev/null", "w", stdout); +} + // // File-lock to make sure that only one instance of daemon is running, also for storing pid // lock (filename) @@ -179,9 +188,13 @@ Handle SetReuid(const Arguments& args) { extern "C" void init(Handle target) { HandleScope scope; - NODE_SET_METHOD(target, "start", Start); + NODE_SET_METHOD(target, "daemonize", Daemonize); NODE_SET_METHOD(target, "lock", LockD); NODE_SET_METHOD(target, "setsid", SetSid); NODE_SET_METHOD(target, "chroot", Chroot); NODE_SET_METHOD(target, "setreuid", SetReuid); + NODE_SET_METHOD(target, "closeStderr", CloseStderr); + NODE_SET_METHOD(target, "closeStdout", CloseStdout); + NODE_SET_METHOD(target, "cloudStdin", CloseStdin); + NODE_SET_METHOD(target, "closeStdio", CloseStdio); } \ No newline at end of file