Respostas:
Não acredito que isso seja possível. A chamada do sistema exec (2) sempre exige um nome de arquivo ou caminho absoluto (o nome do arquivo é sempre a char*
). posix_spawn
também possui requisitos semelhantes para um nome de arquivo.
O mais próximo que você pode fazer é canalizar a saída para um canal nomeado e tentar executar a partir do canal. Isso pode funcionar, embora o shell possa se recusar a executar qualquer arquivo que não tenha os --x--x--x
bits definidos. Crie o pipe mkfifo(1)
e veja se consegue fazê-lo funcionar.
Outra abordagem seria escrever algo que leia a entrada padrão, grave um arquivo em uma área temporária, defina os bits --x nele, garfos e execs e exclua o arquivo. O inode e o conteúdo permanecerão até que o programa termine a execução, mas não será acessível pelo sistema de arquivos. Quando o processo termina, o inode será liberado e o armazenamento retornará à lista gratuita.
EDIT: Como aponta Mat, a primeira abordagem não funcionará, pois o carregador tentará exigir a página no executável, o que gerará tráfego de busca aleatória no arquivo, e isso não é possível em um canal. Isso deixa algum tipo de abordagem como a segunda.
Uma solução usando o memfd syscall: https://github.com/abbat/elfexec
Ele cria um descritor de arquivo nomeado na memória que pode ser usado no exec
. Um pseudocódigo:
#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
memfd.h
cabeçalho, a menos que queira usá-lo MFD_CLOEXEC
(o que interromperá os #! /bin/sh
scripts por causa de erros no linux ' fexecve()
). Isso não é muito complicado, você pode incluir uma amostra de trabalho de 20 linhas em sua resposta (por exemplo, este git gist - embora isso não seja um substituto para o seu elfexec
, pois isso também permitirá que você especifique argv[0]
e executará um binário apenas a partir de um tubo (UUoC mandato ;-))
.o
arquivos em / tmp e morrerá, se não puder.
Isso executará automaticamente a compilação do seu código, mas criará um arquivo (temparaily) no sistema de arquivos para fazê-lo.
echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out
No momento, estou testando isso agora, mas tenho certeza disso ou algo próximo funcionará para você
EDIT: Se o objetivo da sua tubulação é cortar discos físicos da equação de velocidade, considere criar um disco ram para armazenar o arquivo intermediário.
csh
.
Assim como o @TheQUUX sugeriu, eu ainda não testei, mas você pode experimentar cling
- "o interpretador C ++ interativo, construído sobre as bibliotecas LLVM e Clang".
Encontre mais informações aqui: https://cdn.rawgit.com/root-project/cling/master/www/index.html
csh
.