import gradio as gr import subprocess, tempfile, os, resource, shutil # ------------------------------------------------------------------ # 1️⃣ Función que compila y ejecuta el código C # ------------------------------------------------------------------ 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") # Guardar el código fuente with open(c_path, "w") as f: f.write(code) # 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: shutil.rmtree(tmpdir, ignore_errors=True) return f"❌ Error de compilación:\n{compile_proc.stderr}" # Límites (CPU 2 s, RAM 128 MB) 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() # ------------------------------------------------------------------ # 2️⃣ Detección automática del lenguaje para gr.Code # ('c' en Gradio ≥4, 'cpp' en Gradio 3) # ------------------------------------------------------------------ def detect_c_language() -> str: langs = getattr(gr.Code, "languages", []) return "c" if "c" in langs else "cpp" code_lang = detect_c_language() # ------------------------------------------------------------------ # 3️⃣ Construcción de la interfaz # ------------------------------------------------------------------ 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 \nint main(){puts(\"Hola 42!\");}", ""], ["#include \nint main(){int a,b;scanf(\"%d %d\",&a,&b);" "printf(\"%d\\n\",a+b);}", "3 4"], ], ) if __name__ == "__main__": demo.launch()