piston/shared/execute.js

60 lines
1.6 KiB
JavaScript
Raw Normal View History

2021-01-25 18:24:34 +01:00
const { writeFileSync, unlinkSync, mkdirSync } = require('fs');
2021-01-16 13:14:17 +01:00
const { spawn } = require('child_process');
const OUTPUT_LIMIT = 65535;
2021-01-25 18:24:34 +01:00
const LXC_ROOT = '/var/lib/lxc/piston/rootfs';
function execute(language, source, stdin = '', args = []) {
return new Promise(resolve => {
2021-01-25 18:24:34 +01:00
const id = new Date().getTime() + '_' + Math.floor(Math.random() * 10000000);
2021-01-16 13:14:17 +01:00
const sourceFile = `/tmp/${stamp}.code`;
2021-01-25 18:24:34 +01:00
mkdirSync(`${LXC_ROOT}/tmp/${id}`);
writeFileSync(`${LXC_ROOT}/tmp/${id}/code.code`, source);
writeFileSync(`${LXC_ROOT}/tmp/${id}/stdin.stdin`, stdin);
writeFileSync(`${LXC_ROOT}/tmp/${id}/args.args`, args.join('\n'));
2021-01-16 13:14:17 +01:00
const process = spawn(__dirname + '/../lxc/execute', [
language.name,
2021-01-25 18:24:34 +01:00
id,
2021-01-16 13:14:17 +01:00
]);
let stdout = '';
let stderr = '';
let output = '';
process.stderr.on('data', chunk => {
if (stderr.length >= OUTPUT_LIMIT) return;
2021-01-16 13:14:17 +01:00
stderr += chunk;
output += chunk;
});
process.stdout.on('data', chunk => {
if (stdout.length >= OUTPUT_LIMIT) return;
2021-01-16 13:14:17 +01:00
stdout += chunk;
output += chunk;
});
2021-01-22 02:07:23 +01:00
2021-01-16 14:19:29 +01:00
process.on('exit', code => {
2021-01-22 02:07:23 +01:00
unlinkSync(sourceFile);
stderr = stderr.trim().substring(0, OUTPUT_LIMIT);
stdout = stdout.trim().substring(0, OUTPUT_LIMIT);
output = output.trim().substring(0, OUTPUT_LIMIT);
2021-01-16 13:14:17 +01:00
2021-01-16 14:19:29 +01:00
resolve({
stdout,
stderr,
output,
ran: code === 0,
});
2021-01-16 13:14:17 +01:00
});
});
}
module.exports = {
execute,
};