Tworzenie nowego katalogu w C

97

Chcę napisać program, który sprawdza istnienie katalogu; jeśli ten katalog nie istnieje, tworzy katalog i plik dziennika w nim, ale jeśli katalog już istnieje, tworzy po prostu nowy plik dziennika w tym folderze.

Jak mam to zrobić w C z Linuksem?

Jeegar Patel
źródło
1
Funkcja mkdir tworzy nowy katalog, blog.tremend.ro/2008/10/06/ ...
fsonmezay
1
może dlatego, że możesz znaleźć rozwiązanie w google lub nawet tutaj, wykonując proste wyszukiwanie stackoverflow.com/search?q=C+make+directory . Nawiasem mówiąc, nie jestem facetem, który przegłosował.
fsonmezay
Proszę edytować swoje pytanie pokazać kod do tej pory . Powinieneś dołączyć przynajmniej zarys (ale najlepiej minimalny powtarzalny przykład ) kodu, z którym masz problemy, wtedy możemy spróbować pomóc w konkretnym problemie. Przeczytaj również artykuł Jak pytać .
Toby Speight

Odpowiedzi:

148

Sprawdź, statczy katalog istnieje,

I mkdirstworzyć katalog.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat st = {0};

if (stat("/some/directory", &st) == -1) {
    mkdir("/some/directory", 0700);
}

Możesz zobaczyć podręcznik tych funkcji za pomocą poleceń man 2 stati man 2 mkdir.

Arnaud Le Blanc
źródło
5
Uważam, że mkdirw Linuksie modeoprócz path.
Paul R
1
@Uku: przekazywanie nieprawidłowej liczby parametrów do funkcji jest niezdefiniowanym zachowaniem, więc chociaż może się wydawać, że działa dla Ciebie w jednym przypadku, nie powinieneś na nim polegać.
Paul R
3
Jaki jest cel sprawdzania, czy katalog nie istnieje przed jego utworzeniem? Nawet jeśli stat mówi, że jeszcze nie istnieje, w międzyczasie inny proces mógł go utworzyć.
Brandin
2
@Brandin Chyba ślepo odpowiedziałem na pytanie OP :) Masz rację co do stanu wyścigu.
Arnaud Le Blanc
4
Zostanie to oznaczone przez większość dobrych analizatorów statycznych jako ryzyko
TOCTOU
22

Możesz użyć mkdir:

$ man 2 mkdir

#include <sys/stat.h>
#include <sys/types.h>

int result = mkdir("/home/me/test.txt", 0777);
Paul R.
źródło
Czy spowoduje to usunięcie i zastąpienie istniejących katalogów?
jjxtra
@jjxtra :: nie, powinno się nie powieść, jeśli katalog już istnieje, w podobny sposób, jakbyś próbował wykonać tę samą operację z wiersza poleceń.
Paul R
Tak bym się spodziewał. Masz jakiś problem z wydajnością, pomijając sprawdzanie statystyk i za każdym razem po prostu mkdir?
jjxtra
@jjxtra: jeśli nie tworzysz tysięcy katalogów, nie wyobrażam sobie, że będzie jakaś wymierna różnica w wydajności.
Paul R
7

Chcę napisać program, który (...) tworzy katalog i (...) plik w nim

ponieważ jest to bardzo częste pytanie, oto kod do tworzenia wielu poziomów katalogów, a następnie wywoływania fopen. Używam rozszerzenia gnu, aby wydrukować komunikat o błędzie za pomocą printf.

void rek_mkdir(char *path) {
    char *sep = strrchr(path, '/');
    if(sep != NULL) {
        *sep = 0;
        rek_mkdir(path);
        *sep = '/';
    }
    if(mkdir(path, 0777) && errno != EEXIST)
        printf("error while trying to create '%s'\n%m\n", path); 
}

FILE *fopen_mkdir(char *path, char *mode) {
    char *sep = strrchr(path, '/');
    if(sep) { 
        char *path0 = strdup(path);
        path0[ sep - path ] = 0;
        rek_mkdir(path0);
        free(path0);
    }
    return fopen(path,mode);
}
Jens Harms
źródło
3
tylko moje 5 centów - tryb 0777 dla dir może nie być pożądany - może 0755 jest lepszy, a może nawet przekazać parametr?
ivan.ukr
@ ivan.ukr 0777 jest poprawne, tryb zostanie zmodyfikowany przez użytkownika umask. Na przykład. dla umaski 022 daje to 755 lub dla
umaski