Alex Rivera | Logout

How can I create a directory tree in C++ on Linux?

Asked 2009-03-23T20:10:26.110
145

I want an easy way to create multiple directories in C++ on Linux.

For example, I want to save a file lola.file in the directory:

/tmp/a/b/c

but if the directories are not there I want them to be created automagically. A working example would be perfect.

Edit
Report

1 Answer

102

With C++17 or later, there's the standard header <filesystem> with function std::filesystem::create_directories which should be used in modern C++ programs. The C++ standard functions do not have the POSIX-specific explicit permissions (mode) argument, though.

However, here's a C function that can be compiled with C++ compilers.

/*
@(#)File:           mkpath.c
@(#)Purpose:        Create all directories in path
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 1990-2020
@(#)Derivation:     mkpath.c 1.16 2020/06/19 15:08:10
*/

/*TABSTOP=4*/

#include "posixver.h"
#include "mkpath.h"
#include "emalloc.h"

#include <errno.h>
#include <string.h>
/* "sysstat.h" == <sys/stat.h> with fixup for (old) Windows - inc mode_t */
#include "sysstat.h"

typedef struct stat Stat;

static int do_mkdir(const char *path, mode_t mode)
{
    Stat            st;
    int             status = 0;

    if (stat(path, &st) != 0)
    {
        /* Directory does not exist. EEXIST for race condition */
        if (mkdir(path, mode) != 0 && errno != EEXIST)
            status = -1;
    }
    else if (!S_ISDIR(st.st_mode))
    {
        errno = ENOTDIR;
        status = -1;
    }

    return(status);
}

/**
** mkpath - ensure all directories in path exist
** Algorithm takes the pessimistic view and works top-down to ensure
** each directory in path exists, rather than optimistically creating
** the last element and working backwards.
*/
int mkpath(const char *path, mode_t mode)
{
    char           *pp;
    char           *sp;
    int             status;
    char           *copypath = STRDUP(path);

    status = 0;
    pp = copypath;
    while (status == 0 && (sp = strchr(pp, '/')) != 0)
    {
        if (sp != pp)
        {
            /* Neither root nor double slas
answered 2009-03-23T20:52:50.080

Your Answer