Richard Hansen
2014-05-30 07:16:57 UTC
Hi all,
With Issue 7 it's possible to create a regular file and open it at the
~same time via open(O_CREAT). (Does the spec say that the file
creation and open is atomic? If so, it isn't immediately obvious.)
As far as I can tell, it's not possible to create and open a directory
atomically -- you must first call mkdir()/mkdirat() and then make a
separate open() call. Is that correct?
If so, doesn't this open up operations like 'mkdir -p' to race
conditions? (malicious code could sneak in between a mkdirat() and the
subsequent open())
Do any implementations allow you to atomically create and open a
directory as an extension to the spec, perhaps via
open(O_CREAT|O_DIRECTORY)? For example:
#define _XOPEN_SOURCE 700
#include <fcntl.h>
#include <unistd.h>
int
main(int argc, const char *argv[])
{
int fd_parent = open(".", O_WRONLY|O_DIRECTORY);
for (int i = 1; i < argc; ++i) {
int fd_new = openat(fd_parent, argv[i],
O_WRONLY|O_CREAT|O_DIRECTORY, 0777);
close(fd_parent);
fd_parent = fd_new;
}
close(fd_parent);
return 0;
}
Thanks,
Richard
With Issue 7 it's possible to create a regular file and open it at the
~same time via open(O_CREAT). (Does the spec say that the file
creation and open is atomic? If so, it isn't immediately obvious.)
As far as I can tell, it's not possible to create and open a directory
atomically -- you must first call mkdir()/mkdirat() and then make a
separate open() call. Is that correct?
If so, doesn't this open up operations like 'mkdir -p' to race
conditions? (malicious code could sneak in between a mkdirat() and the
subsequent open())
Do any implementations allow you to atomically create and open a
directory as an extension to the spec, perhaps via
open(O_CREAT|O_DIRECTORY)? For example:
#define _XOPEN_SOURCE 700
#include <fcntl.h>
#include <unistd.h>
int
main(int argc, const char *argv[])
{
int fd_parent = open(".", O_WRONLY|O_DIRECTORY);
for (int i = 1; i < argc; ++i) {
int fd_new = openat(fd_parent, argv[i],
O_WRONLY|O_CREAT|O_DIRECTORY, 0777);
close(fd_parent);
fd_parent = fd_new;
}
close(fd_parent);
return 0;
}
Thanks,
Richard