fcntl与参数F_DUPFD的目的是什么

时间:2010-04-12 03:14:47

标签: fcntl

我跟踪了一个oracle进程,发现它首先打开一个文件/etc/netconfig作为文件句柄11,然后通过使用参数{调用256将其复制为fcntl {1}},然后F_DUPFD原始文件句柄close。稍后它使用文件句柄11读取。那么复制文件句柄有什么意义呢?为什么不只是处理原始文件句柄?

256

3 个答案:

答案 0 :(得分:5)

在某些系统上,如Solaris,带有FILE的标准I / O仅适用于文件描述符0-255,因为它的FILE结构实现使用的是8位整数而不是int。如果程序使用大量文件描述符,则使用fnctl(fd,F_DUPFD,256)保留文件描述符3-255很有用。否则,如果打开256个文件,fopen(),freopen()和fdopen()等函数将失败。

答案 1 :(得分:4)

另外,它们是文件描述符而不是文件句柄。后者是与fopen及其兄弟一起使用的C特征,而描述符更为UNIXy,与open等人一起使用。

有趣。想到的唯一原因是,其他一些代码对文件描述符的特定需求为256.我怀疑只有Oracle会知道这个奇怪的原因。在任何情况下,你都不能保证得到256,你得到的文件第一个可用的文件描述符大于或等于那个数字。


从一些调查(我不知道关于UNIX的内部的每一个小东西),有一些属性属于一组重复的描述符,如文件位置和访问模式。还有其他属性属于单个文件描述符,即使是重复的,例如GNULib中的close-on-exec标志。

执行重复(使用dupdup2fcntl)可能是一种创建两个描述符的方法,一个具有不同的文件描述符属性,但我看不到因为第一个描述符无论如何都是关闭的。如你所说,为什么不使用低描述符?

有趣的是,如果你google for netconfig f_dupfd,你会看到fcntl失败的类似痕迹,并继续以低描述符读取该文件,所以我对此事的想法是这是尝试尽可能保留低文件描述符。例如:

4327:   open("/etc/netconfig", O_RDONLY|O_LARGEFILE)    = 4
4327:   fcntl(4, F_DUPFD, 0x00000100)                   Err#22 EINVAL
4327:   read(4, " # p r a g m a   i d e n".., 1024)     = 1024
4327:   read(4, " t s           t p i _ c".., 1024)     = 215
4327:   read(4, 0x00296B80, 1024)                       = 0
4327:   lseek(4, 0, SEEK_SET)                           = 0
4327:   read(4, " # p r a g m a   i d e n".., 1024)     = 1024
4327:   read(4, " t s           t p i _ c".., 1024)     = 215
4327:   read(4, 0x00296B80, 1024)                       = 0
4327:   close(4)                                        = 0

也许该软件的某个文件描述符的字节数组有限,因此它会尝试将其他文件移到255限制以上。

但实际上,这只是我自己的猜测(尽管我认为这是相对聪明的猜测)。还要记住,Oracle本身可能不会这样做。 netconfig的东西在很多地方使用,因此它可能是一些底层库,特别是考虑到上述大多数网页命中都不是特定于Oracle的事实(ftp,{{ 1}}等等。)

答案 2 :(得分:2)

这是另一个需要保留低编号文件描述符的技术的例子。

假设进程打开大量文件描述符,例如它接受超过1024个同时套接字连接。同时,该过程还使用第三方库来打开套接字连接并使用select()来查看套接字是否已准备好进行读取或写入。此外,第三方库编译时__FD_SETSIZE设置为1024(默认值)。

如果库在使用1024以下的所有文件描述符时打开套接字,那么它将获得select()和关联的FD_ *宏无法处理的描述符。这将导致进程崩溃或未定义的行为。