Issue
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.
Solution
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 <iostream>
#include <filesystem> // see notes about these two lines at the bottom
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 <iostream>
#include <stack>
#include <utility>
#include <filesystem> // see notes about these two lines at the bottom
namespace fs = std::filesystem; // -"-
void chmodr(const fs::path& path, fs::perms perm) {
std::stack<fs::path> dirs;
dirs.push(path);
fs::permissions(path, perm);
do {
auto pa = std::move(dirs.top()); // extract the top dir from the stack
dirs.pop(); // and remove it
for(auto& de : fs::directory_iterator(pa)) {
// save subdirectories for later:
if(fs::is_directory(de)) dirs.push(de);
else fs::permissions(de, perm);
}
} while(!dirs.empty()); // loop until there are no dirs left
}
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.
Answered By - Ted Lyngmo Answer Checked By - Katrina (WPSolving Volunteer)