首页 > 解决方案 > 是否有系统调用或某种方式可以知道 Linux 中文件描述符的类型(例如常规文件 fd、套接字 fd、信号 fd、计时器 fd)?

问题描述

正如我不断发现的那样,有各种各样的文件描述符 - 几乎所有东西都围绕文件描述符进行抽象:常规文件、套接字、信号和计时器(例如)。所有文件描述符都只是整数。

给定一个文件描述符,是否有可能知道它是什么类型?例如,最好有一个系统调用,例如 getFdType(fd)。

如果 epoll_wait 由于多个文件描述符准备就绪而被唤醒,则每个文件描述符的处理将基于其类型。这就是我需要这种类型的原因。

当然,我可以自己单独维护这些信息,但让系统支持它会更方便。

此外,所有文件描述符,无论类型如何,都是顺序的。我的意思是,如果您打开一个常规数据文件,然后创建一个计时器文件描述符,然后创建一个信号文件描述符,它们是否都保证按顺序编号?

标签: linuxsocketstimersignalsepoll

解决方案


正如“那个人”所提到的,最明显的这种叫法是fstat. 该st_mode成员包含用于区分常规文件、设备、套接字、管道等的位。

但在实践中,您几乎肯定需要自己跟踪哪个 fd 是哪个。当您打开多个不同的常规文件时,知道它是一个常规文件并没有太大帮助。因此,既然您无论如何都必须在代码中的某个位置维护这些信息,那么回溯该记录似乎是最可靠的方法。

(检查程序中的一些变量也比进行一个或几个额外的系统调用要快得多。)

此外,所有文件描述符,无论类型如何,都是顺序的。我的意思是,如果您打开一个常规数据文件,然后创建一个计时器文件描述符,然后创建一个信号文件描述符,它们是否都保证按顺序编号?

并不真地。

据我所知,创建新 fd 的调用将始终返回编号最小的可用 fd。有一些旧程序依赖于这种行为;在dup2存在之前,我相信将标准输入移动到新文件的公认方式是close(0); open("myfile", ...);.

但是,很难确定哪些 fds 可用。例如,用户可能已经运行了你的程序/usr/bin/prog 5>/some/file/somewhere ,然后它会出现 fd 5 被跳过,因为/some/file/somewhere它已经在 fd 5 上打开。因此,如果你连续打开一堆文件,你不能确定你将获得连续的 fd,除非您自己关闭了所有这些 fd,并且确定所有编号较低的 fd 都已在使用中。这样做似乎比一开始就跟踪 fds 更麻烦(也是潜在问题的根源)。


推荐阅读