echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
Czy istnieje sposób na uruchomienie wyjściowego pliku binarnego w systemie uniksopodobnym?
EDYCJA: Potrzebowałem go do uruchomienia wyjścia g ++ w środowisku piaskownicy, w którym nie mogę napisać żadnego pliku (nic złego, obiecuję).
shell
executable
stdout
Alex B.
źródło
źródło
csh
.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.
źródło
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:źródło
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 Linuxfexecve()
). 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 ciebieelfexec
, 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.Możesz spróbować tcc , który skompiluje i uruchomi program w jednym kroku, bez zapisywania plików pośrednich. To nie jest gcc, co może być dla ciebie problemem, ale jest spektakularnie szybki, więc może nawet postawić lepiej niż gcc dla twoich celów.
źródło
Spowoduje to automatyczne uruchomienie kompilacji kodu, ale w tym celu utworzy plik (tymczasowo) w systemie plików.
(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.
źródło
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
źródło