changeset 87:bd2cf6dda28d

RLG-Web: use the pty module. Convert the RLG-Web server to use the pty.js module instead of the ptyhelper binary.
author John "Elwin" Edwards <elwin@sdf.org>
date Mon, 09 Jul 2012 12:24:03 -0700
parents ad4229cf8321
children d644e7d46852
files rlgwebd.js
diffstat 1 files changed, 19 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/rlgwebd.js	Sun Jul 08 21:20:56 2012 -0700
+++ b/rlgwebd.js	Mon Jul 09 12:24:03 2012 -0700
@@ -10,6 +10,7 @@
 var events = require('events');
 var child_process = require('child_process');
 var daemon = require(path.join(localModules, "daemon"));
+var pty = require(path.join(localModules, "pty.js"));
 
 /* Configuration variables */
 // These first two files are NOT in the chroot.
@@ -70,7 +71,7 @@
  *  Events:
  *   "open": Emitted on startup.  Parameters: success (Boolean)
  *   "data": Data generated by child. Parameters: buf (Buffer)
- *   "exit": Child terminated. Parameters: exitcode, signal
+ *   "exit": Child terminated. Parameters: none
  */
 function TermSession(game, lkey, dims, handlers) {
   var ss = this;
@@ -109,15 +110,18 @@
   for (var key in process.env) {
     childenv[key] = process.env[key];
   }
-  childenv["PTYHELPER"] = String(this.h) + "x" + String(this.w);
-  args = [this.game.path, "-n", this.pname];
-  this.child = child_process.spawn("/bin/ptyhelper", args, {"env": childenv});
+  var args = ["-n", this.pname];
+  var spawnopts = {"env": childenv, "cwd": "/", "rows": this.h, "cols": this.w,
+                   "name": "xterm-256color"};
+  this.term = pty.spawn(this.game.path, args, spawnopts);
+  tslog("%s playing %s (index %d, pid %d)", this.pname, this.game.uname, 
+            this.sessid, this.term.pid);
   this.emit('open', true, this.sessid);
   /* Set up the lockfile and ttyrec */
   var ts = timestamp();
   var progressdir = "/dgldir/inprogress-" + this.game.uname;
   this.lock = path.join(progressdir, this.pname + ":node:" + ts + ".ttyrec");
-  var lmsg = this.child.pid.toString() + '\n' + this.w + '\n' + this.h + '\n'; 
+  var lmsg = this.term.pid.toString() + '\n' + this.w + '\n' + this.h + '\n'; 
   fs.writeFile(this.lock, lmsg, "utf8"); 
   var ttyrec = path.join("/dgldir/ttyrec", this.pname, this.game.uname, 
                ts + ".ttyrec");
@@ -127,11 +131,10 @@
   this.framebuf = new Buffer(1024);
   this.frameoff = 0;
   logins[lkey].sessions.push(this.sessid);
-  tslog("%s playing %s (index %d, pid %d)", this.pname, this.game.uname, 
-            this.sessid, this.child.pid);
   /* END setup */
-  function ttyrec_chunk(buf) {
+  function ttyrec_chunk(datastr) {
     var ts = new Date();
+    var buf = new Buffer(datastr);
     var chunk = new Buffer(buf.length + 12);
     /* TTYREC headers */
     chunk.writeUInt32LE(Math.floor(ts.getTime() / 1000), 0);
@@ -142,8 +145,7 @@
     ss.framepush(buf);
     ss.emit('data', buf);
   }
-  this.child.stdout.on("data", ttyrec_chunk);
-  this.child.stderr.on("data", ttyrec_chunk);
+  this.term.on("data", ttyrec_chunk);
   this.framepush = function(chunk) {
     /* If this chunk resets the screen, discard what preceded it. */
     if (bufncmp(chunk, this.game.clear, this.game.clear.length)) {
@@ -164,18 +166,18 @@
     this.frameoff += chunk.length;
   };
   this.write = function(data) {
-    this.child.stdin.write(data);
+    this.term.write(data);
   };
-  this.child.on("exit", function (code, signal) {
+  this.term.on("exit", function () {
     fs.unlink(ss.lock);
     ss.record.end();
-    ss.emit('exit', code, signal);
+    ss.emit('exit');
     var id = ss.sessid;
     delete sessions[id];
     tslog("Game %s ended.", id);
   });
   this.close = function () {
-    this.child.kill('SIGHUP');
+    this.term.kill('SIGHUP');
   };
 }
 TermSession.prototype = new events.EventEmitter();
@@ -203,7 +205,7 @@
     reply.d = buf.toString("hex");
     ss.sendQ.push(reply);
   }
-  function exitH(code, signal) {
+  function exitH() {
     ss.alive = false;
     ss.sendQ.push({"t": "q"});
   }
@@ -327,7 +329,7 @@
     reply.d = chunk.toString("hex");
     ss.sendQ.push(reply);
   }
-  function exitH(code, signal) {
+  function exitH() {
     ss.alive = false;
     ss.sendQ.push({"t": "q"});
   }
@@ -1010,7 +1012,7 @@
 
 process.on("exit", function () {
   for (var sessid in sessions) {
-    sessions[sessid].child.kill('SIGHUP');
+    sessions[sessid].term.kill('SIGHUP');
   }
   tslog("Quitting...");
   return;