echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
Existe uma maneira de executar o binário de saída em um sistema semelhante ao Unix?
EDIT: Eu precisava executar a saída do g ++ em um ambiente de área restrita onde não posso gravar nenhum arquivo (nada de malicioso, prometo).
shell
executable
stdout
Alex B
fonte
fonte
csh
.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 pipemkfifo(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.
fonte
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:fonte
memfd.h
cabeçalho, a menos que queira usá-loMFD_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 seuelfexec
, pois isso também permitirá que você especifiqueargv[0]
e executará um binário apenas a partir de um tubo (UUoC mandato ;-)).o
arquivos em / tmp e morrerá, se não puder.Você pode tentar o tcc , que irá compilar e executar um programa em uma etapa, sem gravar nenhum arquivo intermediário. Não é o gcc, o que pode ser um problema para você, mas é espetacularmente rápido; portanto, pode até apostar melhor que o gcc para seus propósitos.
fonte
Isso executará automaticamente a compilação do seu código, mas criará um arquivo (temparaily) no sistema de arquivos para fazê-lo.
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.
fonte
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
fonte