Pergunta

Estou tentando criar um shell simples em C para o Unix. Consegui fazer toda a análise de comandos e execução, mas estou tendo um problema com a tubulação. Eu acho que o problema é que não estou conectando o tubo correto para a entrada do segundo comando.

Por exemplo, se eu digitar "LS | WC", ele fará uma pausa após o comando "WC", que eu acho que é porque está esperando a entrada. Eu acho que o problema é quando eu uso o DUP2 (lendo [i], 0), e não está entrando no tubo correto.

Eu sei que isso é uma pergunta ampla, mas se houver algum débito que eu pudesse obter, eu apreciaria. Aqui está o código que cria novos processos e tenta tubá -los.

    int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)    //Create pipes for commands
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg); //Get command and args

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    dup2(writing[i],1);
                    close(writing[i]);
                }

                if(reading[i] != -1)
                {
                    dup2(reading[i],0);
                    close(reading[i]);
                }

                int h;
                for(h = 0; h < num_cmds; h++)
                {
                    close(writing[h]);
                    close(reading[h]);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {
                wait(&status);
                int m;
                for(m = 0; m < num_cmds; m++)
                {
                    if( writing[m] != -1) close(writing[m]);
                    if( reading[m] != -1) close(reading[m]);
                }
            }
        }
        else 
        {
             perror("fork"); 
             continue;
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }

}



ATUALIZAÇÃO: Consegui descobrir, graças a Richard. Foi uma combinação de fechar os descritores de arquivo na ordem errada e não fechar alguns. Aqui está o código de trabalho.

int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg);

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    close(1);
                    dup2(writing[i],1);
                }

                if(reading[i] != -1)
                {
                    close(0);
                    dup2(reading[i],0);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {

                wait(&status);
                close(writing[i]);

                if(i > 0) 
                {
                    close(reading[i]);
                }
            }
        }
        else 
        {
             perror("fork");
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }
Foi útil?

Solução

Acho que seu problema pode ser que você aguarde cada processo dentro do loop e, em seguida, feche todos os descritores de arquivo. Isso torna os descritores de arquivo inválidos para a próxima chamada para Dup2 () e resulta em Stdin para o próximo processo permanecendo inalterado.

Apenas um palpite, eu não executei o código.

Outras dicas

Quando eu digito "LS | WC", o WC faz o esperado e imprime o número de palavras em saída pelo comando LS. Lembre -se de que quando você está tubulando comandos usando "|" Você não precisa criar tubos em seu aplicativo. O primeiro comando precisa emitir para Stdout e o segundo comando precisa ler essa saída do padrão in.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top