Home > OS >  How to perform chmod recursively?
How to perform chmod recursively?

Time:02-24

How can I change permissions to 0777, at runtime, of a folder and all its subfolders, recursively?

The code is in c , mac. I'm including <sys/stat.h> which has chmod, however there's no documentation on how to do it recursively.

CodePudding user response:

The simplest and most portable way would be to use the std::filesystem library that was added in C 17. In there, you'll find a recursive_directory_iterator and many other handy classes and functions for dealing with filesystem specific things.

Example:

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

void chmodr(const fs::path& path, fs::perms perm) {
    fs::permissions(path, perm);      // set permissions on the top directory
    for(auto& de : fs::recursive_directory_iterator(path)) {
        fs::permissions(de, perm);    // set permissions
        std::cout << de << '\n';      // debug print
    }
}

int main() {
    chmodr("your_top_directory", fs::perms::all); // perms::all = 0777
}

However, recursive_directory_iterator has an issue when there are too many directories involved. It may run out of file descriptors because it needs to keep many directories open. For that reason, I prefer to use a directory_iterator instead - and collect the subdirectories to examine for later.

Example:

#include <filesystem>
#include <iostream>
#include <vector>

namespace fs = std::filesystem;

void chmodr(const fs::path& path, fs::perms perm) {
    std::vector<fs::path> subdirs;

    fs::permissions(path, perm);

    for(auto& de : fs::directory_iterator(path)) {
        // save subdirectories for later:
        if(fs::is_directory(de)) subdirs.push_back(de);
        else fs::permissions(de, perm);
    }

    // now go through the subdirectories:
    for(auto& sd : subdirs) {
        chmodr(sd, perm);
    }
}

int main() {
    chmodr("your_top_directory", fs::perms::all);
}

You can read about the std::filesystem:: (fs:: in the code above) functions, classes and permission enums used in the example in the link I provided at the top.

In some implementations, with only partial C 17 support, you may find filesystem in experimental/filesystem instead. If that's the case, you can replace the above

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

with the #ifdef jungle I've provided in this answer.

  • Related