Відповіді:
Я не вірю, що це можливо. Exec (2) системний виклик завжди вимагає ім'я файлу або абсолютний шлях (ім'я файлу завжди char*
). posix_spawn
також має подібні вимоги до імені файлу.
Найближче, що ви могли зробити, це передати висновок у названу трубу та спробувати виконати з труби. Це може спрацювати, хоча оболонка може відмовитись виконувати будь-який файл, у якому не встановлені --x--x--x
біти. Створіть трубу за допомогою mkfifo(1)
і подивіться, чи зможете ви її працювати.
Іншим підходом було б написати щось, що читає стандартне введення, записує файл у область темпорай, встановлює на нього --x біти, forks та execs, а потім видаляє файл. Вкладення та вміст залишатимуться до тих пір, поки програма не завершить виконання, але вона не буде доступною через файлову систему. Коли процес закінчиться, inode буде звільнений, а зберігання повернеться у вільний список.
EDIT: Як зазначає Мат, перший підхід не працюватиме, оскільки завантажувач намагатиметься виконати запит на сторінку у виконуваному файлі, що генеруватиме трафік випадкових запитів у файлі, а це неможливо в трубі. Це залишає такий собі підхід, як другий.
Рішення за допомогою memfd syscall: https://github.com/abbat/elfexec
Він створює іменований дескриптор файлу в пам'яті, який може бути використаний в exec
. Псевдокод:
#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
memfd.h
заголовок, якщо ви не хочете використовувати MFD_CLOEXEC
(що порушить #! /bin/sh
сценарії через помилки в Linux ' fexecve()
). Це не надто складно, ви можете включити у свою відповідь 20-рядковий робочий зразок (наприклад, цей git gist - хоча це не є заміною для переходу для вашого elfexec
, оскільки це також дозволить вам вказати argv[0]
і запустить двійковий код тільки з труби (UUoC мандат ;-))
.o
файли в / tmp і помре, якщо не може.
Це автоматично запустить компіляцію вашого коду, але створить файл (тимчасово) у файловій системі для того, щоб це зробити.
echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out
(Я зараз тестую це зараз, але я майже впевнений, що це чи щось наближене до вас спрацює)
EDIT: Якщо метою ваших трубопроводів є скорочення фізичних дисків з рівняння для швидкості, подумайте про створення оперативного диска для зберігання проміжного файлу.
csh
.
Так само, як запропонував @TheQUUX , я не перевіряв це на своєму, але ви можете спробувати cling
- "інтерактивний інтерпретатор C ++, побудований на базі бібліотек LLVM та Clang."
Дізнайтеся більше тут: https://cdn.rawgit.com/root-project/cling/master/www/index.html
csh
.