我创建了一个函数exec_in_child
,它接受命令参数,管道文件描述符(fds
),read_flag
和write_flag
作为输入。当write_flag
设置为1时,子进程应将stdout
复制到fds[1]
,然后执行该命令。当read_flag
设置为1时,子项应将stdin
复制到fds[0]
并执行命令。
/bin/ls
,将stdout写入管道,然后读取
它在父进程中关闭并打印出来。我无法读入
父进程。 #include <stdio.h> /* printf */ #include <stdlib.h> #include <string.h> /* strlen, strcpy */ int exec_in_child(char *arguments[], const int temp[], int , int); int main() { ssize_t bytes_read; char *curr_dir = (char *)malloc(500); int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } char *arguments[] = {"/bin/pwd",0}; exec_in_child(arguments, pipefd, 0, 1); bytes_read = read(pipefd[0], curr_dir, strlen(curr_dir)); printf("%s = %d\n", "bytes read from pipe" ,(int)bytes_read); printf("%s: %s\n","character read from the pipe",curr_dir); return 0; } int exec_in_child(char * arguments[], const int fds[], int read_flag, int write_flag) { pid_t pid; pid = fork(); if (pid < 0) { perror("Error: Fork Failed"); } else if (pid == 0){ /*inside the child process */ if (read_flag == 1) { dup2(fds[0], 0); perror("Dup2 stdin"); } if (write_flag == 1) { dup2(fds[1], 1); perror("Dup2 stdout"); } execv(arguments[0], arguments); perror("Error in child"); exit(1); } /* if (pid == 0) */ else { while(pid != wait(0)); } /* if(pid < 0) */ return 0; }
我得到了这个结果:
hmwk1-skk2142(test) > ./a.out
Dup2 stdout: Success
bytes read from pipe = 0
character read from the pipe:
答案 0 :(得分:3)
回答你的问题:
1)您不需要关闭管道的任何一端以使用另一端。但是,您通常希望关闭您不使用的管道的任何一端。执行此操作的最大原因是管道将仅在所有打开的写入文件描述符关闭时关闭。
2)您的代码无法正常使用,因为您未正确使用strlen()
。此函数通过搜索null(0)字符来计算字符串的长度。当malloc()
存储curr_dir
时,您无法保证其中存在的内容(尽管通常会将其归零,如本例所示)。
因此,您的调用strlen(curr_dir)
返回零,read()
系统调用认为您想要读取零字节数据。将您的阅读电话更改为以下内容:
bytes_read = read(pipefd[0], curr_dir, 500);
并且您的代码将完美运行。
3)您可以读取和写入您有效文件描述符的任何管道。单个进程绝对可以读取和写入相同的管道。