Reputation: 24707
In my C++ program, I want to make sure i can write info to a file. How can I perform this check?
Upvotes: 1
Views: 2211
Reputation: 29
There could be different file rights POSIX, ACL, RBAC etc. Only POSIX rights are standard
There simplest way to check is to open file for writing in append mode:
std::ofstream file(filePath, std::ios::app);
if (!file.is_open()) {
std::cerr << "File cannot be opened for writing." << std::endl;
return false;
}
Manually check file permissions even for POSIX rights is a bad idea, because it leads to tremendous code. Under UNIX you have to process three triads: -rw-rw-r-x
Current process has user (uid) and group (groupId) rights. User could be in a set of groups - see UNIX "id" command. So the most tricky part is to check group rights of the file agains all possible groups. Let file is a regular file and not a symlink
First part: user itself has rights to write the file
struct stat fileStat;
stat(filePath.c_str(), &fileStat);
// User is the same as the owner of the file
if (fileStat.st_uid == getuid()) {
if ((std::filesystem::status(filePath).permissions() & std::filesystem::perms::owner_write) !=
std::filesystem::perms::none) {
return true;
}
}
Second part: one of groups user belongs to has ability to write
// Get groups list
std::vector<gid_t> groups;
int ngroups = 0;
uint result = getgrouplist(username.c_str(), groupId, nullptr, &ngroups);
groups.resize(ngroups);
result = getgrouplist(username.c_str(), groupId, groups.data(), &ngroups);
// Check all groups
for (uint i = 0; i < ngroups; ++i) {
if (groups[i] == fileStat.st_gid) {
// User belongs to a group that is equal to file group
if ((std::filesystem::status(filePath).permissions() & std::filesystem::perms::group_write) !=
std::filesystem::perms::none) {
return true;
}
}
}
Third part: check others permissions
if ((std::filesystem::status().permissions() & std::filesystem::perms::others_write) !=
std::filesystem::perms::none) {
return true;
}
Upvotes: 1
Reputation:
The only sure way to find if you can write to a file is to try to write to a file. It is possible, and even likely in some circumstances, that a file will have its permissions changed between calls to function such as stat and the actual write. Your code must deal with write failures anyway, so it makes sense to centralise the testing code there.
Upvotes: 4
Reputation: 19965
You use the stat() system call, which the purists will tell you doesn't exist unless you change the tags on your question.
Upvotes: 2