linux c mkdir遇到的坑

mkdir创建目录时,有时会报权限问题错误,创建目录失败,有时可以正常创建目录,但mkdir设置目录权限为S_IRWXU | S_IRWXG | S_IRWXO时,权限一直不正确,可能是这个问题导致的创建目录失败;
1.mkdir函数对创建的目录进行设置权限之前,需要调用umask(0)函数,否则创建的目录权限不是自己传入的权限;
权限值:mode&(~umask权限值取反);
2.递归创建目录时,需要已创建的上层目录为777,/home/data中data目录为777权限, 20190202这个目录或该目录子目录创建时,权限正确;

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章