Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reopen a directory using openat

Tags:

c

linux

As it seems, it is possible to use openat() to reopen an already opened directory. For instance on my Linux system I can do the following:

#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;
}

I could not find this documented anywhere and it feels a bit like an edge case. Also I didn't find other code doing this. Is this well-defined behavior?

EDIT: changed the title: file -> directory

like image 290
peeed Avatar asked Dec 02 '25 14:12

peeed


2 Answers

This is just the same as calling open twice on the same file, which you are allowed to do:

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

where filename refers to an existing file (of any type) and flags1 and flags2 are any set of O_ flags that can be validly applied to that type of file and won't destroy its contents. (In particular, we assume that they do not include O_CREAT, O_TRUNC, or O_EXCL.)

fd1 and fd2 will refer to separate "open file descriptions", so for instance lseek on one will not affect the other, flock on one will block flock on the other, etc.

like image 136
zwol Avatar answered Dec 05 '25 06:12

zwol


With openat(), the first argument, fd, should be the file descriptor for a directory — such as the one you obtained from opening "." — or the special value AT_FDCWD (which means open relative paths relative the current directory). Note that the O_PATH option you use is a Linux-only extension to openat().

So, because you're using a valid file descriptor for a directory, the call to openat() should succeed. You now have two file descriptors both pointing (independently — with separate open file descriptions) to the current directory. In general, it is possible to open the same file multiple times in a single process (or in multiple processes — ensuring access by a single process is actually very hard on Unix-like (POSIX) systems).

There isn't a lot else you can do with those descriptors other than use them in *at() system calls. Either of the file descriptors would have been sufficient; opening both was overkill.

like image 32
Jonathan Leffler Avatar answered Dec 05 '25 08:12

Jonathan Leffler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!