mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
cp: Implement the granular --preserve
flag
This commit is contained in:
parent
69e0b8dbb7
commit
bb0feebddc
1 changed files with 34 additions and 9 deletions
|
@ -17,7 +17,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
TRY(Core::System::pledge("stdio rpath wpath cpath fattr chown"));
|
||||
|
||||
bool link = false;
|
||||
bool preserve = false;
|
||||
auto preserve = Core::File::PreserveMode::Nothing;
|
||||
bool recursion_allowed = false;
|
||||
bool verbose = false;
|
||||
Vector<StringView> sources;
|
||||
|
@ -25,7 +25,37 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(link, "Link files instead of copying", "link", 'l');
|
||||
args_parser.add_option(preserve, "Preserve time, UID/GID and file permissions", nullptr, 'p');
|
||||
args_parser.add_option({
|
||||
Core::ArgsParser::OptionArgumentMode::Optional,
|
||||
"Preserve a selection of mode, ownership and timestamps. Defaults to all three if the option is present but no list is given.",
|
||||
"preserve",
|
||||
'p',
|
||||
"attributes",
|
||||
[&preserve](char const* s) {
|
||||
if (!s) {
|
||||
preserve = Core::File::PreserveMode::Permissions | Core::File::PreserveMode::Ownership | Core::File::PreserveMode::Timestamps;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool values_ok = true;
|
||||
|
||||
StringView { s, strlen(s) }.for_each_split_view(',', false, [&](StringView value) {
|
||||
if (value == "mode"sv) {
|
||||
preserve |= Core::File::PreserveMode::Permissions;
|
||||
} else if (value == "ownership"sv) {
|
||||
preserve |= Core::File::PreserveMode::Ownership;
|
||||
} else if (value == "timestamps"sv) {
|
||||
preserve |= Core::File::PreserveMode::Timestamps;
|
||||
} else {
|
||||
warnln("cp: Unknown or unimplemented --preserve attribute: '{}'", value);
|
||||
values_ok = false;
|
||||
}
|
||||
});
|
||||
|
||||
return values_ok;
|
||||
},
|
||||
Core::ArgsParser::OptionHideMode::None,
|
||||
});
|
||||
args_parser.add_option(recursion_allowed, "Copy directories recursively", "recursive", 'R');
|
||||
args_parser.add_option(recursion_allowed, "Same as -R", nullptr, 'r');
|
||||
args_parser.add_option(verbose, "Verbose", "verbose", 'v');
|
||||
|
@ -33,7 +63,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.add_positional_argument(destination, "Destination file path", "destination");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
if (preserve) {
|
||||
if (has_flag(preserve, Core::File::PreserveMode::Permissions)) {
|
||||
umask(0);
|
||||
} else {
|
||||
TRY(Core::System::pledge("stdio rpath wpath cpath fattr"));
|
||||
|
@ -41,11 +71,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
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) {
|
||||
auto destination_path = destination_is_existing_dir
|
||||
? String::formatted("{}/{}", destination, LexicalPath::basename(source))
|
||||
|
@ -56,7 +81,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
recursion_allowed ? Core::File::RecursionMode::Allowed : Core::File::RecursionMode::Disallowed,
|
||||
link ? Core::File::LinkMode::Allowed : Core::File::LinkMode::Disallowed,
|
||||
Core::File::AddDuplicateFileMarker::No,
|
||||
preserve_mode);
|
||||
preserve);
|
||||
|
||||
if (result.is_error()) {
|
||||
if (result.error().tried_recursing)
|
||||
|
|
Loading…
Add table
Reference in a new issue