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_spawn
ma 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--x
ustawionych 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.h
nagłówka, chyba że chcesz go użyć MFD_CLOEXEC
(który zepsuje #! /bin/sh
skrypty 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 ;-))
.o
pliki 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
.