std::filesy..._directories(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– std::filesy..._directories(3) β€” std::filesystem::create_directory,std::filesystem::create_directories πŸ’–

okay bestie, welcome to the C++ Standard Libary manual (yes, that spelling is literally on the page, not me πŸ’€). This whole page is serving directory-creation realness: std::filesystem::create_directory and std::filesystem::create_directories.


πŸ’– NAME πŸ’–

The stars of the show: std::filesystem::create_directory,std::filesystem::create_directories β€” and the description is literally std::filesystem::create_directory,std::filesystem::create_directories again. Double naming? Iconic. Periodt.

🌸 Synopsis 🌸

Defined in header <filesystem>. Every overload here is (since C++17), no cap.

(1) (since C++17)

bool create_directory( const std::filesystem::path& p );

(2) (since C++17)

bool create_directory( const std::filesystem::path& p,
                       std::error_code& ec ) noexcept;

(3) (since C++17)

bool create_directory( const std::filesystem::path& p,
                       const std::filesystem::path& existing_p );

(4) (since C++17)

bool create_directory( const std::filesystem::path& p,
                       const std::filesystem::path& existing_p,
                       std::error_code& ec ) noexcept;

(5) (since C++17)

bool create_directories( const std::filesystem::path& p );

(6) (since C++17)

bool create_directories( const std::filesystem::path& p,
                         std::error_code& ec );

What they actually do, bestie:

  • 1,2) β€” Creates the directory p as if by POSIX mkdir() with a second argument of static_cast<int>(std::filesystem::perms::all) (the parent directory must already exist). If the function fails because p resolves to an existing directory, no error is reported. Otherwise on failure an error is reported.
  • 3,4) β€” Same as (1,2), except that the attributes of the new directory are copied from existing_p (which must be a directory that exists). It is OS-dependent which attributes are copied: on POSIX systems, the attributes are copied as if by
stat(existing_p.c_str(), &attributes_stat)
mkdir(p.c_str(), attributes_stat.st_mode)

On Windows OS, no attributes of existing_p are copied.

  • 5,6) β€” Executes (1,2) for every element of p that does not already exist. If p already exists, the function does nothing (this condition is not treated as an error).

πŸŽ€ Parameters πŸŽ€

  • p β€” the path to the new directory to create.
  • existing_p β€” the path to a directory to copy the attributes from.
  • ec β€” out-parameter for error reporting in the non-throwing overload.

✨ Return value ✨

true if a directory was newly created for the directory p resolves to, false otherwise.

πŸ”₯ Exceptions πŸ”₯

Any overload not marked noexcept may throw std::bad_alloc if memory allocation fails.

  • 1,5) β€” Throws std::filesystem::filesystem_error on underlying OS API errors, constructed with p as the first path argument and the OS error code as the error code argument.
  • 2,6) β€” Sets a std::error_code& parameter to the OS API error code if an OS API call fails, and executes ec.clear() if no errors occur.
  • 3) β€” Throws std::filesystem::filesystem_error on underlying OS API errors, constructed with p as the first path argument, existing_p as the second path argument, and the OS error code as the error code argument.
  • 4) β€” Sets a std::error_code& parameter to the OS API error code if an OS API call fails, and executes ec.clear() if no errors occur.

🧚 Notes 🧚

The attribute-preserving overload (3,4) is implicitly invoked by copy() when recursively copying directories. Its equivalent in boost.filesystem is copy_directory (with argument order reversed).

🌈 Example 🌈

// Run this code

#include <cassert>
#include <cstdlib>
#include <filesystem>

int main()
{
    std::filesystem::current_path(std::filesystem::temp_directory_path());

    // Basic usage
    std::filesystem::create_directories("sandbox/1/2/a");
    std::filesystem::create_directory("sandbox/1/2/b");

    // Directory already exists (false returned, no error)
    assert(!std::filesystem::create_directory("sandbox/1/2/b"));

    // Permissions copying usage
    std::filesystem::permissions(
        "sandbox/1/2/b",
        std::filesystem::perms::others_all,
        std::filesystem::perm_options::remove
    );
    std::filesystem::create_directory("sandbox/1/2/c",
                                      "sandbox/1/2/b");

    std::system("ls -l sandbox/1/2");
    std::system("tree sandbox");
    std::filesystem::remove_all("sandbox");
}

πŸ’» Possible output πŸ’»

drwxr-xr-x 2 user group 4096 Apr 15 09:33 a
drwxr-x--- 2 user group 4096 Apr 15 09:33 b
drwxr-x--- 2 user group 4096 Apr 15 09:33 c
sandbox
└── 1
    └── 2
        β”œβ”€β”€ a
        β”œβ”€β”€ b
        └── c

🩹 Defect reports 🩹

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. The columns are DR, Applied to, Behavior as published, and Correct behavior β€” here's the tea:

  • DR LWG 2935, applied to C++17 β€” behavior as published: "error if target already exists but is not a directory"; correct behavior: "not error".
  • DR LWG 3014, applied to C++17 β€” behavior as published: "error_code overload of create_directories marked noexcept but can allocate memory"; correct behavior: "noexcept removed".
  • DR P1164R1, applied to C++17 β€” behavior as published: "creation failure caused by an existing non-directory file is not an error"; correct behavior: "made error".

πŸ‘€ See also πŸ‘€

  • create_symlink, create_directory_symlink (C++17) β€” creates a symbolic link (function).
  • copy (C++17) β€” copies files or directories (function).
  • perms (C++17) β€” identifies file system permissions (enum).

That's the whole page, bestie. Footer shoutout: source is http://cppreference.com, version/date is 2024.06.10, and the footer also carries the std::filesy..._directories(3) header energy. Stay slay, and may your parent directories always already exist πŸ’…βœ¨

πŸ“¦ where this page comes from