Linux 上使用 C 语言的 2 个管道进行双向父子通信

发布于 2025-01-06 13:08:46 字数 1568 浏览 0 评论 0原文

我正在尝试在 Linux 上使用 C 语言使用 2 个管道在父进程和子进程之间创建双向通信。父程序是我的程序,子程序只是一个随机程序(比如“猫”)。

我尝试在父级中使用 read() 来读取子级输出,但它给了我 errno 9,这是错误的文件描述符。

以下是我的代码

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

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
    int data_processed;

    /** Pipe for reading for subprocess */
    int read_pipe[2];
    /** Pipe for writing to subprocess */
    int write_pipe[2];

    char buffer[100];
    memset(buffer, '\0', 100);

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
    {
        pid_t pid = fork();
        if (pid == (pid_t)-1)
        {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }
        else if (pid == (pid_t)0) //Child process
        {
            close(Read);
            close(Write);
            close(ParentRead);
            close(ParentWrite);
            dup(ChildRead);
            dup(ChildWrite);
            execlp("cat", (char*)NULL);
            exit(EXIT_FAILURE);
        }
        else { //Parent process
            close(ChildRead);
            close(ChildWrite);

            write(ParentWrite, "abc", 3);
            int r = read(ParentRead, buffer, 99);
            printf("%d %d", r, errno);
            puts(buffer);
        }
    }

    exit(EXIT_SUCCESS);
}

I'm trying to create a two-way communication between parent and child processes using 2 pipes using C on Linux. The parent is my program and the child is just a random program (say "cat").

I try to uses read() in parent to read child output, but it gives me errno 9, which is Bad file descriptor.

The following is my code

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

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
    int data_processed;

    /** Pipe for reading for subprocess */
    int read_pipe[2];
    /** Pipe for writing to subprocess */
    int write_pipe[2];

    char buffer[100];
    memset(buffer, '\0', 100);

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
    {
        pid_t pid = fork();
        if (pid == (pid_t)-1)
        {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }
        else if (pid == (pid_t)0) //Child process
        {
            close(Read);
            close(Write);
            close(ParentRead);
            close(ParentWrite);
            dup(ChildRead);
            dup(ChildWrite);
            execlp("cat", (char*)NULL);
            exit(EXIT_FAILURE);
        }
        else { //Parent process
            close(ChildRead);
            close(ChildWrite);

            write(ParentWrite, "abc", 3);
            int r = read(ParentRead, buffer, 99);
            printf("%d %d", r, errno);
            puts(buffer);
        }
    }

    exit(EXIT_SUCCESS);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜嗑 2025-01-13 13:08:46

如果要将 stdin 和 stdout 重定向到管道,则需要使用 dup2(2) 系统调用。

dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);

聚苯乙烯
我还发现管道中读/写方向错误。这是正确的方法

#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]

记住:pipe[0]是用于读取的fd,pipe[1]是用于写入的fd。

execlp 中还有一个错误。不要忘记将发送到执行程序的第一个参数设置为程序名称

execlp("cat", "cat", (char*)NULL);

If you want to redirect stdin and stdout to pipes, you need to use dup2(2) system call.

dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);

P.S.
Also I found wrong directions of reading/writing in pipes. Here is the correct way

#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]

Remember: pipe[0] is fd for reading, pipe[1] is fd for writing.

And one more error, in execlp. Do not forget to set the first argument you send to the executed programm as a name of the program

execlp("cat", "cat", (char*)NULL);
酷到爆炸 2025-01-13 13:08:46

如果只执行读/写会发生什么?老实说,我不确定 dup 和 cat 是您想要的:

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);

而且,进一步思考,如果您知道最终想要的 fd,请使用 dup2,而不是 dup。了解您的 API,朋友们!

并且,进一步思考,您可以查看 popen(3) 调用的源代码,它以更通用的方式执行此操作。

What happens if you just perform a read/write? I'm unsure that dup and cat are what you want here, to be honest:

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);

And, thinking further, if you know the fd you want to end up at, use dup2, not dup. Know your APIs, people!

And, thinking even further, you could look at the source for the popen(3) call, which does exactly this, in a more general way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文