是否可以通过 procfs 确定进程已打开哪些 fds 进行读取和写入?

Fro*_*its 3 linux linux-kernel procfs

procfs 会告诉我进程在任何给定时间正在使用哪些 fd。但是有没有办法确定哪些是开放的阅读和写作?

在下面的输出中,进程所有者(用户“x”)显然具有对链接/文件的读/写访问权限,但这与知道 pid 4166 是写入还是读取特定 fd 不同。

$ ls -l /proc/4166/fd/
共 0
lrwx------ 1 xx 64 Mar 12 21:15 0 -> /dev/pts/3
lrwx------ 1 xx 64 Mar 12 21:15 1 -> /dev/pts/3
lrwx------ 1 xx 64 Mar 12 21:15 2 -> /dev/pts/3
lrwx------ 1 xx 64 Mar 12 21:15 255 -> /dev/pts/3

我知道 lsof 实用程序可以做到这一点:

$ lsof -p 4166 | grep CHR
bash 4166 x 0u CHR 136,3 0t0 6 /dev/pts/3
bash 4166 x 1u CHR 136,3 0t0 6 /dev/pts/3
bash 4166 x 2u CHR 136,3 0t0 6 /dev/pts/3
bash 4166 x 255u CHR 136,3 0t0 6 /dev/pts/3

lsof 的联机帮助页说,例如那些在 fd 数字 (0, 1, 2, 255) 后面的尾随 u's 意味着 fd 可以读取和写入。

不过,我的问题是是否可以通过 procfs 而不是 lsof 获取此信息。由于各种原因,在另一种编程语言中执行 lsof 对我来说不如轮询 procfs 方便,所以我想知道是否有直接的方法可以在那里执行此操作。

Fro*_*its 5

我按照建议挖掘了 lsof 代码,并找到了答案。

本质上,lsof 实用程序在/proc/XX/fdinfo/YY其中打开文件,其中XX是进程 PID,YY是文件描述符编号。每个文件都是一个很小的文本文件,如下所示:

用户@主机:/proc/6095/fdinfo$ cat 8 
位置:0
标志:02004002

查阅其他联机帮助页,“标志”字段是指传递给open(2) 此处的开放系统命令相关手册页的标志。所以只是为了让它更难一点,当然,以open()符号方式而不是数字方式定义所有这些标志。那么02004002(上面的例子)的标志是什么意思?

我在 libc6-dev 中找到了定义/usr/include/i386-linux-gnu/bits/fcntl-linux.h,包括这些摘录:(警告不要相信这些值适用于您的系统,请自行查找,因为它们可能不同)

# 定义 O_CREAT 0100
# 定义 O_APPEND 02000
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100 /* 不是 fcntl. */
# 定义 O_TRUNC 01000
# 定义 __O_DIRECTORY 0200000
#define O_DIRECTORY __O_DIRECTORY /* 必须是目录。*/
# 定义 O_NONBLOCK 04000
# 定义 __O_CLOEXEC 02000000

因此,给定标志:02004002,该文件看起来像是打开以进行读/写 (02)、非阻塞 (4000)、执行时关闭 (2000000)。

HTH 其他人对这些问题感到困惑。