重新打开一个目录使用openat

3

看起来,可以使用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;
}

我无法在任何文档中找到这个内容,感觉有点像一个边缘情况。我也没有找到其他代码这样做。这是否是明确定义的行为?

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


无论如何,您都可以多次打开文件以进行读取。 - Weather Vane
1
首先,在这两种情况下,您只是获得了一个dirfd,并且在任何_at函数中使用dirfd来解析相对路径,因此行为仍然是明确定义的。 - Ahmed Masud
你不能使用文件来做这件事,只能使用目录,因为“.”是相对于目录本身的名称。 - Barmar
@Barmar 没错,我会更新标题,使其更具描述性。 - peeed
2个回答

3

这与在同一文件上两次调用open的效果相同,这是允许的:

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

filename指现有的任何类型文件,flags1flags2是可应用于该类型文件且不会破坏其内容的任意一组O_标志。 (特别地,我们假设它们不包括 O_CREAT , O_TRUNC 或 O_EXCL 。)

fd1fd2将引用单独的“打开文件描述符”,因此例如对其中一个的lseek不会影响另一个,对其中一个的flock会阻塞另一个的flock等。


3
使用 openat() 函数时,第一个参数 fd 应该是一个目录的文件描述符,比如你通过打开 "." 得到的那个,或者特殊值 AT_FDCWD(表示相对于当前目录打开相对路径)。请注意,你使用的 O_PATH 选项是 Linux 扩展的 openat()

所以,因为你使用了有效的目录文件描述符,调用 openat() 应该会成功。现在你有两个文件描述符都指向当前目录(独立地 —— 每个描述符都有自己的打开文件描述符)。通常来说,在单个进程中(或多个进程中)可以多次打开同一个文件(确保单个进程访问实际上在类 Unix(POSIX)系统上非常困难)。

除了在 *at() 系统调用中使用它们之外,你不能做太多其他事情。任何一个文件描述符都足够了;打开两个是过度的。


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