std::filesystem::rename(3)

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

🌸 NAME 🌸

std::filesystem::rename β€” literally std::filesystem::rename, bestie. That's the name, that's the vibe, we're moving or renaming filesystem objects.

This is the std::filesystem::rename(3) page from the C++ Standard Libary manual (yes, the original header spells it Libary, and we're keeping that energy πŸ’…).


✨ Synopsis ✨

Defined in header <filesystem>:

void rename( const std::filesystem::path& old_p,   (1) (since C++17)
             const std::filesystem::path& new_p );
void rename( const std::filesystem::path& old_p,

             const std::filesystem::path& new_p,   (2) (since C++17)

             std::error_code& ec ) noexcept;

Okay so what it does: it moves or renames the filesystem object identified by old_p to new_p, as if by the POSIX rename. No cap.

🫢 the non-directory file situation 🫢

If old_p is a non-directory file, then new_p must be one of these:

  • the same file as old_p or a hardlink to it: nothing is done in this case.
  • existing non-directory file: new_p is first deleted, then, without allowing other processes to observe new_p as deleted, the pathname new_p is linked to the file and old_p is unlinked from the file. Write permissions are required to both the directory that contains old_p and the directory that contains new_p.
  • non-existing file in an existing directory: the pathname new_p is linked to the file and old_p is unlinked from the file. Write permissions are required to both the directory that contains old_p and the directory that contains new_p.

πŸ¦‹ the directory situation πŸ¦‹

If old_p is a directory, then new_p must be one of these:

  • the same directory as old_p or a hardlink to it: nothing is done in this case.
  • existing directory: new_p is deleted if empty on POSIX systems, but this may be an error on other systems. If not an error, then new_p is first deleted, then, without allowing other processes to observe new_p as deleted, the pathname new_p is linked to the directory and old_p is unlinked from the directory. Write permissions are required to both the directory that contains old_p and the directory that contains new_p.
  • non-existing directory, not ending with a directory separator, and whose parent directory exists: the pathname new_p is linked to the directory and old_p is unlinked from the directory. Write permissions are required to both the directory that contains old_p and the directory that contains new_p.

Symlinks are not followed: if old_p is a symlink, it is itself renamed, not its target. If new_p is an existing symlink, it is itself erased, not its target.

πŸ’€ rename fails if πŸ’€

  • new_p ends with dot or with dot-dot.
  • new_p names a non-existing directory ending with a directory separator.
  • old_p is a directory which is an ancestor of new_p.

🫢 Parameters 🫢

  • old_p β€” path to move or rename
  • new_p β€” target path for the move/rename operation
  • ec β€” out-parameter for error reporting in the non-throwing overload

πŸ’– Return value πŸ’–

(none)

That's it. That's the return value. It said what it said πŸ’….


😭 Exceptions 😭

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

  1. Throws std::filesystem::filesystem_error on underlying OS API errors, constructed with old_p as the first path argument, new_p as the second path argument, and the OS error code as the error code argument.
  2. 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.

🧚 Example 🧚

// Run this code β€” yep, that's literally the cue in the original:

        #include <filesystem>
        #include <fstream>
        namespace fs = std::filesystem;

        int main()
        {
            std::filesystem::path p = std::filesystem::current_path() /
       "sandbox";
            std::filesystem::create_directories(p / "from");
            std::ofstream{ p / "from/file1.txt" }.put('a');
            std::filesystem::create_directory(p / "to");

        //  fs::rename(p / "from/file1.txt", p / "to/"); // error: "to" is a
       directory
            fs::rename(p / "from/file1.txt", p / "to/file2.txt"); // OK
        //  fs::rename(p / "from", p / "to"); // error: "to" is not empty
            fs::rename(p / "from", p / "to/subdir"); // OK

            std::filesystem::remove_all(p);
        }

πŸ‘‘ See also πŸ‘‘

  • rename β€” renames a file (function)
  • remove β€” removes a file or empty directory
  • remove_all β€” removes a file or directory and all its contents, recursively

And the leftover tags in that same see-also block are literally (C++17), (function), (C++17) β€” not hiding them from you, bestie 🫢.


okay that's the whole page, periodt πŸ’… source/version/date energy at the very end: http://cppreference.com, 2024.06.10, std::filesystem::rename(3). mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from