我正在尝试在Linux上使用C使用2个pipe道创build父进程和subprocess之间的双向通信。 父母是我的程序,孩子只是一个随机程序(说“猫”)。
我尝试在父级使用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); }
如果要将stdin和stdout重定向到管道,则需要使用dup2(2)系统调用。
dup2 (ChildRead, 0); dup2 (ChildWrite, 1);
PS我也发现在管道中读写错误的方向。 这是正确的方法
#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);
如果你只是执行一个读/写会发生什么? 我不确定dup和cat是你想要的,老实说:
char buf[256]; int len; len = read(ChildRead, 256); write(ChildWrite, len);
而且,进一步思考,如果你知道你最终想要的fd,使用dup2,而不是dup。 知道你的API,人!
而且,进一步思考,你可以看到popen(3)调用的来源,这正是以更一般的方式完成的。