You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.3 KiB
HTML
132 lines
4.3 KiB
HTML
<!doctype html>
|
|
<html lang="en-us">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<title>WebPerl Perl Runner</title>
|
|
|
|
<!-- ----- WebPerl - http://webperl.zero-g.net -----
|
|
|
|
Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net)
|
|
at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB),
|
|
Berlin, Germany, http://www.igb-berlin.de
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the same terms as Perl 5 itself: either the GNU General Public
|
|
License as published by the Free Software Foundation (either version 1,
|
|
or, at your option, any later version), or the "Artistic License" which
|
|
comes with Perl 5.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the licenses for details.
|
|
|
|
You should have received a copy of the licenses along with this program.
|
|
If not, see http://perldoc.perl.org/index-licence.html
|
|
-->
|
|
|
|
<!-- Possible To-Do for Later: This whole thing could probably also be
|
|
accomplished with a Web Worker, but that would probably require a
|
|
stripped-down version of webperl.js (that loads things without
|
|
using window.* and especially document.*
|
|
https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker
|
|
https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts
|
|
-->
|
|
|
|
<script src="../webperl.js"></script>
|
|
<!--script src="https://webperlcdn.zero-g.net/v0.07-beta/webperl.js"
|
|
integrity="sha256-jL8SB7St5ou4+hb0frK0k6VCQXsWQ1wolDrdU7i4juc" crossorigin="anonymous"></script-->
|
|
<script>
|
|
"use strict";
|
|
|
|
Perl.noMountIdbfs=true; // we're sandboxed
|
|
Perl.endAfterMain=true; // act like command-line perl
|
|
|
|
var knownClients = [];
|
|
var currentClient; // which client we're running Perl for, also keeps state
|
|
|
|
Perl.addStateChangeListener(function (from,to) {
|
|
if (from==to) return; // won't be needed as of v0.09-beta
|
|
for(var i=0; i<knownClients.length; i++)
|
|
knownClients[i].postMessage({ perlRunnerState: Perl.state },'*');
|
|
if (to=="Ended") {
|
|
if (currentClient) {
|
|
for (var c=1;c<=2;c++) // flush buffers
|
|
if (stdbuf[c].length)
|
|
currentClient.postMessage({ perlOutput: { chan:c, data:stdbuf[c] } },'*');
|
|
//TODO: how to handle nonzero exit codes and communicate them back to the client
|
|
//TODO: post output files
|
|
}
|
|
else console.error("state change to Ended with no current client?");
|
|
window.location.reload(false);
|
|
}
|
|
});
|
|
|
|
var stdbuf = [null,'',''];
|
|
Perl.output = function (str,chan) {
|
|
stdbuf[chan] += str;
|
|
var pos = stdbuf[chan].lastIndexOf("\n");
|
|
if (pos>-1) {
|
|
var line = stdbuf[chan].slice(0,pos);
|
|
if (currentClient)
|
|
currentClient.postMessage({ perlOutput: { chan:chan, data:line+"\n" } },'*');
|
|
else
|
|
console.warn("output on",chan==1?"STDOUT":"STDERR",
|
|
"with no client?",line);
|
|
stdbuf[chan] = stdbuf[chan].slice(pos+1);
|
|
}
|
|
};
|
|
|
|
Perl.init(function () {
|
|
FS.currentPath = ENV.HOME; // NOTE: https://github.com/kripken/emscripten/issues/5873
|
|
window.addEventListener('message', function (event) {
|
|
var data = event.data;
|
|
var result;
|
|
if (data["perlRunnerRegisterClient"]) {
|
|
result = { perlRunnerState: Perl.state };
|
|
if (!knownClients.includes(event.source))
|
|
knownClients.push(event.source);
|
|
}
|
|
else if (data["runPerl"]) {
|
|
if (!knownClients.includes(event.source))
|
|
knownClients.push(event.source);
|
|
if (currentClient) {
|
|
//TODO Later: a way to communicate these errors back to client?
|
|
console.error("Attempt to run Perl from",event.source,
|
|
"but am already running Perl for",currentClient);
|
|
return;
|
|
}
|
|
if (Perl.state!="Ready") {
|
|
console.error("Attempt to run Perl in state",Perl.state,
|
|
"from",event.source);
|
|
return;
|
|
}
|
|
|
|
currentClient = event.source;
|
|
|
|
var scriptFn = data.runPerl["scriptName"]
|
|
? data.runPerl.scriptName : 'script.pl';
|
|
Module['thisProgram'] = './'+scriptFn;
|
|
FS.writeFile( FS.joinPath([FS.cwd(), scriptFn]),
|
|
data.runPerl.script );
|
|
|
|
//TODO: input files
|
|
|
|
var argv = data.runPerl["argv"] ? data.runPerl.argv : [scriptFn];
|
|
Perl.start(argv);
|
|
}
|
|
else console.warn("Perl Runner ignoring unknown message:", data);
|
|
//console.log("runner got message", data, "result", result); //DB
|
|
if (result)
|
|
event.source.postMessage(result,
|
|
event.origin==null || event.origin=="null" ? '*' : event.origin);
|
|
});
|
|
});
|
|
|
|
</script>
|
|
|
|
</head>
|
|
<body>
|
|
</body>
|
|
</html>
|