【问题标题】:Is dup2() necessary for execlexecl 是否需要 dup2()
【发布时间】:2013-04-03 06:44:24
【问题描述】:

使用管道时是否需要将stdin 替换为pipe 结尾?

我有一个应用程序:-

  • 创建管道,
  • forks 一个子进程,然后
  • execl() 新子进程中的新进程映像,

但我遇到了两个概念问题。

  1. 有必要用dup()dup2()代替stdin吗?使用管道中的fd 显然会更容易。 (我几乎不需要了解这个

  2. 1234563

我无法弄清楚在执行 execl() 后仍然打开的确切内容,以及如何从新执行的进程中访问该信息。

【问题讨论】:

  • 我认为您觉得使用 dup() 和 dup2() 很复杂/很难。 Here is very good tutorial colorful and easy with diagram. 还有Other useful chapters
  • 其实 dup() 和 dup2() 更容易其他也可能的方法是使用 fcntl() 或 ioctl() 函数但并不比 dup.() 更简单
  • @GrijeshChauhan 但是,需要 dup 吗?我猜有必要,我的意思是子进程打开文件描述符在执行 execl 时是否保持打开状态?我认为如果是新的,exec 家族会清除进程映像。如果没有必要,我不确定如何通过 char *arg 传递管道的文件描述符(它是一个 int)。
  • 相信你正在用execl系列函数替换标准命令。这些函数默认写入标准输出也从标准输入获取输入。要与该进程通信,您必须将管道建立为 IPC,并且必须使用 dup() 显式更改输入/输出流。但是假设如果您的子进程不与标准输入/输出交互,那么就没有必要重定向标准输入/标准输出。 (记住 stdin/stdout 是 FILE* 不是描述符
  • 回答第二个问题:假设您想将子进程输出重定向到父进程打开的其他文件。然后您可以将打开文件的fd 作为参数从父进程传递给子进程。并按照相同的步骤使用 dup() 重定向到该文件

标签: c exec fork ipc pipe


【解决方案1】:

您可能正在尝试将数据提供给系统上存在的子进程,但如果您也在编写子进程,那么您不需要使用 dup()stdin

execl() 使父进程中所有打开的文件描述符保持打开状态,以便您可以:

int fd[2];
pipe(fd);
if (fork() == 0)
{
    char tmp[20];
    close(fd[1]);
    snprintf(tmp, sizeof(tmp), "%d", fd[0]);
    execl("client", tmp, NULL);
    exit(1);
}

在客户端代码中:

int main(int argc, char** argv)
{
    int fd = strtod(argv[1], NULL, 10);
    /* Read from fd */
}

【讨论】:

  • 而是给 OP 一个例子,展示如何使用 execl(...,..) 函数中的参数将文件描述符传递给子进程。
  • @GrijeshChauhan,嗯,我就是这么做的?
  • Joel,您能解释一下将数据馈送到系统上存在的子进程与编写子进程的含义吗?
  • 对于“系统上存在的子进程”,我的意思是一个已经由其他人创建的程序,它可能希望从标准输入读取数据。当我们自己编写子进程时,您可以做其他事情,例如将文件描述符作为参数。
  • @GrijeshChauhan 感谢您对这个问题的帮助。现在回去阅读你的 cmets 对我来说更有意义。感谢您编辑帖子以更清楚地阅读!
【解决方案2】:

这取决于您正在运行的命令。但是,许多 Unix 命令从标准输入读取并写入标准输出,因此如果管道没有设置为写入端是一个命令的输出,而读取端是下一个命令的输入,则不会发生任何事情(或,更准确地说,程序从输入不是来自的地方读取,或者写入到不会被读取的地方,或者挂起等待你在终端输入输入,或者不按预期工作)。

如果您的管道位于文件描述符 3 和 4 上,则您执行的命令必须知道从 3 读取并写入 4。您可以使用 shell 处理它,但与使用 @987654321 相比,这样做有点怪诞过度@。

没有;您不必使用dup2(),但这样做通常更容易。您可以关闭标准输出,然后使用普通的dup() 而不是dup2()

如果您将dup2() 用于管道,请不要忘记关闭两个的原始文件描述符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 2012-01-27
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多