murilo ijanc'

Posts | CVS
Mail | PGP

C Makedirs

Opa pessoal, quem nunca necessitou utilizar aquela função makedirs que existem em inúmeras linguagens. No python existe os.markdirs no rust existe std::fs::createdirall basicamente essa função cria um diretório recursivamente por exemplo:

Imagine que exista o path: /home/mbsd/src e você queria criar o diretório para o seu projeto: /home/mbsd/src/projetos/projeto1.

Se eu fosse fazer isso no meu shell, simplesmente digitaria assim:

$ mkdir ~/src/projetos/projeto1
mkdir: /home/mbsd/src/projetos/projeto1: No such file or directory

Op’s deu erro, se você olhar na página de manual do mkdir(1) existe uma opção para criar todo o caminho.

$ mkdir -p ~/src/projetos/projeto1

Vamos criar agora a nossa função em C para realizar o mesmo processo das funções listadas acima, basicamente iremos utilizar mkdir(2) iterar sobre o arranjo de char (path) e checar ocorrências do caracter /. Bora lá então:

#include 

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
makedirs(const char *path, mode_t mode)
{
    char *tmp = NULL;
    char *p = NULL;
    size_t len;
    int sta;

    if (path == NULL) {
        errno = ENOENT;
        return -1;
    }

    tmp = strdup(path);
    p = tmp;

    for (; *p; p++)
        if (*p == '/') {
            *p = 0;
            mkdir(tmp, mode);
            *p = '/';
        }
    free(tmp);

    sta = mkdir(path, mode);

    return sta;
    
}

int
main(int argc, char *argv[])
{
    int sta;
    const char *p = "/home/mbsd/src/projetos/projetos1";

    if ((sta = makedirs(p, S_IRWXU)) != 0) {
        fprintf(stderr, "failed create %s: %s\n", p, strerror(errno));
        exit(2);
    }
    return (0);
}