How to create directory with right permissions using C on Posix
Asked Answered
V

3

9

I am trying to write a simple C program that creates directories (a mkdir clone.). This is what I have so far:

#include <stdlib.h>
#include <sys/stat.h> // mkdir
#include <stdio.h> // perror

mode_t getumask()
{
    mode_t mask = umask(0);
    umask (mask);
    return mask;
}

int main(int argc, const char *argv[])
{
    mode_t mask = getumask();
    printf("%i",mask);

    if (mkdir("trial",mask) == -1) {
        perror(argv[0]);
        exit(EXIT_FAILURE);
    }
    return 0;
}

This code creates directory with d--------- but I want it to create it with drwxr-xr-x like mkdir do? What am I doing wrong here?

Verboten answered 13/4, 2012 at 20:38 Comment(2)
What does the diagnostic print produce? It might work better if you added a newline after the %i, and it would be more easily legible if you used %o or %.4o instead of %i. Also, you appear to be missing #include <sys/stat.h> which declares umask() and mkdir().Narcotic
It produces 22 with %4o.Verboten
D
2

As Eric says, umask is the complement of the actual permission mode you get. So instead of passing mask itself to mkdir(), you should pass 0777-mask to mkdir().

Danelaw answered 13/4, 2012 at 21:8 Comment(2)
Thanks, I indeed wanted to incorporate umask to get correct permission. I changed 0777-mask to 0777 & ~mask though. :)Verboten
I actually needn't use umask directly, since appearantly, mkdir already does that. So using 0777 results in a directory with drwxr-xr-x when my umask is 022Verboten
P
13

You seem to be misunderstanding what umask is used for. It sets/retrieves the process's file mode creation mask, which in turn is used to turn off bits in the file mode you specify in calls like mkdir, like this (pseduo-code):

real_mode = requested_mode & ~umask

So in your code, since you pass in the value of the umask itself, you end up specifying permissions as zero, which is exactly what you see.

Instead, you should specify the permissions you want in the call to mkdir, like this:

mkdir("trial", 0755)
Plaint answered 13/4, 2012 at 21:1 Comment(4)
I think yasar11732 wants to incorporate the current user's umask setting, not hard coding 0755. Just my guess.Danelaw
There is normally no need to mess with the user's umask in an application; libc already does that for you in mkdir(). So hardcoding 0755 or 0775 is perfectly fine.Furcate
What if I umask 0? Hardcoding 0755 will make it 0755 instead of desired 0777. Maybe hardcoding 0777 is more correct, as yasar11732 commented, but it is not harmful to 0777 & ~mask.Danelaw
I'm trying to create directories with drwxrwxr-x permissions, if I've understood the mkdir docs correctly then 0775 should give that but it doesn't. Do I need to be su?Evolute
D
2

As Eric says, umask is the complement of the actual permission mode you get. So instead of passing mask itself to mkdir(), you should pass 0777-mask to mkdir().

Danelaw answered 13/4, 2012 at 21:8 Comment(2)
Thanks, I indeed wanted to incorporate umask to get correct permission. I changed 0777-mask to 0777 & ~mask though. :)Verboten
I actually needn't use umask directly, since appearantly, mkdir already does that. So using 0777 results in a directory with drwxr-xr-x when my umask is 022Verboten
D
1

Disclaimer: I extracted this answer from the OPs question. Answers should not be contained in the question itself.


Answer provided by yasar:

This is the working solution for me:

int main(int argc, const char *argv[])
{
    if (mkdir("trial",0777) == -1) {
        perror(argv[0]);
        exit(EXIT_FAILURE);
    }
    return 0;
}

Setting right permissions according to umask is automatically handled. So I only needed to call mkdir with full permissions, and that gets chopped according to current umask.

Demonetize answered 19/8, 2021 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.