echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
Есть ли способ запустить выходной двоичный файл в Unix-подобной системе?
EDIT: мне нужно было его запустить вывод г ++ в изолированном окружении , где я не могу писать какой - либо файл (ничего злонамеренного, я обещаю).
shell
executable
stdout
Алекс Б
источник
источник
csh
.Ответы:
Я не верю, что это возможно. Exec (2) системный вызов всегда требует имя файла или абсолютный путь (имя файла всегда
char*
).posix_spawn
также имеет аналогичные требования для имени файла.Самое близкое, что вы можете сделать, это направить вывод в именованный канал и попытаться выполнить его из канала. Это может сработать, хотя оболочка может отказаться выполнять любой файл, для которого не установлены
--x--x--x
биты. Создайте трубу с помощьюmkfifo(1)
и посмотрите, сможете ли вы заставить ее работать.Другой подход состоит в том, чтобы написать что-то, что читает стандартный ввод, записывает файл во временную область, устанавливает для него биты --x, разветвляется и исполняет, а затем удаляет файл. Индекс и содержимое останутся до тех пор, пока не завершится выполнение программы, но не будут доступны через файловую систему. Когда процесс завершится, индекс будет освобожден, и хранилище будет возвращено в свободный список.
РЕДАКТИРОВАТЬ: Как указывает Mat, первый подход не будет работать, так как загрузчик будет пытаться запросить страницу в исполняемом файле, который будет генерировать трафик случайного поиска по файлу, а это невозможно на конвейере. Это оставляет какой-то подход, как второй.
источник
Решение с использованием системного вызова memfd: https://github.com/abbat/elfexec
Он создает именованный дескриптор файла в памяти, который может быть использован в
exec
. Псевдокод:источник
memfd.h
заголовок, если вы не хотите его использоватьMFD_CLOEXEC
(что приведет к поломке#! /bin/sh
скриптов из-за ошибок в linux 'fexecve()
). Это не так уж сложно, вы можете включить в ваш ответ 20-строчный рабочий пример (например, этот git gist - хотя это не является заменой для васelfexec
, так как это также позволит вам указатьargv[0]
и запустит двоичный файл). только из трубы (UUoC поручено ;-)).o
файлы в / tmp и умрет, если не сможет.Вы можете попробовать tcc , который скомпилирует и выполнит программу за один шаг, без записи каких-либо промежуточных файлов. Это не GCC, что может быть проблемой для вас, но это невероятно быстро, поэтому он может даже поставить лучше, чем GCC для ваших целей.
источник
Это автоматически запустит компиляцию вашего кода, но создаст файл (временно) в файловой системе, чтобы сделать это.
(Я сейчас проверяю это сейчас, но я почти уверен, что или что-то близкое к этому подойдет вам)
РЕДАКТИРОВАТЬ: Если цель вашего трубопровода состоит в том, чтобы вырезать физические диски из уравнения для скорости, подумайте о создании оперативного диска для хранения промежуточного файла.
источник
csh
.Точно так же, как предложил @TheQUUX , я сам не тестировал, но вы можете попробовать
cling
- «интерактивный интерпретатор C ++, построенный на основе библиотек LLVM и Clang».Более подробную информацию можно найти здесь: https://cdn.rawgit.com/root-project/cling/master/www/index.html.
источник