help em c, redirecionamento

markoni

Power Member
boas, redirecionamento
Pretendo ler o conteudo de um ficheiro pr a console usando o "execvp"(ou outro como este)
tipo:por na console "cat < fich.txt" e que o conteudo do ficheiro apareça no ecra
:::::::::::::::::::::::::::
int fd=open(Arg[2],O_RDONLY,0600);
if (fd==-1){perror("main: exec");return 1;}

execv(Arg[0],Arg[2]);
:::::::::::::::::::::::::::::
onde Arg[2] é o nome do ficheiro e Arg[0] é o comando
exemplo:Arg[2] contem o "fich.txt" e Arg[0] o "cat"

Alguem me diz o que está mal?
 
O que é o 0600 como terceiro argumento de open? Se bem me lembro são as permissões... devias usar as constantes que estão definidas: S_IRUSR, S_IWUSR, S_IXUSR, entre outras. Fica muito melhor o código.
Mas o problema não está aí de certeza. Porque o terceiro parâmetro de open é ignorado se no segundo (flags) não estiver O_CREAT...

O problema está no execvp(). O segundo parâmetro deve ser:
"A null terminated array of null-terminated strings."
Até aqui tudo bem. Mas o primeiro elemento desse array deve ser o nome do programa que é executado. Os parâmetros que recebes na main(int argc, char* argv[]) são exactamente no mesmo formato que esses. O execvp vai copiá-los direitinhos para a função main() do cat...
O que estás a fazer é: correr o cat, dizer-lhe que se chama fich.txt, e não recebe parâmetros.
Devias passar "cat" como primeiro argumento e a lista com "cat", "fich.txt", NULL no segundo.

Ao que parece querias tirar o "<" no meio... Tens de passar o Arg[2] para Arg[1] e por o terminador NULL em Arg[2]*. Assim depois fazes: execvp(Arg[0], Arg);

Se quiseres usar o execlp fica mais fácil: execlp(Arg[0], Arg[0], Arg[2], NULL);

Mais alguma questão?

P.S: O que estás a fazer NÃO É REDIRECIONAMENTO! Para redirecionamento tens de usar dup()/dup2()... Se o que queres é mesmo redirecionamento... podes apagar o que tens porque vais chumbar... :002:

* Também fazia falta libertar memória...
 
Última edição:
int fd=open(Argumentos[2],O_RDONLY,0600);
if (fd==-1){perror("main: exec");return 1;}
dup2(fd,0);
execvp(Argumentos[0],(char*)0);


Diga-mos que assim resolvi o problem
 
Só falta uma coisa... Um pequeno pormenor, que neste caso não faz estragos mas é bom reter: Está a "leakar" descritores. Antes do exec, fecha o fd -> close(fd);
 
Código:
if(j==0){
                        close(fd[0]);
                        dup2(fd[1],STDOUT_FILENO);
                        close(fd[1]);close(fd);
                        execvp(Argumentos[0],Argumentos);
                        }
                       else{
                        close(fd[1]);
                        dup2(fd[0],STDIN_FILENO);
                        close(fd[0]);close(fd);
                        execvp(Argumentos[0],Argumentos);

tenho um for a correr duas vez antes disto onde cria um fork em cada passagem( são 2)
onde vou passar por aqui duas vez, uma j=0 e outra j=1...isto para fazer ls | wc por exemplo, onde para j=0 tras como argumentos o ls e pr j=1 tras os dados do wc......
Não está a funcionar...alguem diz porque?
 
Última edição pelo moderador:
Não deve ser isto, mas não podes fechar um vector => close(fd). Essa instrução está a mais.
Não te esqueças de fechar ambos os lados do pipe no processo pai!
Podes comparar o teu código com o que está no repositório em sticky.
 
Back
Topo