Odpowiedzi:
Nie wierzę, że to jest możliwe. Exec (2) połączenie systemu zawsze wymaga pliku lub całkowitej ścieżki (nazwa pliku jest zawsze char*). posix_spawnma również podobne wymagania dotyczące nazwy pliku.
Najbliższe, co możesz zrobić, to przesłać wyjście do nazwanego potoku i spróbować wykonać z potoku. Może to działać, chociaż powłoka może odmówić wykonania dowolnego pliku, który nie ma --x--x--xustawionych bitów. Utwórz potok za pomocą mkfifo(1)i sprawdź, czy możesz go uruchomić.
Innym podejściem byłoby napisanie czegoś, co odczytuje standardowe dane wejściowe, zapisuje plik do obszaru tymczasowego, ustawia na nim bity --x, rozwidla i wykonuje, a następnie usuwa plik. I-węzeł i zawartość pozostaną, dopóki program nie zakończy działania, ale nie będzie dostępny przez system plików. Po zakończeniu procesu i-węzeł zostanie zwolniony, a pamięć masowa zostanie zwrócona na bezpłatną listę.
EDYCJA: Jak zauważa Mat, pierwsze podejście nie zadziała, ponieważ moduł ładujący spróbuje wywołać stronę w pliku wykonywalnym, co wygeneruje losowy ruch związany z wyszukiwaniem pliku, a nie jest to możliwe w potoku. To pozostawia jakieś podejście jak drugie.
Rozwiązanie wykorzystujące system memfd syscall: https://github.com/abbat/elfexec
Tworzy nazwany deskryptor pliku w pamięci, który można wykorzystać w exec. Pseudokod:
#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
memfd.hnagłówka, chyba że chcesz go użyć MFD_CLOEXEC(który zepsuje #! /bin/shskrypty z powodu błędów w systemie Linux fexecve()). To nie jest zbyt skomplikowane, możesz dołączyć 20-liniową próbkę roboczą do swojej odpowiedzi (np. Ten git gist - chociaż nie jest to zamiana drop-in dla ciebie elfexec, ponieważ pozwoli ci to określić argv[0]i uruchomi binarny tylko z fajki (mandat UUoC ;-))
.opliki w / tmp i umrze, jeśli nie będzie.
Spowoduje to automatyczne uruchomienie kompilacji kodu, ale w tym celu utworzy plik (tymczasowo) w systemie plików.
echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out
(Obecnie testuję to teraz, ale jestem całkiem pewien, że to, czy coś blisko to zadziała dla Ciebie)
EDYCJA: Jeśli celem twojego rurociągu jest wycięcie dysków fizycznych z równania prędkości, rozważ utworzenie dysku RAM, który pomieści plik pośredni.
csh.
Tak jak sugerował @TheQUUX , nie testowałem go sam, ale możesz wypróbować cling- „interaktywny interpreter C ++, zbudowany na bibliotekach LLVM i Clang”.
Znajdź więcej informacji tutaj: https://cdn.rawgit.com/root-project/cling/master/www/index.html
csh.