微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在子流程中重定向标准输出是否也对父流程进行了重定向?

我正在为星期二的OS考试学习.为了准备,我试图通过C程序模拟命令行管道.

该程序非常简单.我制作一个管道,然后派生一个子进程.

子进程将标准输出重定向到管道的写端,关闭管道的文件描述符,然后执行命令(在这种情况下为ls).

父进程等待子进程退出,将标准输入重定向到管道的读取端,关闭管道的文件描述符,然后执行命令(在这种情况下为grep’school’).

当我使用ls |通过命令行执行命令时grep’school’的一行显示为“ school”,它被打印到标准输出,这是有道理的,因为该目录中有一个我正在运行该程序的目录.

运行我制作的程序时,我没有收到任何错误消息,但是没有产生任何输出.

我唯一想到的将阻止此工作的原因是,在子进程中重定向标准输出会以某种方式影响父进程命令的输出,但是我几乎肯定不会出现这种情况.

这是代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main() {
    int fds[2];
    int pipe_val, close_val, write_val, dup_val, status;
    pid_t pid;
    char *error;

    pipe_val = pipe(fds);
    if (pipe_val) {
        fprintf(stderr, "Failed to prepare pipe.\n");
        return -1;
    }
    pid = fork();
    if (pid == -1) {
        fprintf(stderr, "Failed to fork a child process.\n");
        return -1;
    } else if (pid == 0) {
        dup_val = dup2(fds[1], STDOUT_FILENO);
        if (dup_val) {
            error = strerror(errno);
            fprintf(stderr, "Failed to redirect standard output in child process because %s\n", error);
            exit(1);
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of pipe in child process.\n");
            exit(1);
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of pipe in child process.\n");
            exit(1);
        }
        execl("/bin/ls", "ls", NULL);
        fprintf(stderr, "Failed to execute command in child process.\n");
        exit(1);
    } else {
        wait(&status);
        dup_val = dup2(fds[0], STDIN_FILENO);
        if (dup_val) {
           error = strerror(errno);
           fprintf(stderr, "Failed to redirect standard input in parent process because %s.\n", error);
            return -1;
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of the pipe in the parent process.\n");
            return -1;
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of the pipe in the parent process.\n");
            return -1;
        }
        execl("/bin/grep", "grep", "school", NULL);
        fprintf(stderr, "Failed to execute the command in the parent process.\n");
        return -1;
    }
}

解决方法:

您的第一个问题是,您尚未包括所使用函数的所有必需标头. strerror需要< string.h>并且等待需要< sys / wait.h>.

如果使用gcc进行编译,请始终使用gcc -Wall并阅读警告.在这种情况下,它本来会抱怨隐含的strerror声明.

因为未声明strerror,所以编译器假定它返回一个int,这是错误的.如果在64位Linux x86上运行程序,则int的大小甚至与strerror返回的指针的大小不一样.当您随后将strerror的结果以%s格式传递给fprintf时,这将成为一个致命的问题,因为指针被误解为一个int值,然后又转换回指针,最后得到一个伪造的值. fprintf segfaults,您将永远不会看到错误消息.

包括正确的标题,您将看到一条错误消息,将导致您需要解决的下一个问题.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐