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 con mkfifo(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.
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:
#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
memfd.h
encabezado a menos que quiera usarlo MFD_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 su elfexec
, ya que eso también le permitirá especificar argv[0]
y ejecutará un binario solo desde una tubería (UUoC obligatorio ;-))
.o
archivos en / tmp y morirá si no puede.
Esto ejecutará automáticamente la compilación de su código, pero crea un archivo (temparaily) en el sistema de archivos para poder hacerlo.
echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out
(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.
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
csh
.