1

similar question here.

But it only covers for a single directory level. For example if you gave /home/mypc/directory and if only directory doesn’t exist, it creates one. but when it comes to /home/mypc/directory/directory2 where both directory and directory2 doesn't exist, It gives a segmentation fault error. Could anyone suggest a suitable method for this.

thanks in advance.

Community
  • 1
  • 1
Laksith
  • 354
  • 3
  • 20

3 Answers3

6

If you don't want to depend on external processes, you could just write a recursive function to create a directory hierarchy:

int mkdirhier(char const* target) {
    int r = 0;

    struct stat st = {0};
    if (-1 != stat(target, &st))
        return 0; // already exists

    char* parent = strdup(target);
    if (strcmp(dirname(parent), target))
        r = mkdirhier(parent); // recurse

    if (parent)
        free(parent);

    if (!r && (r = mkdir(target, 0700)))
        perror(target);

    return r;
}

Live On Coliru

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <errno.h>
#include <time.h>

int mkdirhier(char const* target);

int main() {
    char buf[1024];
    srand(time(NULL));

    snprintf(buf, sizeof(buf), "./tree/some%d/dir%d/sub", rand(), rand());
    mkdirhier(buf);

    snprintf(buf, sizeof(buf), "/nopermissions/tree/some%d/dir%d/sub", rand(), rand());
    return mkdirhier(buf);
}

Prints

gcc main.c; ./a.out; find .
/nopermissions: Permission denied
.
./tree
./tree/some1804649601
./tree/some1804649601/dir1553142090
./tree/some1804649601/dir1553142090/sub
./main.cpp
./a.out
./main.c
sehe
  • 374,641
  • 47
  • 450
  • 633
1

Split the path into its components, and check each and every component of the path. So for the path /home/mypc/directory/directory2 you check and possibly create, in order

  1. /home
  2. /home/mypc
  3. /home/mypc/directory
  4. /home/mypc/directory/directory2
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • `#define fileLocation "/home/laksith/Desktop/log/lp"` actually Im going to give this as a macro . so when a person give any directory editing the line the files should be stored there. – Laksith Sep 10 '15 at 08:06
-1

If you are going to use mkdir to create the directory just add -p.

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

struct stat st = {0};

if (stat("/home/mypc/directory/directory2", &st) == -1) {
    system("mkdir --mode=744 -p /home/mypc/directory/directory2");
}
  • then what does it it do. could you explain – Laksith Sep 10 '15 at 08:08
  • First it will verify the status of the directory. If it cannot obtain this status the directory does not exists. So you call the system to execute `mkdir` who creates the full path with `-p`. – Lucas Magalhães Sep 10 '15 at 08:15
  • 1
    @Lucas, there are reasons other than non-existence that `stat` might fail, (eg, permissions, too many symbolic links, a component of the path is not a directory, etc.) so it is incorrect to claim that stat failure implies non-existence. – William Pursell Sep 10 '15 at 08:26
  • 2
    -1: Using `system` is not a very good solution: inefficiency of forking a process, dependency on `PATH`, vulnerability to [code injection](https://en.wikipedia.org/wiki/Code_injection), won't easily work with a file path with spaces... – Basile Starynkevitch Sep 10 '15 at 09:12
  • @WilliamPursell You are correct, as the documentation describes. – Lucas Magalhães Sep 10 '15 at 10:03
  • @BasileStarynkevitch Thanks for the explanation. – Lucas Magalhães Sep 10 '15 at 10:04