Skip to content

Commit ef97587

Browse files
committed
修复多文件评测时SE的Bug
1 parent ac75821 commit ef97587

File tree

5 files changed

+108
-266
lines changed

5 files changed

+108
-266
lines changed

src/Spawn/Meter.ts

-11
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ export interface MeterResult {
1111
};
1212
}
1313

14-
export const EmptyMeterResult: MeterResult = {
15-
memory: 0,
16-
returnCode: 0,
17-
signal: -1,
18-
time: {
19-
real: 0,
20-
usr: 0,
21-
sys: 0,
22-
},
23-
};
24-
2514
export interface MeteredChildProcess extends ChildProcess {
2615
result: Promise<MeterResult>;
2716
}

src/Utilities/ExecutableAgent.ts

+94-111
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,86 @@ export class ExecutableAgent {
128128
}
129129
}
130130

131+
private async spawn(
132+
languageOption: {
133+
args?: string[];
134+
command: string;
135+
spawnOption?: HengSpawnOption;
136+
},
137+
runOption: {
138+
args?: string[];
139+
cwd?: string;
140+
stdio?: CompleteStdioOptions;
141+
}
142+
) {
143+
let logFileFH: FileHandle | undefined = undefined;
144+
try {
145+
if (!runOption.args) {
146+
runOption.args = [];
147+
}
148+
if (languageOption.args) {
149+
runOption.args = [...languageOption.args, ...runOption.args];
150+
}
151+
const logPath = path.resolve(this.fileAgent.dir, CompileLogName);
152+
logFileFH = await fs.promises.open(logPath, "w", 0o700);
153+
if (runOption.stdio === undefined) {
154+
runOption.stdio = ["ignore"];
155+
}
156+
runOption.stdio[1] = logFileFH.fd;
157+
runOption.stdio[2] = logFileFH.fd;
158+
const HengSpawnOption: HengSpawnOption = {
159+
cwd:
160+
languageOption.spawnOption?.cwd ??
161+
runOption.cwd ??
162+
this.fileAgent.dir,
163+
env: languageOption.spawnOption?.env,
164+
stdio: runOption.stdio,
165+
uid: getConfig().judger.uid,
166+
gid: getConfig().judger.gid,
167+
timeLimit:
168+
languageOption.spawnOption?.timeLimit ??
169+
this.executable.limit.compiler.cpuTime,
170+
memoryLimit:
171+
languageOption.spawnOption?.memoryLimit ??
172+
this.executable.limit.compiler.memory,
173+
pidLimit:
174+
languageOption.spawnOption?.pidLimit ??
175+
getConfig().judger.defaultPidLimit,
176+
fileLimit:
177+
languageOption.spawnOption?.fileLimit ??
178+
this.executable.limit.compiler.output,
179+
};
180+
const subProc = hengSpawn(
181+
languageOption.command,
182+
runOption.args,
183+
HengSpawnOption
184+
);
185+
const procResult = await subProc.result;
186+
await logFileFH.close();
187+
this.fileAgent.register(CompileLogName, CompileLogName);
188+
try {
189+
for (const file of this.configuredLanguage.compiledFiles) {
190+
await fs.promises.access(file);
191+
}
192+
} catch (error) {
193+
procResult.returnCode = procResult.returnCode || 1;
194+
}
195+
const statisticPath = path.resolve(
196+
this.fileAgent.dir,
197+
CompileStatisticName
198+
);
199+
await fs.promises.writeFile(
200+
statisticPath,
201+
JSON.stringify(procResult),
202+
{ mode: 0o700 }
203+
);
204+
this.fileAgent.register(CompileStatisticName, CompileStatisticName);
205+
return procResult;
206+
} finally {
207+
logFileFH && (await logFileFH.close());
208+
}
209+
}
210+
131211
/**
132212
* You'd better not set args, stdio, cwd.
133213
* cwd is low priority.
@@ -158,85 +238,14 @@ export class ExecutableAgent {
158238
await this.fileAgent.getString(CompileStatisticName)
159239
);
160240
} else {
161-
let compileLogFileFH: FileHandle | undefined = undefined;
162-
try {
163-
const command = languageRunOption.command;
164-
if (!args) {
165-
args = [];
166-
}
167-
if (languageRunOption.args) {
168-
args = [...languageRunOption.args, ...args];
169-
}
170-
const compileLogPath = path.resolve(
171-
this.fileAgent.dir,
172-
CompileLogName
173-
);
174-
compileLogFileFH = await fs.promises.open(
175-
compileLogPath,
176-
"w",
177-
0o700
178-
);
179-
if (stdio === undefined) {
180-
stdio = ["ignore", "pipe", "pipe"];
181-
}
182-
stdio[1] = compileLogFileFH.fd;
183-
stdio[2] = compileLogFileFH.fd;
184-
const spawnOption: HengSpawnOption = {
185-
cwd:
186-
languageRunOption.spawnOption?.cwd ??
187-
cwd ??
188-
this.fileAgent.dir,
189-
env: languageRunOption.spawnOption?.env,
190-
stdio: stdio,
191-
uid: getConfig().judger.uid,
192-
gid: getConfig().judger.gid,
193-
timeLimit:
194-
languageRunOption.spawnOption?.timeLimit ??
195-
this.executable.limit.compiler.cpuTime,
196-
memoryLimit:
197-
languageRunOption.spawnOption?.memoryLimit ??
198-
this.executable.limit.compiler.memory,
199-
pidLimit:
200-
languageRunOption.spawnOption?.pidLimit ??
201-
getConfig().judger.defaultPidLimit,
202-
fileLimit:
203-
languageRunOption.spawnOption?.fileLimit ??
204-
this.executable.limit.compiler.output,
205-
};
206-
207-
const subProc = hengSpawn(command, args, spawnOption);
208-
const procResult = await subProc.result;
209-
await compileLogFileFH.close();
210-
211-
this.fileAgent.register(CompileLogName, CompileLogName);
212-
213-
try {
214-
for (const file of this.configuredLanguage.compiledFiles) {
215-
await fs.promises.access(file);
216-
}
217-
} catch (error) {
218-
procResult.returnCode = procResult.returnCode || 1;
219-
}
220-
221-
const compileStatisticPath = path.resolve(
222-
this.fileAgent.dir,
223-
CompileStatisticName
224-
);
225-
await fs.promises.writeFile(
226-
compileStatisticPath,
227-
JSON.stringify(procResult),
228-
{ mode: 0o700 }
229-
);
230-
this.fileAgent.register(
231-
CompileStatisticName,
232-
CompileStatisticName
233-
);
234-
this.compiled = true;
235-
this.signCompileCache();
236-
return procResult;
237-
} finally {
238-
compileLogFileFH && (await compileLogFileFH.close());
239-
}
241+
const procResult = await this.spawn(languageRunOption, {
242+
args,
243+
cwd,
244+
stdio,
245+
});
246+
this.compiled = true;
247+
this.signCompileCache();
248+
return procResult;
240249
}
241250
}
242251

@@ -259,38 +268,12 @@ export class ExecutableAgent {
259268
if (!this.compiled && !this.compileCached) {
260269
throw new Error("Please compile first");
261270
} else {
262-
const command = languageRunOption.command;
263-
if (!args) {
264-
args = [];
265-
}
266-
if (languageRunOption.args) {
267-
args = [...languageRunOption.args, ...args];
268-
}
269-
270-
const spawnOption: HengSpawnOption = {
271-
cwd:
272-
languageRunOption.spawnOption?.cwd ??
273-
cwd ??
274-
this.fileAgent.dir,
275-
env: languageRunOption.spawnOption?.env,
276-
stdio: stdio,
277-
uid: getConfig().judger.uid,
278-
gid: getConfig().judger.gid,
279-
timeLimit:
280-
languageRunOption.spawnOption?.timeLimit ??
281-
this.executable.limit.runtime.cpuTime,
282-
memoryLimit:
283-
languageRunOption.spawnOption?.memoryLimit ??
284-
this.executable.limit.runtime.memory,
285-
pidLimit:
286-
languageRunOption.spawnOption?.pidLimit ??
287-
getConfig().judger.defaultPidLimit,
288-
fileLimit:
289-
languageRunOption.spawnOption?.fileLimit ??
290-
this.executable.limit.runtime.output,
291-
};
292-
293-
return hengSpawn(command, args, spawnOption).result;
271+
const procResult = await this.spawn(languageRunOption, {
272+
args,
273+
cwd,
274+
stdio,
275+
});
276+
return procResult;
294277
}
295278
}
296279

src/Utilities/File.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export async function chownR(
4040
gid: number,
4141
depth: number
4242
): Promise<void> {
43-
if (depth >= 10) {
43+
if (depth >= 4) {
4444
throw new Error("too deep folder");
4545
}
4646
const curdir = await fs.promises.opendir(dirpath);

0 commit comments

Comments
 (0)