# HG changeset patch # User John "Elwin" Edwards # Date 1341861843 25200 # Node ID bd2cf6dda28d378b1fefaeadb83ddc5599abc9c1 # Parent ad4229cf832144a77efd2c4ac3fba726dea431f1 RLG-Web: use the pty module. Convert the RLG-Web server to use the pty.js module instead of the ptyhelper binary. diff -r ad4229cf8321 -r bd2cf6dda28d rlgwebd.js --- 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;