0

わかりました、このコードには 2 つの主要な問題があります。

1: 親は子が印刷するのを待たずに、メインに戻って印刷します。waitpid() を含めましたが、期待どおりに機能していないようです。

  1. リダイレクトすると、ファイルは正常に作成されますが、nano と vim はファイルを「表示」しませんが、Gedit は表示できます (したがって、出力が正しく送信されていることがわかります)。

この関数の流れ:

文字列が入力され、文字列の末尾の & がチェックされます (存在する場合は削除され、バックグラウンド フラグが更新されます)。

次に、文字列は '|' でトークン化されます。
各トークンは '<' と '>' でトークン化され、それから各文字列は ' ' でトークン化されます。結果の char ** が実行され、上記のトークン化の結果に基づいて出力/入力がリダイレクトされます。

    void execute_command(char * s)
    {
        printf("\n");
        int fd[3][2]; //  since we are guaranteed each type of redirection will be used only once, I only need 3 pipes:  <  >  and |
        //int fd[2];    
        int res;
        pid_t pid;
        int status;
        int stdin_c = dup(0);
        int stdout_c = dup(1);
        int i;
        int background = 0;

        for(i = 0; s[i] != '\0'; i++);
            if(s[i-1] == '&')
            {
                background = 1;
                s[i-1] = '\0';
            }

        char ** piped = token_pipe(s);
        char ** left_a;
        char ** right_a;
        int output = 0;
        int input = 0;

        for(i = 0; piped[i] != NULL; i++)
        {
            left_a = token_leftarrow(piped[i]);
            right_a = token_rightarrow(piped[i]);
            if(left_a[1] != NULL)   
            {
                free(piped[i]);
                piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                strcpy(piped[i], left_a[0]);
                fd[0][0] = open(left_a[1], O_RDONLY);
                input = i;      
            }

            if(right_a[1] != NULL)  
            {
                free(piped[i]);
                piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                strcpy(piped[i], right_a[0]);
                fd[1][1] = open(right_a[1], O_WRONLY | O_CREAT, 0666);
                output = i;
            }   
        }

        char ** spaced = token_space(piped[0]);
        char ** spaced2 = NULL;
        if(piped[1] != NULL)
        {
            spaced2 = token_space(piped[1]);
            res = pipe(fd[2]);
            if(res < 0)
            {
                printf("Pipe Failure\n");
                exit(-1);
            }// end if
        }   

        if(fork() == 0)
        {
            if(background == 1)
               setpgid(0, 0);
            if(piped[1] != NULL)
            {
                close(fd[2][1]);
                close(0);
                dup(fd[2][0]);

                if(output == 1 && right_a[1] != NULL)
                {
                    dup2(fd[1][1], 1);
                    close(fd[1][1]);
                }         

                execvp(spaced2[0], spaced2);
                perror("Invalid Command");
                exit(-1);
            }
            else
            {   
                if(input == 0 || output == 0)
                {
                    if(right_a[1] != NULL)
                    {
                        dup2(fd[1][1], 1);
                        close(fd[1][1]);
                    }
                    if(left_a[1] != NULL)
                    {
                        dup2(fd[0][0], 0);
                        close(fd[0][0]);
                    }

                }   

                execvp(spaced[0], spaced);
                perror("Invalid command\n");
                exit(-1);
            }
        }
    else
    {
        if(piped[1] != NULL)
        {
            if((pid = fork()) == 0)
            {
                close(fd[2][0]);
                close(1);
                dup(fd[2][1]); 
                if(input == 0 && left_a[1] != NULL)
                {
                    dup2(fd[0][0], 0);
                    close(fd[0][0]);
                }     

                execvp(spaced[0], spaced);
                perror("Invalid Command");
                exit(-1);
            }
            else
                if(background == 0)
                    waitpid(pid, &status, WNOHANG);

        }
        else
            if(background == 0)
                wait(NULL);


        close(fd[2][0]);
        close(fd[2][1]);
        close(fd[0][0]);
        close(fd[1][1]);
        dup2(stdin_c, 0);
        dup2(stdout_c, 1);

      } 


    }
4

0 に答える 0