Risposte:
Non credo sia possibile. La chiamata di sistema exec (2) richiede sempre un nome file o un percorso assoluto (il nome file è sempre a char*
). posix_spawn
ha anche requisiti simili per un nome file.
Il più vicino che puoi fare è reindirizzare l'output in una pipe denominata e provare a eseguirlo dalla pipe. Potrebbe funzionare, sebbene la shell possa rifiutare di eseguire qualsiasi file che non abbia i --x--x--x
bit impostati. Crea la pipa con mkfifo(1)
e vedi se riesci a farlo funzionare.
Un altro approccio sarebbe quello di scrivere qualcosa che legga l'input standard, scriva un file in un'area temporanea, imposta i bit --x su di esso, forchette ed esecuzioni quindi elimina il file. L'inode e il contenuto rimarranno fino al termine dell'esecuzione del programma ma non saranno accessibili tramite il file system. Al termine del processo, l'inode verrà rilasciato e la memoria verrà restituita all'elenco gratuito.
EDIT: Come sottolinea Mat, il primo approccio non funzionerà poiché il caricatore tenterà di richiedere la pagina nell'eseguibile, il che genererà traffico di ricerca casuale sul file e questo non è possibile su una pipe. Questo lascia una sorta di approccio come il secondo.
Una soluzione che utilizza memfd syscall: https://github.com/abbat/elfexec
Crea un descrittore di file con nome in memoria che può essere utilizzato in exec
. Uno pseudo-codice:
#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
memfd.h
dell'intestazione a meno che tu non voglia usare MFD_CLOEXEC
(che romperà gli #! /bin/sh
script a causa di bug in Linux ' fexecve()
). Non è troppo complicato, puoi includere un campione di lavoro a 20 righe nella tua risposta (ad es. Questo git gist - anche se non è un rimpiazzo sostitutivo per il tuo elfexec
, dal momento che ciò ti permetterà anche di specificare argv[0]
ed eseguirà un binario solo da una pipa (UUoC obbligatorio ;-))
.o
file su / tmp e morirà se non ci riesce.
Questo eseguirà automaticamente la compilazione del tuo codice, ma crea un file (temporaneo) sul filesystem per farlo.
echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out
(Attualmente sto testando questo ora, ma sono abbastanza sicuro, o qualcosa di simile funzionerà per te)
EDIT: se l'obiettivo delle tubazioni è tagliare i dischi fisici fuori dall'equazione per la velocità, prendere in considerazione la creazione di un disco ram per contenere il file intermedio.
csh
.
Proprio come suggerito da @TheQUUX , non l'ho testato da solo, ma potresti provare cling
- "l'interprete interattivo C ++, basato sulle librerie LLVM e Clang".
Maggiori informazioni qui: https://cdn.rawgit.com/root-project/cling/master/www/index.html
csh
.