linux c mkdir遇到的坑

mkdir创建目录时,有时会报权限问题错误,创建目录失败,有时可以正常创建目录,但mkdir设置目录权限为S_IRWXU | S_IRWXG | S_IRWXO时,权限一直不正确,可能是这个问题导致的创建目录失败;
1.mkdir函数对创建的目录进行设置权限之前,需要调用umask(0)函数,否则创建的目录权限不是自己传入的权限;
权限值:mode&(~umask权限值取反);
在终端执行:umask
0002
touch 空文件默认属性最大为666,ugo都没有可执行x的权限
之后将666-002等于664
touch test.txt
-rw-rw-r-- 1 zhangsan zhangsan 78 Dec 14 15:48 m.txt
touch 目录默认属性为777, 因为目录没有x执行权限的话,就无法进入该目录
777-002等于775
mkdir 20201214
drwxrwxr-x 2 zhangsan zhangsan 4096 Dec 14 16:15 20201214
所以在创建文件或目录时,需要执行umask(0),否则设置的权限不是自己想要的结果
2.递归创建目录时,需要已创建的上层目录为777,/home/data中data目录为777权限, 20190202这个目录或该目录子目录创建时,权限正确;

#include 
#include 
#include 
#include 
#include 

int make_dir_iterator_rec(int* p_err_cd, char *mkdir_path)
{
    char tmp_buf[2000+1];
    char tmp_dir[2000+1];
    char *p_tmp = NULL ,*p_tmp1 = NULL;
    int n_ret = 0;
    mode_t old_mask;
    
    memset(tmp_buf,0,sizeof(tmp_buf));
    memset(tmp_dir,0,sizeof(tmp_dir));

    if(strlen(mkdir_path) > 2000 )
    {
        *p_err_cd = 1000;
        return -1;
    }
    strcat(tmp_buf,"/");

    p_tmp1 = mkdir_path;
    while(1)
    {
        if(p_tmp1[0] =='\0')
            return 0;
        p_tmp = strchr(p_tmp1,'/');
        if(p_tmp == NULL)
        {
            strcat(tmp_buf,p_tmp1);
            old_mask = umask(0);
            n_ret=mkdir(tmp_buf, S_IRWXU | S_IRWXG | S_IRWXO);
            umask(old_mask);
            if(n_ret!=0 && errno!= EEXIST)
            {
                *p_err_cd = 3000 + errno;
                return -1;
            }
            break;
        }
        else if(p_tmp == p_tmp1 )
        {
            p_tmp1++;
            continue;
        }
        memset(tmp_dir,0x00,sizeof(tmp_dir));
        memcpy(tmp_dir,p_tmp1,p_tmp-p_tmp1+1);
        strcat(tmp_buf,tmp_dir);
        /*
         *mkdir(path, mode)设置目录权限时,需要调用umask(cmode)函数
         *最终权限值:mode&(~cmode),即mode与(cmode取反)
         */
        old_mask = umask(0);
        n_ret=mkdir(tmp_buf, S_IRWXU | S_IRWXG | S_IRWXO);
        umask(old_mask);
        
        if(n_ret!=0 && errno!= EEXIST)
        {
            *p_err_cd = 3000 + errno;
            return -1;
        }
        p_tmp1 = p_tmp++;
    }

    return 0;
}

int main()
{
    char path[1024];
    int error = 0;
    memset(path, 0x00, sizeof(path));
    
    memcpy(path, "/home/data/20190202", sizeof(path));
    int res = make_dir_iterator_rec(&error, path);
    if (res != 0)
    {
        printf("make_dir_iterator_rec fail, erron=%d,msg=%s\n", error, strerror(errno));
        return -1;
    }

    return 0;
}

你可能感兴趣的:(linux,C,c语言,mkdir,umask,递归创建目录)