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 \nint main(){printf(\"Hola 42!\\n\");}", ""], [r"#include \nint main(){int a,b;scanf(\"%d %d\",&a,&b);printf(\"%d\\n\",a+b);}", "3 4"] ], ) if __name__ == "__main__": demo.launch()