1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:07:34 +00:00

LibCore: Make copying permissions, ownership and timestamps combineable

This commit is contained in:
Tim Schumacher 2022-07-12 23:28:10 +02:00 committed by Linus Groh
parent a85b728768
commit 69e0b8dbb7
3 changed files with 19 additions and 6 deletions

View file

@ -408,16 +408,18 @@ ErrorOr<void, File::CopyError> File::copy_file(String const& dst_path, struct st
auto my_umask = umask(0); auto my_umask = umask(0);
umask(my_umask); umask(my_umask);
// NOTE: We don't copy the set-uid and set-gid bits unless requested. // NOTE: We don't copy the set-uid and set-gid bits unless requested.
if (preserve_mode != PreserveMode::PermissionsOwnershipTimestamps) if (!has_flag(preserve_mode, PreserveMode::Permissions))
my_umask |= 06000; my_umask |= 06000;
if (fchmod(dst_fd, src_stat.st_mode & ~my_umask) < 0) if (fchmod(dst_fd, src_stat.st_mode & ~my_umask) < 0)
return CopyError { errno, false }; return CopyError { errno, false };
if (preserve_mode == PreserveMode::PermissionsOwnershipTimestamps) { if (has_flag(preserve_mode, PreserveMode::Ownership)) {
if (fchown(dst_fd, src_stat.st_uid, src_stat.st_gid) < 0) if (fchown(dst_fd, src_stat.st_uid, src_stat.st_gid) < 0)
return CopyError { errno, false }; return CopyError { errno, false };
}
if (has_flag(preserve_mode, PreserveMode::Timestamps)) {
// FIXME: Implement utimens() and use it here. // FIXME: Implement utimens() and use it here.
struct utimbuf timbuf; struct utimbuf timbuf;
timbuf.actime = src_stat.st_atime; timbuf.actime = src_stat.st_atime;
@ -462,10 +464,12 @@ ErrorOr<void, File::CopyError> File::copy_directory(String const& dst_path, Stri
if (chmod(dst_path.characters(), src_stat.st_mode & ~my_umask) < 0) if (chmod(dst_path.characters(), src_stat.st_mode & ~my_umask) < 0)
return CopyError { errno, false }; return CopyError { errno, false };
if (preserve_mode == PreserveMode::PermissionsOwnershipTimestamps) { if (has_flag(preserve_mode, PreserveMode::Ownership)) {
if (chown(dst_path.characters(), src_stat.st_uid, src_stat.st_gid) < 0) if (chown(dst_path.characters(), src_stat.st_uid, src_stat.st_gid) < 0)
return CopyError { errno, false }; return CopyError { errno, false };
}
if (has_flag(preserve_mode, PreserveMode::Timestamps)) {
// FIXME: Implement utimens() and use it here. // FIXME: Implement utimens() and use it here.
struct utimbuf timbuf; struct utimbuf timbuf;
timbuf.actime = src_stat.st_atime; timbuf.actime = src_stat.st_atime;

View file

@ -56,8 +56,10 @@ public:
}; };
enum class PreserveMode { enum class PreserveMode {
Nothing, Nothing = 0,
PermissionsOwnershipTimestamps, Permissions = (1 << 0),
Ownership = (1 << 1),
Timestamps = (1 << 2),
}; };
struct CopyError : public Error { struct CopyError : public Error {
@ -113,4 +115,6 @@ private:
ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes }; ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes };
}; };
AK_ENUM_BITWISE_OPERATORS(File::PreserveMode);
} }

View file

@ -41,6 +41,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
bool destination_is_existing_dir = Core::File::is_directory(destination); bool destination_is_existing_dir = Core::File::is_directory(destination);
auto preserve_mode = Core::File::PreserveMode::Nothing;
if (preserve)
preserve_mode = Core::File::PreserveMode::Permissions | Core::File::PreserveMode::Ownership | Core::File::PreserveMode::Timestamps;
for (auto& source : sources) { for (auto& source : sources) {
auto destination_path = destination_is_existing_dir auto destination_path = destination_is_existing_dir
? String::formatted("{}/{}", destination, LexicalPath::basename(source)) ? String::formatted("{}/{}", destination, LexicalPath::basename(source))
@ -51,7 +56,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
recursion_allowed ? Core::File::RecursionMode::Allowed : Core::File::RecursionMode::Disallowed, recursion_allowed ? Core::File::RecursionMode::Allowed : Core::File::RecursionMode::Disallowed,
link ? Core::File::LinkMode::Allowed : Core::File::LinkMode::Disallowed, link ? Core::File::LinkMode::Allowed : Core::File::LinkMode::Disallowed,
Core::File::AddDuplicateFileMarker::No, Core::File::AddDuplicateFileMarker::No,
preserve ? Core::File::PreserveMode::PermissionsOwnershipTimestamps : Core::File::PreserveMode::Nothing); preserve_mode);
if (result.is_error()) { if (result.is_error()) {
if (result.error().tried_recursing) if (result.error().tried_recursing)