Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way on a POSIX system to atomically create a directory if it doesn't exist?

Tags:

c

posix

Is there any way on a POSIX system to atomically create a directory only if it doesn't already exist?

Similar to

int fd = open( "/path/to/file", O_CREAT | O_EXCL | O_RDWR, 0644 );

This doesn't work:

int dfd = open( "/path/to/dir", O_DIRECTORY | O_CREAT | O_EXCL | O_RDWR, 0755 );

fails on my Solaris 11 and Ubuntu 20.04 systems with errno set to EINVAL on Solaris and ENOTDIR on Ubuntu.

The POSIX open() documentation states this for O_CREAT:

If the file exists, this flag has no effect except as noted under O_EXCL below. Otherwise, if O_DIRECTORY is not set ...

Well, it's not a file, and O_DIRECTORY is set.

(Inspired by the question Race condition stat and mkdir - there doesn't appear to be any way in POSIX to atomically create a directory if it doesn't already exist.)

like image 895
Andrew Henle Avatar asked Mar 04 '21 21:03

Andrew Henle


1 Answers

To answer the question in your title, mkdir does this -- there's no need for extra flags as mkdir will always "atomically" create a directory if and only if it does not exist (and the path is not a file).

From comments, it seems that you actually want to atomically create and open a directory, but it seems like this is an XY problem. Why, as you cannot open a directory for write in any case? If you first create and then open the directory (non-atomically) then there is no difference in behavior (and no race condition) as if in the interim, someone removed the directory, the open will fail.

If you're worried about only creating files in a directory with permissions set such that noone (else) can read them, you can check the permissions and ownership of the directory (with fstat) after opening it.

like image 76
Chris Dodd Avatar answered Nov 11 '22 14:11

Chris Dodd