Ответы:
Я не верю, что это возможно. Exec (2) системный вызов всегда требует имя файла или абсолютный путь (имя файла всегда char*
). posix_spawn
также имеет аналогичные требования для имени файла.
Самое близкое, что вы можете сделать, это направить вывод в именованный канал и попытаться выполнить его из канала. Это может сработать, хотя оболочка может отказаться выполнять любой файл, для которого не установлены --x--x--x
биты. Создайте трубу с помощью mkfifo(1)
и посмотрите, сможете ли вы заставить ее работать.
Другой подход состоит в том, чтобы написать что-то, что читает стандартный ввод, записывает файл во временную область, устанавливает для него биты --x, разветвляется и исполняет, а затем удаляет файл. Индекс и содержимое останутся до тех пор, пока не завершится выполнение программы, но не будут доступны через файловую систему. Когда процесс завершится, индекс будет освобожден, и хранилище будет возвращено в свободный список.
РЕДАКТИРОВАТЬ: Как указывает Mat, первый подход не будет работать, так как загрузчик будет пытаться запросить страницу в исполняемом файле, который будет генерировать трафик случайного поиска по файлу, а это невозможно на конвейере. Это оставляет какой-то подход, как второй.
Решение с использованием системного вызова memfd: 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
(Я сейчас проверяю это сейчас, но я почти уверен, что или что-то близкое к этому подойдет вам)
РЕДАКТИРОВАТЬ: Если цель вашего трубопровода состоит в том, чтобы вырезать физические диски из уравнения для скорости, подумайте о создании оперативного диска для хранения промежуточного файла.
csh
.
Точно так же, как предложил @TheQUUX , я сам не тестировал, но вы можете попробовать cling
- «интерактивный интерпретатор C ++, построенный на основе библиотек LLVM и Clang».
Более подробную информацию можно найти здесь: https://cdn.rawgit.com/root-project/cling/master/www/index.html.
csh
.