Linux C如何打开一个目录并获取文件描述符

8
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

int main()
{
    int fd;
    if ((fd = open("/home/zhangke", O_DIRECTORY | O_RDWR)) ==-1)
    {
        printf("error %s\n", strerror(errno));
       return -1;
    }
    return 0;
}

/home/zhangke是一个目录并且已经存在。我收到了“Is a directory”错误,那么我该如何使用open()来正确地获取一个目录的fd呢?


2
使用 opendir() 函数打开一个目录。 - Barmar
1
你无法为目录获取文件描述符。 - Barmar
4
实际上,你可以获得一个目录的文件描述符,但是如果尝试使用 O_RDWR,则会出现错误。请使用 O_RDONLY - Barmar
5
如果您使用dir = opendir(...);打开一个目录,可以使用dirfd(dir)获取底层文件描述符。在使用2.6.39、3.x、4.x或更高版本内核的Linux中,可以使用open(dirpath, O_DIRECTORY | O_PATH)获得指定目录的文件描述符,以便与fchdir()和*at()函数一起使用;但请参阅有关手册页上O_PATH限制的说明。 - Nominal Animal
2
open(dirpath, O_DIRECTORY | O_PATH)open(dirpath, O_RDONLY | O_DIRECTORY) 的区别在于,如果您没有(执行和)读取目录的访问权限,则后者将失败。而前者仅需要执行访问权限。 - Nominal Animal
显示剩余5条评论
1个回答

14
请使用访问模式O_RDONLY代替O_RDWR。来自open(2)错误列表:

EISDIR路径名引用了一个目录并请求的访问涉及写入(即设置了 O_WRONLYO_RDWR)。

据我所知,没有一种方法可以原子地创建和打开一个目录。 O_CREAT标志总是创建一个普通文件。当打开一个现有名称时,O_DIRECTORY只有意义检查该名称是否是目录。

1
请注意,在目录中使用O_CREAT标志也会导致EISDIR错误。 - papirrin
有没有一种方法可以在一个调用中创建一个目录并获取该目录的打开文件描述符?(可能是通过传递 O_CREAT 来实现) - Antonin Décimo
我不这么认为。如果描述符指向一个空目录,你会怎么做?你不能以写模式打开目录。 - Barmar
@Barmar:和空目录路径一样,但使用at函数并减少竞争条件。例如,使用openat在其中创建文件。 - user2357112
@user2357112supportsMonica 我想设计师们没有考虑到这点,因为他们没有提供一种原子地创建和打开目录的方法。目录只能用mkdir(2)创建,它不会打开它。 - Barmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接