是否有独立于平台的非阻塞方法来判断文件描述符是否是磁盘上的文件(常规/目录)



>我正在寻找文件描述符的类型,而不可能在内核中阻塞。我知道我可以使用fstat(2)fstat也会得到各种元数据信息(访问时间等(,这些信息可能会阻塞任意时间(特别是在网络文件系统上(。

编辑:我正在寻找一个系统调用来执行此操作,生成一个单独的进程是不可接受的,因为生成一个进程并读取其结果肯定不是即时的。

我唯一需要知道的信息是文件描述符是否是磁盘上的"文件"(S_IFREGS_IFLNKS_IFDIR(。 或者,如果我能分辨出它是套接字(S_IFSOCK(,fifo(S_IFIFO(还是字符设备(S_IFCHR(,那也没问题。

我很确定任何内核都会随时提供这些信息,如果可以将其显示在用户空间而不会阻塞,我很感兴趣。

一个便携式解决方案(至少是macOS和Linux(将不胜感激。

谢谢!

在 Linux 上,您可以查看proc伪文件系统,/proc/<pid>/fd,例如:

[max@supernova:/proc/7275/fd] $ ls -l /proc/7275/fd/
total 0
lr-x------ 1 max max 64 Oct 12 16:28 0 -> /dev/null
l-wx------ 1 max max 64 Oct 12 16:28 1 -> 'pipe:[69689]'
lrwx------ 1 max max 64 Oct 12 16:28 10 -> 'socket:[69698]'
l-wx------ 1 max max 64 Oct 12 16:28 100 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/MANIFEST-000001'
lr-x------ 1 max max 64 Oct 12 16:28 101 -> '/home/max/.config/google-chrome/Default/Sync Data/LevelDB/001633.ldb'
l-wx------ 1 max max 64 Oct 12 16:28 102 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/000024.log'
lr-x------ 1 max max 64 Oct 12 16:28 103 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/000022.ldb'
lr-x------ 1 max max 64 Oct 12 16:28 104 -> /opt/google/chrome/nacl_irt_x86_64.nexe
lr-x------ 1 max max 64 Oct 12 16:28 105 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/000005.ldb'
lr-x------ 1 max max 64 Oct 12 16:28 106 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/000025.ldb'
lr-x------ 1 max max 64 Oct 12 16:28 107 -> '/home/max/.config/google-chrome/Default/Service Worker/Database/000019.ldb'
lrwx------ 1 max max 64 Oct 12 16:28 108 -> 'socket:[89401]'
lrwx------ 1 max max 64 Oct 12 16:28 109 -> 'socket:[68628]'
lrwx------ 1 max max 64 Oct 12 16:28 11 -> 'anon_inode:[eventfd]'

您可以在非阻塞模式下将"lsof"命令与参数"-b"一起使用。此参数将导致 lsof 避免可能阻塞的内核函数。例如:

sudo lsof -b | less
COMMAND     PID   TID            USER   FD      TYPE             DEVICE    SIZE/OFF     NODE NAME
systemd       1                  root  cwd       DIR                8,1        4096          2 /
systemd       1                  root  rtd       DIR                8,1        4096          2 /
systemd       1                  root  txt       REG                8,1     1595792      19245 /lib/systemd/systemd

"类型"将为您提供文件类型。您可以使用 grep 通过管道获取有关文件描述符的信息,

sudo lsof -b | grep <your file descriptor>

或者有很多参数可以让你自定义lsof操作。

对于平台独立性,这些是支持 lsof 的平台:-

Apple Darwin 9 and Mac OS X 10.[567]
FreeBSD 8.[234], 9.0, 10.0 and 11.0 for AMD64-based systems
Linux 2.1.72 and above for x86-based systems
Solaris 9, 10 and 11

最新更新