1- import fs from "fs" ;
1+ import fs , { readFileSync , writeFileSync } from "fs" ;
22import path from "path" ;
3- import { execSync } from "child_process" ;
3+ import { execSync , spawn } from "child_process" ;
44import {
55 ExecutionResult ,
66 ICompileFile ,
@@ -48,49 +48,70 @@ export const compilerService = {
4848 return { result : "Error to create file" , filePath : "" , file : "" } ;
4949 }
5050 } ,
51- moveFileToIsolate : async (
52- filePath : string ,
53- boxId : number ,
54- ) : Promise < IMoveFile > => {
55- try {
56- const sanboxPath = execSync ( `isolate --init --box-id=${ boxId } ` ) ;
57- execSync ( `mv ${ filePath } ${ sanboxPath . toString ( ) . trim ( ) } /box/` ) ;
58- return { result : "" , sanboxPath : `${ sanboxPath . toString ( ) . trim ( ) } /box` } ;
59- } catch ( error ) {
60- return { result : "Error Move File To isolate" , sanboxPath : "" } ;
61- }
62- } ,
6351 compileFile : async (
64- sanboxPath : string ,
52+ filePath : string ,
6553 language : languageType ,
6654 file : string ,
6755 ) : Promise < ICompileFile > => {
6856 try {
6957 const regex = / \w + / ;
7058 const filenameMatch = file . match ( regex ) ;
59+ let execFolder = ''
60+ let exeFile = ''
7161 if ( ! filenameMatch ) {
7262 throw new Error ( "INVALID_FILEPATH" ) ;
7363 }
74- const fullPath = path . join ( sanboxPath , file ) ;
64+ const folderPath = path . resolve ( __dirname , `../../temp` ) ;
7565 if ( language === languageType . C ) {
66+ execFolder = path . resolve ( folderPath , 'exe-c' )
67+ exeFile = `${ execFolder } /${ filenameMatch } `
68+ if ( ! fs . existsSync ( execFolder ) ) {
69+ fs . mkdirSync ( execFolder , { recursive : true } ) ;
70+ }
7671 execSync (
77- `gcc -w -std=c++14 ${ fullPath } -o ${ sanboxPath } / ${ filenameMatch } ` ,
72+ `gcc -w -std=c++14 ${ filePath } -o ${ exeFile } ` ,
7873 ) ;
7974 } else if ( language === languageType . CPP ) {
75+ execFolder = path . resolve ( folderPath , 'exe-cpp' )
76+ exeFile = `${ execFolder } /${ filenameMatch } `
77+ if ( ! fs . existsSync ( execFolder ) ) {
78+ fs . mkdirSync ( execFolder , { recursive : true } ) ;
79+ }
8080 execSync (
81- `g++ -w -std=c++14 ${ fullPath } -o ${ sanboxPath } / ${ filenameMatch } ` ,
81+ `g++ -w -std=c++14 ${ filePath } -o ${ exeFile } ` ,
8282 ) ;
8383 } else if ( language === languageType . JAVA ) {
84- execSync ( `javac -d ${ sanboxPath } ${ fullPath } ` ) ;
84+ execFolder = path . resolve ( folderPath , 'exe-java' )
85+ exeFile = `${ execFolder } /${ filenameMatch } .class`
86+ if ( ! fs . existsSync ( execFolder ) ) {
87+ fs . mkdirSync ( execFolder , { recursive : true } ) ;
88+ }
89+ execSync ( `javac -d ${ execFolder } ${ filePath } ` ) ;
90+ } else if ( language === languageType . PYTHON ) {
91+ exeFile = `${ filePath } `
8592 }
86- return { result : "" } ;
93+ return { result : "" , exeFile : exeFile } ;
8794 } catch ( error : any ) {
8895 const err = error . stdout . toString ( )
8996 ? error . stdout . toString ( )
9097 : error . stderr . toString ( ) ;
91- return { result : err } ;
98+ return { result : err , exeFile : "" } ;
9299 }
93100 } ,
101+
102+ moveFileToIsolate : async (
103+ exefilePath : string ,
104+ boxId : number ,
105+ ) : Promise < IMoveFile > => {
106+ try {
107+ const sanboxPath = execSync ( `isolate --init --box-id=${ boxId } ` ) ;
108+ execSync ( `cp ${ exefilePath } ${ sanboxPath . toString ( ) . trim ( ) } /box/` ) ;
109+ return { result : "" , sanboxPath : `${ sanboxPath . toString ( ) . trim ( ) } /box` } ;
110+ } catch ( error ) {
111+ return { result : "Error Move File To isolate" , sanboxPath : "" } ;
112+ }
113+ } ,
114+
94115 Run : async (
95116 boxId : number ,
96117 language : languageType ,
@@ -99,34 +120,45 @@ export const compilerService = {
99120 file : string ,
100121 ) : Promise < ExecutionResult > => {
101122 return new Promise ( async ( resolve , _reject ) => {
123+ const inputFile = `${ sanboxPath . toString ( ) . trim ( ) } /input.txt`
124+ const outputFile = `${ sanboxPath . toString ( ) . trim ( ) } /output.txt`
125+ const metaFile = `${ sanboxPath . toString ( ) . trim ( ) } /meta.txt`
126+ writeFileSync ( inputFile , input )
127+ writeFileSync ( outputFile , '' )
128+ writeFileSync ( metaFile , '' )
102129 try {
103- execSync ( `echo ${ input } > ${ sanboxPath . toString ( ) . trim ( ) } /input.txt` ) ;
104130 const filenameMatch = file . match ( / \w + / ) ;
105- let stdout : string = "" ;
131+ let command = '' ;
106132 if ( language === languageType . C || language === languageType . CPP ) {
107- stdout = execSync (
108- `isolate --box-id=${ boxId } --silent --stderr-to-stdout --stdin=input.txt --run ${ filenameMatch } ` ,
109- { encoding : "utf-8" } ,
110- ) ;
111- }
112- else if ( language === languageType . JAVA ) {
113- stdout = execSync (
114- `isolate --box-id=${ boxId } --silent --stderr-to-stdout -p --stdin=input.txt --run /usr/lib/jvm/java-17-openjdk-amd64/bin/java ${ filenameMatch } ` ,
115- { encoding : "utf-8" } ,
116- ) ;
133+ command = `isolate --box-id=${ boxId } --time=5 --wall-time=5 --stderr-to-stdout --stdin=input.txt --stdout=output.txt --meta=${ metaFile } --silent --run ${ filenameMatch } ` ;
134+ } else if ( language === languageType . JAVA ) {
135+ command = `isolate --box-id=${ boxId } --time=5 --wall-time=5 --stderr-to-stdout --stdin=input.txt --stdout=output.txt --meta=${ metaFile } --silent --run /usr/lib/jvm/java-17-openjdk-amd64/bin/java ${ filenameMatch } ` ;
136+ } else if ( language === languageType . PYTHON ) {
137+ command = `isolate --box-id=${ boxId } --time=5 --wall-time=5 --stderr-to-stdout --stdin=input.txt --stdout=output.txt --meta=${ metaFile } --silent --run /usr/bin/python3 ${ file } ` ;
117138 }
118- else if ( language === languageType . PYTHON ) {
119- stdout = execSync (
120- `isolate --box-id=${ boxId } --silent --stderr-to-stdout --stdin=input.txt --run /usr/bin/python3 ${ file } ` ,
121- { encoding : "utf-8" } ,
122- ) ;
123- }
124- resolve ( { result : stdout . toString ( ) } ) ;
125- } catch ( error : any ) {
126- const err = error . stdout . toString ( )
127- ? error . stdout . toString ( )
128- : error . stderr . toString ( ) ;
129- resolve ( { result : err } ) ;
139+ const childProcess = spawn ( command , { shell : true } ) ;
140+
141+ // Handle process exit
142+ childProcess . on ( 'exit' , ( ) => {
143+ const metaContent = readFileSync ( metaFile , 'utf-8' ) ;
144+ const output = readFileSync ( outputFile , 'utf-8' ) ;
145+
146+ const lines = metaContent . split ( '\n' ) ;
147+ const status = lines . find ( ( line ) => line . startsWith ( 'status:' ) ) ?. split ( ':' ) [ 1 ] ?. trim ( ) || '' ;
148+ const exitCode = lines . find ( ( line ) => line . startsWith ( 'exitCode:' ) ) ?. split ( ':' ) [ 1 ] ?. trim ( ) || '' ;
149+
150+ if ( status === 'TO' ) {
151+ resolve ( { result : 'Execution Time Out' } ) ;
152+ } else if ( exitCode !== '0' ) {
153+ resolve ( { result : output } ) ;
154+ } else {
155+ resolve ( { result : output } ) ;
156+ }
157+
158+ } ) ;
159+
160+ } catch ( error ) {
161+ resolve ( { result : 'error execute' } ) ;
130162 }
131163 } ) ;
132164 } ,
0 commit comments