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

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