From 6cfaa7fdfe8baa38f333c308f2de1efa12bbf853 Mon Sep 17 00:00:00 2001 From: purocean Date: Mon, 8 Nov 2021 15:49:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(run-code):=20=E4=BF=AE=E5=A4=8D=E9=95=BF?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=BF=90=E8=A1=8C=E5=91=BD=E4=BB=A4=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E4=B8=BB=E8=BF=9B=E7=A8=8B=E9=98=BB=E5=A1=9E=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/server/index.ts | 2 +- src/main/server/run.ts | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/main/server/index.ts b/src/main/server/index.ts index b209d2e0..a550c87f 100644 --- a/src/main/server/index.ts +++ b/src/main/server/index.ts @@ -139,7 +139,7 @@ const plantumlGen = async (ctx: any, next: any) => { const runCode = async (ctx: any, next: any) => { if (ctx.path.startsWith('/api/run')) { - const rst = run.runCode(ctx.request.body.language, ctx.request.body.code) + const rst = await run.runCode(ctx.request.body.language, ctx.request.body.code) ctx.body = result('ok', '运行成功', rst) } else { await next() diff --git a/src/main/server/run.ts b/src/main/server/run.ts index beeb22ca..dabf3e4c 100644 --- a/src/main/server/run.ts +++ b/src/main/server/run.ts @@ -1,14 +1,27 @@ -import * as fs from 'fs' +import * as fs from 'fs-extra' import * as os from 'os' import * as path from 'path' -import { execFileSync } from 'child_process' +import * as cp from 'child_process' import * as wsl from '../wsl' import config from '../config' const isWsl = wsl.isWsl const isWin = os.platform() === 'win32' -const runCode = (language: string, code: string) => { +async function execFile (file: string, args: string[], options?: cp.ExecFileOptions) { + return new Promise((resolve) => { + let result = '' + // 默认 300 秒超时 + const process = cp.execFile(file, args, { timeout: 300 * 1000, ...options }) + process.stdout?.on('data', data => { result += data }) + process.stderr?.on('data', data => { result += data }) + process.on('close', () => { + resolve(result) + }) + }) +} + +const runCode = async (language: string, code: string): Promise => { try { const languageMap = { sh: { cmd: 'sh', args: ['-c'] }, @@ -26,12 +39,12 @@ const runCode = (language: string, code: string) => { code = code.split('\n').slice(1).join('\n') // 去掉第一行的注释 if (isWsl) { const tmpFile = path.join(wsl.toWslPath(wsl.getWinTempPath()), fileName) - fs.writeFileSync(tmpFile, code) - return execFileSync('cmd.exe', ['/c', `${wsl.toWinPath(tmpFile).replace(/\\/g, '/')}`]).toString() + await fs.writeFile(tmpFile, code) + return execFile('cmd.exe', ['/c', `${wsl.toWinPath(tmpFile).replace(/\\/g, '/')}`]) } else { const tmpFile = path.join(os.tmpdir(), fileName) - fs.writeFileSync(tmpFile, code) - return execFileSync('cmd', ['/c', tmpFile]).toString() + await fs.writeFile(tmpFile, code) + return execFile('cmd', ['/c', tmpFile]) } } @@ -42,7 +55,7 @@ const runCode = (language: string, code: string) => { const useWsl = isWin && config.get('runCodeUseWsl', false) if (useWsl) { - return execFileSync('wsl.exe', ['--', runParams.cmd].concat(runParams.args).concat([code])).toString() + return execFile('wsl.exe', ['--', runParams.cmd].concat(runParams.args).concat([code])) } const env = { ...process.env } @@ -51,12 +64,12 @@ const runCode = (language: string, code: string) => { env.PATH = `${extPath}:${env.PATH}` } - return execFileSync( + return execFile( runParams.cmd, runParams.args.concat([code]), { env } - ).toString() - } catch (e) { + ) + } catch (e: any) { return e.message } }