【问题标题】:How does the program access the inherited file descriptors? [closed]程序如何访问继承的文件描述符? [关闭]
【发布时间】:2017-07-31 11:21:42
【问题描述】:

在 Linux API 中,程序会继承在其调用者中打开的文件描述符的副本。

程序如何访问继承的文件描述符?哪些函数用于此目的?

程序的调用者可以是

  • C 中的另一个程序,或

  • 一个 bash 外壳。在这种情况下,程序如何访问在调用它的 shell 中打开的文件描述符?来自 Bash Manual,在 bash shell 中,

    当要执行除内置函数或 shell 函数之外的简单命令时,它会在由以下内容组成的单独执行环境中调用。除非另有说明,否则这些值是从 shell 继承的。

    • shell 的打开文件,以及通过重定向到命令指定的任何修改和添加

谢谢。

【问题讨论】:

  • 定义“它的调用者”。对我来说,这听起来太模糊了。
  • 你能详细说明一下吗?你是在说fork()吗?
  • 它的调用者可以是另一个 C 程序或 bash shell。
  • 您必须在自己的代码中找到答案。例如,只需传递 argv[] 中的数字即可。
  • @NikosC。 fork()创建当前进程的子进程。那么子进程如何访问继承自当前进程的文件描述符

标签: c linux api


【解决方案1】:

当你fork()一个新进程时,你的文件描述符仍然有效。您照常访问它们:

int fd = open(/* ... */);
pid_t pid = fork();

if (pid == 0) {
    // We're the child.
} else if (pid > 0) {
    // We're the parent.
} else {
    // fork() failed.
}

父进程和子进程仍然可以访问fd。子进程没有什么特别的要求;可以正常访问fd

对于子进程是不同程序的情况,父进程需要将文件描述符传递给子进程。即使有办法找出所有打开的文件描述符,也无法分辨这些描述符指的是什么。它们来自贝壳吗?从节目?这只是随机数据。

因此,您需要通过管道或main() 的参数或IPC 机制与它们进行通信。换句话说,文件描述符没有什么特别之处。它们是需要像任何其他数据一样进行通信的数据。

例如,一个 bash 脚本可能会打开一些文件,使用 3 和 4 作为文件描述符,然后告诉您的程序它使用哪些描述符:

#! /bin/bash

exec 3<> /tmp/newfile1
echo "This is file one." >&3

exec 4<> /tmp/newfile2
echo "This is file two." >&4

./myprogram 3 4

您的程序可以通过以下方式获得这些:

int main(int argc, char* argv[])
{
    fd1 = atoi(argv[1]);
    fd2 = atoi(argv[2]);

    // ... Obviously you'd need error-checking, but this is just an example.
}

【讨论】:

  • 谢谢。如果子进程的调用者是 bash shell 进程怎么办?也就是子进程的程序是从 bash shell 启动的。
  • 再次感谢您的更新。您能否举一些使用管道和使用 main 的参数将打开的文件描述符从 bash shell 传递到 C 中的程序的示例?
  • @Tim 我认为这不言自明,但我添加了一个示例。
  • 我明白了。谢谢。您将如何使用管道来代替?
  • @Tim Google“如何在 C 中创建管道”和“如何在 bash 中创建管道”。在这两种情况下,您都使用mkfifo
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 2017-11-30
  • 2020-06-06
  • 1970-01-01
  • 2011-03-31
  • 2012-04-29
相关资源
最近更新 更多