RLG-Web: use the pty module.

Convert the RLG-Web server to use the pty.js module instead of the
ptyhelper binary.
This commit is contained in:
John "Elwin" Edwards 2012-07-09 12:24:03 -07:00
parent b9a6a1e303
commit 9c45f52722

View file

@ -10,6 +10,7 @@ var fs = require('fs');
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 @@ var nextsession = 0;
* 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 @@ function TermSession(game, lkey, dims, handlers) {
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 @@ function TermSession(game, lkey, dims, handlers) {
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 @@ function TermSession(game, lkey, dims, handlers) {
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 @@ function TermSession(game, lkey, dims, handlers) {
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 @@ function Watcher(session) {
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 @@ function Player(gamename, lkey, dims, callback) {
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 @@ function conHandler(chunk) {
process.on("exit", function () {
for (var sessid in sessions) {
sessions[sessid].child.kill('SIGHUP');
sessions[sessid].term.kill('SIGHUP');
}
tslog("Quitting...");
return;