I have a POSIX shared memory directory which gets blown away on reboot and needs to be recreated on occasion. An example,
#include <sys/stat.h>
#include <sys/file.h>
int main(int argc, char argv[])
{
struct stat st = {0};
if (stat("/dev/shm/example", &st) == -1) {
mkdir("/dev/shm/example", 0777);
}
}
This creates the directory with missing write permissions for group/others:
drwxr-xr-x. 2 *** *** *** May 14 12:00 example
I've tried experimenting with the mode_t flags and even replaced "0777" with "S_IRWXU | S_IRWXG | S_IRWXO". I do need the directory to have permission flag 0777.
You need to set the permission explicitly or reset your file creation mask with the umask()
function.
Per the POSIX mkdir()
documentation (bolding mine):
The
mkdir()
function shall create a new directory with name path. The file permission bits of the new directory shall be initialized from mode. These file permission bits of the mode argument shall be modified by the process' file creation mask.
The only thread-safe way to create a file or directory with the exact permissions you want is to explicitly set them after creation:
mkdir("/dev/shm/example", 0777);
chmod("/dev/shm/example", 0777);
Of course, you'd do well to actually check the return values for those calls.
Calling umask()
to set and restore your file creation mask is not thread-safe:
mode_t old = umask( 0 );
mkdir("/dev/shm/example", 0777);
umask( old );
There are multiple race conditions possible with doing that:
old
mask you get with the first call to umask()
can be the 0
set by another threadIf either of those race conditions happens, either
Or all three.
So don't call umask()
when you need to set permission bits exactly. Set the mode explicitly with a call to [f]chmod()
(The possible issues that could arise from creating directories in /dev/shm
is probably worth another question...)