Run umask
in the shell; it will report 022
. The bits set in the umask
value are removed from permissions when creating files or directories.
In a single-threaded program, one way to really set 0777
permissions is to dink with umask()
:
mode_t old_mask = umask(0);
mkdir("/tmp/mkdir-test", 0777);
umask(old_mask);
That preserves the current setting except when you are sure you need to override it. However, this is dangerous in multi-threaded programs because the umask
value is global per-process, not per-thread (and thanks to Peter Cordes for pointing this out).
The other option for setting the permissions is to use chmod()
, and doing so is safe with multi-threaded programs too:
const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, 0) == 0)
chmod(dirname, target_mode);
The permissions set by the chmod()
function are not affected by umask
values.
The permissions on the call to mkdir()
are probably best set to 0
as shown; it will always work reliably and doesn't risk affecting other threads by modifying the umask
value. Alternatively, you could use the desired target permissions in the call to mkdir()
if you wanted to (and a previous version of this answer suggested doing so, using 0777
as the hard-coded target permissions).
const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, target_mode) == 0)
chmod(dirname, target_mode);
If you use this idiom, it is important that the mode passed to mkdir()
is the same as, or less permissive than, the mode passed to chmod()
— and 0
is less permissive than any other mode (and always works).
If you use a more relaxed mode in the call to mkdir()
, there's a TOCTOU (Time-of-Check, Time-of-Use) style vulnerability between the mkdir()
and chmod()
calls during which someone (some process) could get into the directory with relaxed permissions and wreak havoc; this could be a security risk.
Note that umask()
is a very simple system call and therefore very quick too (as system calls go, compared with heavyweights such as open()
, mkdir()
or chmod()
).