c - 在 exec 中将管道作为参数传递

标签 c exec fork pipe

我正在尝试将一个管道传递给另一个我用 execv 创建的进程。到目前为止,这是我的代码,但它不起作用。我到处寻找信息,但找不到任何关于传递管道 vie exec 的具体信息。任何帮助表示赞赏。谢谢

int fd[2];
pipe(fd);

char passwrite[1];
sprintf(passwrite, "%d", fd[0]);

char arg[1];
arg[1]=passwrite;

int x;
x=fork();
if (x==0) {
execv("NewProg",arg);
}

最佳答案

管道是一种单向连接,通常最终位于由共同祖先关联的两个进程之间,通常是要创建的两个进程中的第一个,除非它是一个 shell,在这种情况下,shell 创建管道并有两个使用管道的 child 。管道有一个写端,供一个进程使用;它有一个被另一个使用的读端。将一个进程的标准输出连接到另一个进程的标准输入通常是最简单的。使用文件描述符而不是标准 I/O 文件流也是最简单的。

操作顺序是:

  1. 调用pipe()创建管道。
  2. 调用fork() 来创建一个 child 。
  3. 子进程(fork() 的返回值 0)执行以下操作:
    • close()管道的写端
    • dup2() 管道的读取端到标准输入
    • close() 管道的读取端
    • execve() 将从管道(其标准输入)读取的子进程
  4. 父进程(fork() 的返回值 > 0)执行以下操作:
    • close() 管道的读取端
    • dup2() 管道的写入端到标准输出。
    • close()管道的写端
    • execve() 将写入管道(其标准输出)的进程

请注意,在这种情况下,您最终关闭了 pipe() 调用返回的两个文件描述符,并且关闭了它们两次(一次在父级中,一次在子级中)。

如果父进程应该通过文件流写入子进程,请对写入文件描述符使用 fdopen() 调用(不要使用 dup2() 在它上面,或者 close() 它——你在 fdopen() 返回的文件流上用 fclose() 关闭它,或者通过退出)。

如果你想告诉子进程它可以读取哪个文件描述符号来从管道获取输入,那么你不需要在子进程中执行dup2();你可以简单地在一个字符数组中格式化一个字符串(复数 - 你至少需要字符并且应该允许十几个左右,因为它非常便宜),然后你可以安排将参数传递给 execve() 函数。请记住, child 至少需要三个指针:一个用于 argv[0],程序名称;一个用于文件描述符编号;一个用于终止空指针。这就是 execve() 知道何时到达参数列表末尾的方式。如果您只使用 execv(),则同样适用;您只是无法确定 child 的环境(例如,它收到的环境变量列表);它只会获得与父进程在 fork() 时所拥有的环境相同的环境。

¶3 和 ¶4 中的第一步都是关键步骤。如果省略它们,管道将无法正常工作。

关于c - 在 exec 中将管道作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5189475/

相关文章:

c - 具有多个元素的链表并找到最大的

c - gcc 错误 - typedef 已初始化(改用 decltype)

c - execvp() 不让我

git - 通过命令行在github上自动打开一个pull request

c++ - 生成一个新终端并打开 vim

c++ - 最小唯一字符

C - execvp 无法使用有效输入

C - 通过 execve 传递管道

c - 这个程序创建了多少个进程,包括初始的父进程?

永远不会执行的代码可以调用未定义的行为吗?