mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibCore: Use ErrorOr<T> for Core::File::copy_file()
This commit is contained in:
parent
c7e62d448c
commit
4a2b718ba2
Notes:
sideshowbarker
2024-07-18 01:24:00 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/4a2b718ba2f
8 changed files with 37 additions and 32 deletions
|
@ -1169,7 +1169,7 @@ int run_in_windowed_mode(String initial_location, String entry_focused_on_init)
|
|||
continue;
|
||||
|
||||
if (auto result = Core::File::copy_file_or_directory(url_to_copy.path(), new_path); result.is_error()) {
|
||||
auto error_message = String::formatted("Could not copy {} into {}:\n {}", url_to_copy.to_string(), new_path, result.error().error_code);
|
||||
auto error_message = String::formatted("Could not copy {} into {}:\n {}", url_to_copy.to_string(), new_path, static_cast<Error const&>(result.error()));
|
||||
GUI::MessageBox::show(window, error_message, "File Manager", GUI::MessageBox::Type::Error);
|
||||
} else {
|
||||
had_accepted_copy = true;
|
||||
|
|
|
@ -231,7 +231,7 @@ Result<void, String> CSVExportDialogPage::move_into(const String& target)
|
|||
Core::File::AddDuplicateFileMarker::No);
|
||||
|
||||
if (result.is_error())
|
||||
return String { result.error().error_code.string() };
|
||||
return String::formatted("{}", static_cast<Error const&>(result.error()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ Result<void, String> ProjectTemplate::create_project(const String& name, const S
|
|||
auto result = Core::File::copy_file_or_directory(path, content_path());
|
||||
dbgln("Copying {} -> {}", content_path(), path);
|
||||
if (result.is_error())
|
||||
return String::formatted("Failed to copy template contents. Error code: {}", result.error().error_code);
|
||||
return String::formatted("Failed to copy template contents. Error code: {}", static_cast<Error const&>(result.error()));
|
||||
} else {
|
||||
dbgln("No template content directory found for '{}', creating an empty directory for the project.", m_id);
|
||||
int rc;
|
||||
|
|
|
@ -347,7 +347,7 @@ static String get_duplicate_name(String const& path, int duplicate_count)
|
|||
return duplicated_name.build();
|
||||
}
|
||||
|
||||
Result<void, File::CopyError> File::copy_file_or_directory(String const& dst_path, String const& src_path, RecursionMode recursion_mode, LinkMode link_mode, AddDuplicateFileMarker add_duplicate_file_marker, PreserveMode preserve_mode)
|
||||
ErrorOr<void, File::CopyError> File::copy_file_or_directory(String const& dst_path, String const& src_path, RecursionMode recursion_mode, LinkMode link_mode, AddDuplicateFileMarker add_duplicate_file_marker, PreserveMode preserve_mode)
|
||||
{
|
||||
if (add_duplicate_file_marker == AddDuplicateFileMarker::Yes) {
|
||||
int duplicate_count = 0;
|
||||
|
@ -361,23 +361,23 @@ Result<void, File::CopyError> File::copy_file_or_directory(String const& dst_pat
|
|||
|
||||
auto source_or_error = File::open(src_path, OpenMode::ReadOnly);
|
||||
if (source_or_error.is_error())
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
auto& source = *source_or_error.value();
|
||||
|
||||
struct stat src_stat;
|
||||
if (fstat(source.fd(), &src_stat) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
if (source.is_directory()) {
|
||||
if (recursion_mode == RecursionMode::Disallowed)
|
||||
return CopyError { OSError(errno), true };
|
||||
return CopyError { errno, true };
|
||||
return copy_directory(dst_path, src_path, src_stat);
|
||||
}
|
||||
|
||||
if (link_mode == LinkMode::Allowed) {
|
||||
if (link(src_path.characters(), dst_path.characters()) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -385,31 +385,31 @@ Result<void, File::CopyError> File::copy_file_or_directory(String const& dst_pat
|
|||
return copy_file(dst_path, src_stat, source, preserve_mode);
|
||||
}
|
||||
|
||||
Result<void, File::CopyError> File::copy_file(String const& dst_path, struct stat const& src_stat, File& source, PreserveMode preserve_mode)
|
||||
ErrorOr<void, File::CopyError> File::copy_file(String const& dst_path, struct stat const& src_stat, File& source, PreserveMode preserve_mode)
|
||||
{
|
||||
int dst_fd = creat(dst_path.characters(), 0666);
|
||||
if (dst_fd < 0) {
|
||||
if (errno != EISDIR)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
auto dst_dir_path = String::formatted("{}/{}", dst_path, LexicalPath::basename(source.filename()));
|
||||
dst_fd = creat(dst_dir_path.characters(), 0666);
|
||||
if (dst_fd < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
}
|
||||
|
||||
ScopeGuard close_fd_guard([dst_fd]() { ::close(dst_fd); });
|
||||
|
||||
if (src_stat.st_size > 0) {
|
||||
if (ftruncate(dst_fd, src_stat.st_size) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
char buffer[32768];
|
||||
ssize_t nread = ::read(source.fd(), buffer, sizeof(buffer));
|
||||
if (nread < 0) {
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
}
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
@ -418,7 +418,7 @@ Result<void, File::CopyError> File::copy_file(String const& dst_path, struct sta
|
|||
while (remaining_to_write) {
|
||||
ssize_t nwritten = ::write(dst_fd, bufptr, remaining_to_write);
|
||||
if (nwritten < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
VERIFY(nwritten > 0);
|
||||
remaining_to_write -= nwritten;
|
||||
|
@ -433,27 +433,27 @@ Result<void, File::CopyError> File::copy_file(String const& dst_path, struct sta
|
|||
my_umask |= 06000;
|
||||
|
||||
if (fchmod(dst_fd, src_stat.st_mode & ~my_umask) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
if (preserve_mode == PreserveMode::PermissionsOwnershipTimestamps) {
|
||||
if (fchown(dst_fd, src_stat.st_uid, src_stat.st_gid) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
// FIXME: Implement utimens() and use it here.
|
||||
struct utimbuf timbuf;
|
||||
timbuf.actime = src_stat.st_atime;
|
||||
timbuf.modtime = src_stat.st_mtime;
|
||||
if (utime(dst_path.characters(), &timbuf) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void, File::CopyError> File::copy_directory(String const& dst_path, String const& src_path, struct stat const& src_stat, LinkMode link, PreserveMode preserve_mode)
|
||||
ErrorOr<void, File::CopyError> File::copy_directory(String const& dst_path, String const& src_path, struct stat const& src_stat, LinkMode link, PreserveMode preserve_mode)
|
||||
{
|
||||
if (mkdir(dst_path.characters(), 0755) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
String src_rp = File::real_path_for(src_path);
|
||||
src_rp = String::formatted("{}/", src_rp);
|
||||
|
@ -461,11 +461,11 @@ Result<void, File::CopyError> File::copy_directory(String const& dst_path, Strin
|
|||
dst_rp = String::formatted("{}/", dst_rp);
|
||||
|
||||
if (!dst_rp.is_empty() && dst_rp.starts_with(src_rp))
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
DirIterator di(src_path, DirIterator::SkipDots);
|
||||
if (di.has_error())
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
while (di.has_next()) {
|
||||
String filename = di.next_path();
|
||||
|
@ -481,18 +481,18 @@ Result<void, File::CopyError> File::copy_directory(String const& dst_path, Strin
|
|||
umask(my_umask);
|
||||
|
||||
if (chmod(dst_path.characters(), src_stat.st_mode & ~my_umask) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
if (preserve_mode == PreserveMode::PermissionsOwnershipTimestamps) {
|
||||
if (chown(dst_path.characters(), src_stat.st_uid, src_stat.st_gid) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
|
||||
// FIXME: Implement utimens() and use it here.
|
||||
struct utimbuf timbuf;
|
||||
timbuf.actime = src_stat.st_atime;
|
||||
timbuf.modtime = src_stat.st_atime;
|
||||
if (utime(dst_path.characters(), &timbuf) < 0)
|
||||
return CopyError { OSError(errno), false };
|
||||
return CopyError { errno, false };
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/OSError.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
|
@ -59,14 +60,18 @@ public:
|
|||
PermissionsOwnershipTimestamps,
|
||||
};
|
||||
|
||||
struct CopyError {
|
||||
OSError error_code;
|
||||
struct CopyError : public Error {
|
||||
CopyError(int error_code, bool t)
|
||||
: Error(error_code)
|
||||
, tried_recursing(t)
|
||||
{
|
||||
}
|
||||
bool tried_recursing;
|
||||
};
|
||||
|
||||
static Result<void, CopyError> copy_file(String const& dst_path, struct stat const& src_stat, File& source, PreserveMode = PreserveMode::Nothing);
|
||||
static Result<void, CopyError> copy_directory(String const& dst_path, String const& src_path, struct stat const& src_stat, LinkMode = LinkMode::Disallowed, PreserveMode = PreserveMode::Nothing);
|
||||
static Result<void, CopyError> copy_file_or_directory(String const& dst_path, String const& src_path, RecursionMode = RecursionMode::Allowed, LinkMode = LinkMode::Disallowed, AddDuplicateFileMarker = AddDuplicateFileMarker::Yes, PreserveMode = PreserveMode::Nothing);
|
||||
static ErrorOr<void, CopyError> copy_file(String const& dst_path, struct stat const& src_stat, File& source, PreserveMode = PreserveMode::Nothing);
|
||||
static ErrorOr<void, CopyError> copy_directory(String const& dst_path, String const& src_path, struct stat const& src_stat, LinkMode = LinkMode::Disallowed, PreserveMode = PreserveMode::Nothing);
|
||||
static ErrorOr<void, CopyError> copy_file_or_directory(String const& dst_path, String const& src_path, RecursionMode = RecursionMode::Allowed, LinkMode = LinkMode::Disallowed, AddDuplicateFileMarker = AddDuplicateFileMarker::Yes, PreserveMode = PreserveMode::Nothing);
|
||||
|
||||
static String real_path_for(String const& filename);
|
||||
static String read_link(String const& link_path);
|
||||
|
|
|
@ -61,7 +61,7 @@ int main(int argc, char** argv)
|
|||
if (result.error().tried_recursing)
|
||||
warnln("cp: -R not specified; omitting directory '{}'", source);
|
||||
else
|
||||
warnln("cp: unable to copy '{}' to '{}': {}", source, destination_path, result.error().error_code);
|
||||
warnln("cp: unable to copy '{}' to '{}': {}", source, destination_path, static_cast<Error const&>(result.error()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ int main(int argc, char** argv)
|
|||
Core::File::AddDuplicateFileMarker::No);
|
||||
|
||||
if (result.is_error()) {
|
||||
warnln("mv: could not move '{}': {}", old_path, result.error().error_code);
|
||||
warnln("mv: could not move '{}': {}", old_path, static_cast<Error const&>(result.error()));
|
||||
return 1;
|
||||
}
|
||||
rc = unlink(old_path);
|
||||
|
|
|
@ -125,7 +125,7 @@ int main(int argc, char** argv)
|
|||
Core::File::AddDuplicateFileMarker::No);
|
||||
|
||||
if (result.is_error()) {
|
||||
warnln("usermod: could not move directory {} : {}", target_account.home_directory().characters(), result.error().error_code);
|
||||
warnln("usermod: could not move directory {} : {}", target_account.home_directory().characters(), static_cast<Error const&>(result.error()));
|
||||
return 1;
|
||||
}
|
||||
rc = unlink(target_account.home_directory().characters());
|
||||
|
|
Loading…
Reference in a new issue