C 如何阻止Exeve退出原始程序

C 如何阻止Exeve退出原始程序,c,io,pipe,fork,io-redirection,C,Io,Pipe,Fork,Io Redirection,我已经编写了自己的shell,并编写了一个处理三重管道的函数,但我的shell在execve之后退出时遇到了一个问题。我相信问题是我需要多拨一点时间?但我不完全确定在哪里,因为这样可以完美地执行管道程序。此外,在这个实现中没有使用wait(2),不确定这是否也与wait有关。谢谢 int fd[2]; int fd2[2]; if (pipe(fd) == -1) { perror("ERROR CREATING PIPE"); return; } pid_t pid = f

我已经编写了自己的shell,并编写了一个处理三重管道的函数,但我的shell在execve之后退出时遇到了一个问题。我相信问题是我需要多拨一点时间?但我不完全确定在哪里,因为这样可以完美地执行管道程序。此外,在这个实现中没有使用wait(2),不确定这是否也与wait有关。谢谢

int fd[2];
int fd2[2];

if (pipe(fd) == -1)
{
    perror("ERROR CREATING PIPE");
    return;
}

pid_t pid = fork();

if (args4[0] != NULL)
{
    switch(pid)
    {
        case -1:
            printf("%s\n", "fail to fork");
            return;
        case 0:
            if (pipe(fd2) == -1)
            {
                perror("ERROR CREATING PIPE");
                return;
            }
            switch(pid = fork())
            {
                case -1:
                    printf("%s\n", "fail to fork");
                    return;
                    break;
                case 0:
                    if ( dup2(fd2[1], STDOUT_FILENO) == -1 )
                    {
                        printf("%s\n", "fail to dup");
                        return;
                    }
                    close(fd2[0]);
                    close(fd2[1]);
                    execve(args2[0], args2, environ);
                    exit(1);
                default:
                    if ( dup2(fd2[0], STDIN_FILENO) == -1 )
                    {
                        printf("%s\n", "fail to dup");
                        return;
                    }
                    if ( dup2(fd[1], STDOUT_FILENO) == -1 )
                    {
                        printf("%s\n", "fail to dup");
                        return;
                    }
                    close(fd2[0]);
                    close(fd2[1]);
                    execve(args3[0], args3, environ);
                    exit(2);
            }
            exit(3);

        default:
            if ( dup2(fd[0], STDIN_FILENO) == -1)
            {
                printf("%s\n", "fail to dup");
                return;
            }
            close(fd[0]);
            close(fd[1]);
            printf("%s\n", "4");
            execve(args4[0], args4, environ);
            exit(4);
    }
}

您已经分叉两次,因此有3个进程。它们中的每一个都由execve创建的相应进程替换。由于execve()不会返回(在成功时),因此永远无法访问exit()语句。以下是在没有管道(您清楚地了解如何设置管道)和不必要的语句的情况下重写的代码:

pid_t pid = fork();
if (pid) {
    execve(args4[0], args4, environ);
}
else {
    pid = fork();
    if (pid) {
        execve(args3[0], args3, environ);
    }
    else {
        execve(args2[0], args2, environ);
    }
}
使用上面重写的代码,您可以更容易地看到,您将得到如下三个过程:


args2[0]| args3[0]| arg4[0]

您需要为每个要调用的子进程分叉。是的,我理解,我很难确定要分叉哪个进程。我认为它应该是execve(args2[0],args2,environ),因为它是最后一个调用的进程。我在三位高管面前都试过分岔,但都没用。别担心,我很蠢。非常感谢。分叉args4的第一个进程错误消息应写入
stderr
,而不是
stdout
<代码>fprintf(stderr,…)执行此操作。当错误是系统函数返回的指示时,请使用
peror()
,这样操作系统认为错误发生的原因也会被输出。