是否可以静态定义std in / out / err以外的文件描述符?

时间:2016-02-11 00:33:01

标签: c posix file-descriptor

正如大多数开发人员所知,流程定义了三个文件描述符,我们更常见的是stdinstdoutstderr

从我所知的fd中,每一个都分别静态定义为0,1和2。这在POSIX标准中明确说明:http://pubs.opengroup.org/onlinepubs/009695399/functions/stdin.html

现在假设我有一组需要第4个进程的进程。例如,使用fork() exec()创建的子进程需要在socketpair()之前使用fork()创建的控件套接字的句柄。对于此示例,第四个句柄(套接字)的目的是在父进程和子进程之间提供链接。现在问题来了......孩子怎么知道哪个FD是控制插座?只要#define CONTROL_SOCKET 3dup2(new_socket,CONTROL_SOCKET)之间的fork(),我就无法使用静态数字(例如:exec())。我能够foo = write(CONTROL_SOCKET, bar, baz)在孩子的内心。让我们把它看作任何其他FDs打开我的应用程序预计将关闭exec所以我的逻辑是dup2()不会关闭任何不会被关闭的任何东西exec() {1}}。

我知道有几种可能的解决办法可以避免这样做(例如:在环境变量或程序参数中传递FD),网上有很多例子说明如何这样做。我不明白的是正在解决的问题是什么?静态定义FD的问题是什么?乍一看,这是一种避免不存在问题的感觉。有些系统使用0,1和2以外的FD,我可能会在执行前覆盖dup2(<some fd>,3)的重要内容吗?

注意: 这个问题实际上是一个关于编写可在现有 POSIX操作系统之间移植的代码的问题。

3 个答案:

答案 0 :(得分:2)

除了0,1,2之外,没有广泛使用的文件描述符。我似乎记得一些使用固定文件描述符超出该范围的跟踪系统(虽然通常不是3),但它们非常例外(我不记得在这个千年里注意到了它。)

总的来说,如果集合中的第一个进程能够确保描述符在启动时未被使用,则可以安全地将描述符传递给其子进程。如果您发现描述符已在使用中,则可以向控件套接字打开不同的描述符,然后使用fstat()来比较两个描述符。如果它们是同一个设备,你可以继续使用继承的描述符3;如果没有,您需要dup2()close()控制套接字。

如果您的进程计划只是自己打开控件套接字,则不必担心使用哪个文件描述符。

答案 1 :(得分:1)

您可能不希望这样做的原因是,与012不同,您无法保证3将成为dup2(<some fd>, 3)打开,除非你总是控制进程的启动方式。

但是,为某个频道设置固定的描述符号并没有错。 绝对不会用<some fd>覆盖任何内容。 它只会为您的流程及其子项掩盖reduce,但3在父流程中根本不会受到影响。

答案 2 :(得分:-1)

你不需要这么复杂。

即。不要将dup2()与您不确定的目标描述符一起使用(例如,因为您刚关闭它),或者您不希望隐式关闭它。

只需在命令行或环境变量中传递new_socket本身,作为表示其整数值的字符串,如注释中所示。

请参阅此答案:https://stackoverflow.com/a/21596854/816536但忽略“P1.c”的第二个变体 - 这是失败的方式。