在linux内核编程中,有没有办法检查特定文件描述符是否正在用于给定进程或是否可用?
答案 0 :(得分:2)
是的,您可以测试一下:
struct files_struct * files = task->files;
struct fdtable *fdt;
spin_lock(&files->file_lock);
fdt = files_fdtable(files);
if (test_bit(fd, fdt->open_fds->fds_bits))
{
/* fd is in use */
}
spin_unlock(&files->file_lock);
但是,一旦解锁files
结构,信息可能会过时,所以真正的问题是你要用它做什么?
答案 1 :(得分:1)
假设您在内核中并且在struct task_struct * proc中有一个进程上下文,并且您只想检查给定的fd是否对应于该进程中的打开文件而不是以某种方式实际使用该文件:
int is_valid_fd_for_process(int fd, struct task_struct* proc)
{
int exists;
rcu_read_lock();
exists = (NULL != fcheck_files(proc->files, fd));
rcu_read_unlock();
return exists;
}
如果您确实想要使用此fd以某种方式解决的文件结构或将其存储以供稍后使用,您应该获取它的参考。请参阅fget的代码,该代码为当前流程执行此操作并使其适用于任何流程。
答案 2 :(得分:0)
如果您真的在 Linux内核中编程,那么您将查看您感兴趣的流程 但我认为你的意思是你正在编写一个用户空间程序,使用内核API在files_struct
附带的task_struct
。< / p>
我没有直接的方法来做到这一点。但是你应该能够对fcntl
进行一些破解。基本上,您查询文件描述符的状态标志,如果您收到错误,您知道(或多或少)文件描述符无效 - 因此可用。
但是如果你有多个线程,那就很有趣了。检查后,另一个线程可以使用文件描述符。如果您真的想要使用该文件描述符,可能需要dup2()
或F_DUPFD
,但我不确定您实际上要做什么。
示例代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main(void)
{
int rc, fd;
for (fd = 0; fd < 8; fd++) {
errno = 0;
rc = fcntl(fd, F_GETFL);
if (rc >= 0)
printf("fd %d is open\n", fd);
else if (errno == EBADF)
printf("fd %d is closed\n", fd);
else
printf("error %d querying fd %d \n", errno, fd);
}
return 0;
}