使用文件重定向在C中实现Shell会导致带有输入重定向的无限循环

时间:2016-09-14 23:18:10

标签: c shell dup2

我在C中实现了一个简单的shell,我挂断了将输入重定向到命令。我成功地管道和重定向输出工作,所以我不确定我的问题在于重定向输入。似乎由于某种原因它导致无限循环,因为我打印出我的execvp调用的结果,每当我尝试重定向输入时,我得到来自该程序部分的无限-1。任何帮助将不胜感激。

int main(void) {
    char input[128];
    char *commands[128];
    static char* args[128];
    pid_t pid;
    int numCommands;
    int commandNum;
    int j;
    int argNum;
    int i;

    while (1) {
        // Take in input
        fgets(input, 128, stdin);

        if (strcmp(input, "exit\n") == 0) {
            break;
        }
        // Get first command, if null then line is empty
        commands[0] = strtok(input, " \n\t");
        if(commands[0] == NULL) continue;

        // Read in all subsequent commands until null
        numCommands = 1;
        while(1) {
            commands[numCommands] = strtok(NULL, " \n\t");
            if (commands[numCommands] == NULL) break;
            numCommands++;
        }

        int numPipes;
        numPipes = countPipes(commands);

        int pipefds[2*numPipes];
        for (i = 0; i < numPipes; ++i) {
            pipe(pipefds + i*2);
        }

        int ran = 0;
        commandNum = 0;
        int outputRedirect = 0;
        int inputRedirect = 0;

        while (commands[commandNum] != NULL) {
            j = commandNum + 1;
            args[0] = commands[commandNum];
            argNum = 1;
            while (j < numCommands) {
                if (strcmp(commands[j], "|") == 0) {
                    ++commandNum;
                    break;
                } else if (strcmp(commands[j], ">") == 0) {
                    outputRedirect = open(commands[j + 1], O_TRUNC | O_WRONLY | O_CREAT, 0755);
                    ++commandNum;
                    break;
                } else if (strcmp(commands[j], "<") == 0) {
                    inputRedirect = open(commands[j + 1], O_RDONLY);
                    ++commandNum;
                    break;
                } else {
                    ++commandNum;
                    args[argNum] = commands[j];
                    ++argNum;
                }
                ++j;
            }

            pid = fork();
            if (pid == 0) {
                if (outputRedirect != 0) {
                    dup2(outputRedirect, STDOUT_FILENO);
                }
                if (inputRedirect != 0) {
                    dup2(inputRedirect, STDIN_FILENO);
                    close(inputRedirect);
                }
                if (ran != 0) {
                    dup2(pipefds[(ran - 1) * 2], STDIN_FILENO);
                }
                if (ran != numPipes) {
                    dup2(pipefds[ran*2+1], STDOUT_FILENO);
                }
                for (i = 0; i < numPipes * 2; ++i) {
                    close(pipefds[i]);
                }
                printf("%d\n", execvp(args[0], args));
            }
            ++commandNum;
            ++ran;


        }
        for (i = 0; i < numPipes * 2; ++i) {
            close(pipefds[i]);
        }


    }
    return 0;
}

0 个答案:

没有答案