File size: 2,786 Bytes
1e75d97 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import gradio as gr
import subprocess, tempfile, os, uuid, resource
# --- Función principal --------------------------------------------------------
def compile_and_run(code: str, stdin: str = "") -> str:
"""
Compila el código C, lo ejecuta y devuelve la salida (stdout + stderr).
Se aplican límites de tiempo y memoria para evitar abusos.
"""
# 1. Crear carpeta temporal única
tmpdir = tempfile.mkdtemp(prefix="c_exec_")
c_path = os.path.join(tmpdir, "main.c")
bin_path = os.path.join(tmpdir, "main")
# 2. Guardar código
with open(c_path, "w") as f:
f.write(code)
# 3. Compilar
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:
return f"❌ Error de compilación:\n{compile_proc.stderr}"
# 4. Establecer límites de recursos antes de ejecutar
def limit_resources():
resource.setrlimit(resource.RLIMIT_CPU, (2, 2)) # 2 s CPU
resource.setrlimit(resource.RLIMIT_AS, (128*1024*1024, # 128 MB
128*1024*1024))
# 5. Ejecutar binario generado
try:
run_proc = subprocess.run(
[bin_path],
input=stdin,
text=True,
capture_output=True,
timeout=2, # tiempo real (wall-clock)
preexec_fn=limit_resources
)
except subprocess.TimeoutExpired:
return "⏰ Tiempo de ejecución excedido (2 s)."
out = run_proc.stdout
err = run_proc.stderr
exit = run_proc.returncode
response = f"⏹ Código de salida: {exit}\n"
if out:
response += f"\n📤 STDOUT\n{out}"
if err:
response += f"\n⚠️ STDERR\n{err}"
return response.strip()
# --- UI en Gradio -------------------------------------------------------------
title = "Compilador C online (42 Edition)"
description = """
Ejecuta fragmentos de **lenguaje C** con límite de recursos.
También disponible como endpoint REST (`/run/predict`).
"""
demo = gr.Interface(
fn = compile_and_run,
inputs = [
gr.Code(language="c", 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 = [
[r"#include <stdio.h>\nint main(){printf(\"Hola 42!\\n\");}", ""],
[r"#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() |