是否有可能确定一个进程打开哪个fds进行读取而不是通过procfs进行写入?

时间:2014-03-13 01:30:27

标签: linux linux-kernel procfs

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

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

$ ls -l /proc/4166/fd/
total 0
lrwx------ 1 x x 64 Mar 12 21:15 0 -> /dev/pts/3
lrwx------ 1 x x 64 Mar 12 21:15 1 -> /dev/pts/3
lrwx------ 1 x x 64 Mar 12 21:15 2 -> /dev/pts/3
lrwx------ 1 x x 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)的人意味着fd是开放的读写。

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

1 个答案:

答案 0 :(得分:2)

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

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

user@host:/proc/6095/fdinfo$ cat 8 
pos:    0
flags:  02004002

咨询其他联机帮助页,“flags”字段是指传递给开放系统命令relevant man page for open(2) here的标志。所以只是为了让它更难一点,当然open()象征性地定义所有这些标志,而不是数字。那么02004002(上面的例子)的标志是什么意思呢?

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

# define O_CREAT           0100
# define O_APPEND         02000
#define O_ACCMODE          0003
#define O_RDONLY             00
#define O_WRONLY             01
#define O_RDWR               02
# define O_CREAT           0100 /* Not fcntl.  */
# define O_TRUNC          01000
# define __O_DIRECTORY  0200000
# define O_DIRECTORY    __O_DIRECTORY   /* Must be a directory.  */
# define O_NONBLOCK       04000
# define __O_CLOEXEC   02000000

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

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