1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-05 12:21:48 +02:00

{libutil,libstore}: Factor out chmodIfNeeded

Using std::filesystem::path directly because we need .c_str()
anyway to interact with chmod. Path/string views don't have to be
null-terminated.
This commit is contained in:
Sergei Zimmerman 2025-03-05 02:43:11 +03:00
parent c99edc840c
commit 82f337de10
4 changed files with 57 additions and 4 deletions

View file

@ -776,4 +776,18 @@ std::filesystem::path makeParentCanonical(const std::filesystem::path & rawPath)
}
}
bool chmodIfNeeded(const fs::path & path, mode_t mode, mode_t mask)
{
auto pathString = path.string();
auto prevMode = lstat(pathString).st_mode;
if (((prevMode ^ mode) & mask) == 0)
return false;
if (chmod(pathString.c_str(), mode) != 0)
throw SysError("could not set permissions on '%s' to %o", pathString, mode);
return true;
}
} // namespace nix

View file

@ -366,4 +366,20 @@ typedef std::function<bool(const Path & path)> PathFilter;
extern PathFilter defaultPathFilter;
/**
* Change permissions of a file only if necessary.
*
* @details
* Skip chmod call if the directory already has the requested permissions.
* This is to avoid failing when the executing user lacks permissions to change the
* directory's permissions even if it would be no-op.
*
* @param path Path to the file to change the permissions for.
* @param mode New file mode.
* @param mask Used for checking if the file already has requested permissions.
*
* @return true if permissions changed, false otherwise.
*/
bool chmodIfNeeded(const std::filesystem::path & path, mode_t mode, mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO);
}