|
import gradio as gr |
|
import subprocess, tempfile, os, resource, shutil |
|
|
|
|
|
|
|
|
|
|
|
def compile_and_run(code: str, stdin: str = "") -> str: |
|
""" |
|
Compila el código C recibido, lo ejecuta con límites de |
|
recursos y devuelve stdout, stderr y exit-code. |
|
""" |
|
tmpdir = tempfile.mkdtemp(prefix="c_exec_") |
|
c_path = os.path.join(tmpdir, "main.c") |
|
bin_path = os.path.join(tmpdir, "main") |
|
|
|
|
|
with open(c_path, "w") as f: |
|
f.write(code) |
|
|
|
|
|
compile_proc = subprocess.run( |
|
["gcc", c_path, "-O2", "-std=c11", "-pipe", "-o", bin_path], |
|
capture_output=True, |
|
text=True, |
|
timeout=10 |
|
) |
|
if compile_proc.returncode != 0: |
|
shutil.rmtree(tmpdir, ignore_errors=True) |
|
return f"❌ Error de compilación:\n{compile_proc.stderr}" |
|
|
|
|
|
def limit_resources(): |
|
resource.setrlimit(resource.RLIMIT_CPU, (2, 2)) |
|
resource.setrlimit(resource.RLIMIT_AS, (128 * 1024 * 1024, |
|
128 * 1024 * 1024)) |
|
|
|
try: |
|
run_proc = subprocess.run( |
|
[bin_path], |
|
input=stdin, |
|
text=True, |
|
capture_output=True, |
|
timeout=2, |
|
preexec_fn=limit_resources |
|
) |
|
except subprocess.TimeoutExpired: |
|
shutil.rmtree(tmpdir, ignore_errors=True) |
|
return "⏰ Tiempo de ejecución excedido (2 s)." |
|
|
|
stdout, stderr = run_proc.stdout, run_proc.stderr |
|
exit_code = run_proc.returncode |
|
|
|
shutil.rmtree(tmpdir, ignore_errors=True) |
|
|
|
result = f"⏹ Código de salida: {exit_code}\n" |
|
if stdout: |
|
result += f"\n📤 STDOUT\n{stdout}" |
|
if stderr: |
|
result += f"\n⚠️ STDERR\n{stderr}" |
|
return result.strip() |
|
|
|
|
|
|
|
|
|
|
|
|
|
def detect_c_language() -> str: |
|
langs = getattr(gr.Code, "languages", []) |
|
return "c" if "c" in langs else "cpp" |
|
|
|
code_lang = detect_c_language() |
|
|
|
|
|
|
|
|
|
|
|
title = "Compilador C online (42 Edition)" |
|
description = ( |
|
"Ejecuta fragmentos de **lenguaje C** con límite de recursos.\n" |
|
"Disponible también como endpoint REST (`/run/predict`)." |
|
) |
|
|
|
demo = gr.Interface( |
|
fn=compile_and_run, |
|
inputs=[ |
|
gr.Code(language=code_lang, label="Código C"), |
|
gr.Textbox( |
|
lines=3, |
|
placeholder="Entrada estándar (stdin)", |
|
label="Stdin (opcional)" |
|
), |
|
], |
|
outputs=gr.Textbox(label="Resultado"), |
|
title=title, |
|
description=description, |
|
examples=[ |
|
["#include <stdio.h>\nint main(){puts(\"Hola 42!\");}", ""], |
|
["#include <stdio.h>\nint main(){int a,b;scanf(\"%d %d\",&a,&b);" |
|
"printf(\"%d\\n\",a+b);}", "3 4"], |
|
], |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |