changeset 139:dcd07c1d846a

Replace the daemon module with posix. The daemon module doesn't include chroot() anymore, so a replacement is needed. Detaching a daemon keeps getting harder to do in Node, so some setup has been moved into a shell script.
author John "Elwin" Edwards
date Sat, 20 Jul 2013 12:23:53 -0700
parents 144595e50376
children 789c094675f4
files rlgwebd rlgwebd.js
diffstat 2 files changed, 40 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rlgwebd	Sat Jul 20 12:23:53 2013 -0700
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+LOGFILE=/var/local/rlgwebd/log
+CTLSOCKET=/var/local/rlgwebd/ctl
+RLGWEBDJS=./rlgwebd.js
+
+if [ $UID != 0 ]
+then
+  echo "$0 needs to run as root." >&2
+  exit 1
+fi
+
+if [ $# -gt 0 ] && [ $1 = stop ]
+then
+  socat "EXEC:echo quit" "$CTLSOCKET"
+else
+  # Start
+  setsid node "$RLGWEBDJS" </dev/null &>>$LOGFILE &
+fi
+
+exit
+
--- a/rlgwebd.js	Thu Jul 18 10:43:41 2013 -0700
+++ b/rlgwebd.js	Sat Jul 20 12:23:53 2013 -0700
@@ -9,14 +9,13 @@
 var fs = require('fs');
 var events = require('events');
 var child_process = require('child_process');
-var daemon = require(path.join(localModules, "daemon"));
+var posix = require(path.join(localModules, "posix"));
 var pty = require(path.join(localModules, "pty.js"));
 var WebSocketServer = require(path.join(localModules, "websocket")).server;
 
 /* Configuration variables */
-// These first two files are NOT in the chroot.
+// The first file is NOT in the chroot.
 var ctlsocket = "/var/local/rlgwebd/ctl";
-var logfile = "/var/local/rlgwebd/log";
 var httpPort = 8080;
 var chrootDir = "/var/dgl/";
 var dropToUID = 501;
@@ -911,7 +910,18 @@
         return;
       }
       var pid = parseInt(fdata.split('\n')[0], 10);
-      process.kill(pid, 'SIGHUP');
+      try {
+        process.kill(pid, 'SIGHUP');
+      }
+      catch (err) {
+        /* If the PID is invalid, the lockfile is stale. */
+        if (err.code == "ESRCH") {
+          var nodere = RegExp("^" + pname + ":node:");
+          if (fname.match(nodere)) {
+            fs.unlink(fullfile);
+          }
+        }
+      }
       /* The response doesn't mean that the game is gone.  The only way
        * to make sure a dgamelaunch-supervised game is over would be to
        * poll fname until it disappears. */
@@ -1396,17 +1406,11 @@
   sock.on('data', conHandler);
 });
 ctlServer.listen(ctlsocket, function () {
-  /* fork off and die */
+  /* rlgwebd.js now assumes that it has been started by the rlgwebd shell
+   * script, or some other method that detaches it and sets up stdio. */
+  /* chroot and drop permissions.  posix.chroot() does chdir() itself. */
   try {
-    daemon.start(logfile);
-  }
-  catch (err) {
-    tslog("Daemonization failed: %s", err);
-    process.exit(1);
-  }
-  /* chroot and drop permissions.  daemon.chroot() does chdir() itself. */
-  try {
-    daemon.chroot(chrootDir);
+    posix.chroot(chrootDir);
   }
   catch (err) {
     tslog("chroot to %s failed: %s", chrootDir, err);