What is the expected behavior of open (name, O_CREAT | O_DIRECTORY, mode)?

Despite a thorough reading of the relevant standard documentation , I cannot understand what the expected behavior is in POSIX-compatible systems when an open system call is invoked with flags, including O_CREAT|O_DIRECTORY .

The standard states that

If O_CREAT and O_DIRECTORY are set and , the requested access mode is not O_WRONLY or O_RDWR, no result is specified.

However, it does not indicate system behavior with (O_CREAT|O_DIRECTORY|O_WRONLY) or with (O_CREAT|O_DIRECTORY|O_RDWR) . Indeed (as I understand it) the behavior of EISDIR applies only to existing directories.

In the O_CREATE section, the standard indicates that when a named file does not exist,

if O_DIRECTORY is not set , the file should be created as a regular file; [...]

but again, it is not indicated what will happen if O_DIRECTORY also set.

I have looked through the manual pages of NetBSD (which, as you know, cares a lot about POSIX compliance) and Linux (it is a widely used system, although it is actually not POSIX), but I cannot find any explanation.

Is it possible to say that the use of both flags is not specified? And if so, what is the most common behavior?

Is open(name, O_CREAT|O_DIRECTORY, mode) equivalent to mkdir for any POSIX compatible OS?

+5
source share
3 answers

netbsd itself contains the following in vn_open:

 if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY)) return EINVAL; 

therefore, any combination with the two deviates directly.

on linux it is a little more hairy, but any trivial test will show you that the directory is also not created, but you can get the file

for beats I also checked freebsd, which never ends up creating anything with O_DIRECTORY in the first place

if you are looking for mkdir that fd returns to you, I'm afraid there is nothing like that. on the other hand, you should be able to safely open with O_DIRECTORY everything that you mkdir'ed.

+2
source

I think you misunderstood what O_DIRECTORY . This is not to create a directory, but to ensure that the "file" opened by open(2) is a directory.

O_DIRECTORY
If the path is resolved to a file without a directory, errno will fail and set to [ENOTDIR].

This is how POSIX documents it (cited above).

However, it does not determine the behavior of the system with either of them (O_CREAT | O_DIRECTORY | O_WRONLY) or (O_CREAT | O_DIRECTORY | O_RDWR)

The behavior of O_CREAT|O_DIRECTORY|O_WRONLY and O_CREAT|O_DIRECTORY|O_RDWR equivalent to O_CREAT|O_WRONLY and O_CREAT|O_RDWR respectively, the path name (first argument open (2)) is a directory. The presence of O_DIRECTORY is to open the file is a directory - it does not affect anything.

Is it possible to say that the use of both flags is not specified? And if so, what is the most common behavior?

This means that the behavior of a particular combination is O_CREAT | O_DIRECTORY O_CREAT | O_DIRECTORY not specified; does not mean the use of individual flags (with or without other flags) is not indicated.

Open (name, O_CREAT | O_DIRECTORY, mode), equivalent to mkdir for any POSIX compatible operating system?

Not at all. That is why he remained unspecified. On Linux, this is definitely not - a regular file is created:

When both O_CREAT and O_DIRECTORY are indicated in the flags, and the file specified by the path name does not exist, open () will create a regular file (i.e. O_DIRECTORY is ignored).

To create a directory, you must use mkdir(2) .

+3
source

The answers are not correct yet. Implementations may support the creation of directories through O_CREAT|O_DIRECTORY|O_WRONLY or O_CREAT|O_DIRECTORY|O_RDWR , but they are not required. This was clarified in 2014, as you can see in the Austin group error debugger :

open("/path/to/existing/directory", O_CREAT) should fail with EISDIR , but implementations should be allowed to support creating and opening a directory through open("/path/to/directory", O_CREAT|O_DIRECTORY) as an extension

with the following rationale:

The standard does not specify behavior when open() is called with O_CREAT|O_RDONLY (or O_CREAT|O_SEARCH ) in an existing directory. In addition, some systems want to allow the creation of directories using the open() function. This should be a valid, but not mandatory extension.

The text you specified from the current version of the standard

If O_CREAT and O_DIRECTORY are set, and the requested access mode is not O_WRONLY or O_RDWR, no result is specified.

was just one of the changes made.

One of the reasons for this, described by Rich Felkner , is that it will provide an interface for atomically creating and opening a directory.

However, I do not know if any POSIX implementation there really provides for creating a directory through open .

+2
source

Source: https://habr.com/ru/post/1271103/


All Articles