1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

help em c, redirecionamento

Discussão em 'Programação' iniciada por markoni, 27 de Maio de 2008. (Respostas: 5; Visualizações: 1137)

  1. markoni

    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?
     
  2. The_True_Eue

    The_True_Eue Power Member

    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: 28 de Maio de 2008
  3. markoni

    markoni Power Member

    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
     
  4. The_True_Eue

    The_True_Eue Power Member

    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);
     
  5. markoni

    markoni Power Member

    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: 4 de Junho de 2008
  6. The_True_Eue

    The_True_Eue Power Member

    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.
     

Partilhar esta Página