使用openat重新打开目录

时间:2019-02-20 19:27:51

标签: c linux

看起来,可以使用openat() 重新打开一个已经打开的目录。例如,在我的Linux系统上,我可以执行以下操作:

#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(void) {

    int fd1 = open(".", O_PATH);
    if (fd1 == -1) {
        perror("open");
        return 1;
    }
    int fd2 = openat(fd1, ".", O_RDONLY);
    if (fd2 == -1) {
        perror("openat");
        close(fd1);
        return 1;
    }
    close(fd1);

    // do fancy things with fd2, now opened
    // with access mode read-only

    return 0;
}

我在任何地方都找不到此文档,感觉有点像是边缘情况。我也没有发现其他代码这样做。这是行为明确的行为吗?

编辑:更改标题:文件->目录

2 个答案:

答案 0 :(得分:2)

这与在同一文件上两次调用open相同,您可以执行以下操作:

int fd1 = open("filename", flags1);
int fd2 = open("filename", flags2);

其中filename是指现有文件(任何类型),而flags1flags2是可以有效地应用于该类型的O_标志的任何集合文件,并且不会破坏其内容。 (特别是,我们假定它们不包括O_CREATO_TRUNCO_EXCL。)

fd1fd2分别指代“ open file descriptions”,因此,例如,其中一个上的lseek不会影响另一个,例如flock阻止flock,等等。

答案 1 :(得分:2)

对于openat(),第一个参数fd应该是目录的文件描述符(例如,您从打开"."中获得的目录)或特殊值{{1 }}(这意味着打开相对于当前目录的相对路径)。请注意,您使用的AT_FDCWD选项是openat()的仅Linux扩展。

因此,由于您正在使用目录的有效文件描述符,因此对O_PATH的调用应该会成功。现在,您有两个文件描述符,它们都(分别具有单独的打开文件描述)指向当前目录。通常,可以在单个进程中(或多个进程中)多次打开同一文件-确保在类似Unix(POSIX)的系统上,单个进程的访问实际上非常困难。

除了在openat()系统调用中使用这些描述符外,您无法做很多其他事情。任何一个文件描述符就足够了;都开门太杀了。