echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
¿Hay alguna manera de ejecutar el binario de salida en un sistema tipo Unix?
EDITAR: lo necesitaba para ejecutar la salida de g ++ en un entorno de espacio aislado donde no puedo escribir ningún archivo (nada malicioso, lo prometo).
shell
executable
stdout
Alex B
fuente
fuente
csh
.Respuestas:
No creo que esto sea posible. La llamada al sistema exec (2) siempre requiere un nombre de archivo o ruta absoluta (el nombre de archivo siempre es a
char*
).posix_spawn
también tiene requisitos similares para un nombre de archivo.Lo más cercano que puede hacer es canalizar la salida en una tubería con nombre e intentar ejecutar desde la tubería. Eso puede funcionar, aunque el shell puede negarse a ejecutar cualquier archivo que no tenga los
--x--x--x
bits establecidos. Cree la tubería conmkfifo(1)
y vea si puede hacer que funcione.Otro enfoque sería escribir algo que lea la entrada estándar, escriba un archivo en un área de temporay, establezca los bits --x, bifurcaciones y ejecutivos y luego elimine el archivo. El inodo y el contenido permanecerán hasta que el programa termine de ejecutarse, pero no será accesible a través del sistema de archivos. Cuando finalice el proceso, se liberará el inodo y el almacenamiento se devolverá a la lista libre.
EDITAR: como señala Mat, el primer enfoque no funcionará ya que el cargador intentará exigir la página en el ejecutable, lo que generará tráfico de búsqueda aleatorio en el archivo, y esto no es posible en una tubería. Esto deja algún tipo de enfoque como el segundo.
fuente
Una solución usando memfd syscall: https://github.com/abbat/elfexec
Crea un descriptor de archivo con nombre en la memoria que podría usarse en
exec
. Un pseudocódigo:fuente
memfd.h
encabezado a menos que quiera usarloMFD_CLOEXEC
(lo que romperá los#! /bin/sh
scripts debido a errores en linux 'fexecve()
). Eso no es demasiado complicado, puede incluir una muestra de trabajo de 20 líneas en su respuesta (por ejemplo, este git gist , aunque eso no es un reemplazo directo para suelfexec
, ya que eso también le permitirá especificarargv[0]
y ejecutará un binario solo desde una tubería (UUoC obligatorio ;-)).o
archivos en / tmp y morirá si no puede.Puede probar tcc , que compilará y ejecutará un programa en un solo paso, sin escribir ningún archivo intermedio. No es gcc, lo que puede ser un problema para usted, pero es espectacularmente rápido, por lo que incluso puede apostar mejor que gcc para sus propósitos.
fuente
Esto ejecutará automáticamente la compilación de su código, pero crea un archivo (temparaily) en el sistema de archivos para poder hacerlo.
(Actualmente estoy probando esto ahora, pero estoy bastante seguro de que esto, o algo similar funcionará para usted)
EDITAR: Si el objetivo de su tubería es cortar discos físicos fuera de la ecuación para la velocidad, considere crear un disco RAM para contener el archivo intermedio.
fuente
csh
.Tal como sugirió @TheQUUX , no lo he probado por mí mismo, pero es posible que desee probar
cling
: "el intérprete interactivo de C ++, creado sobre las bibliotecas LLVM y Clang".Encuentre más información aquí: https://cdn.rawgit.com/root-project/cling/master/www/index.html
fuente