1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-18 01:45:07 +00:00

FileManager: Don't close() twice when copying a file

This commit is contained in:
Andreas Kling 2020-08-17 11:30:30 +02:00
parent 0fecdb7904
commit a27d782dd6
2 changed files with 14 additions and 15 deletions

View file

@ -29,6 +29,7 @@
#include <AK/ScopeGuard.h> #include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <LibCore/DirIterator.h> #include <LibCore/DirIterator.h>
#include <LibCore/File.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -82,23 +83,21 @@ bool copy_file_or_directory(const String& src_path, const String& dst_path)
return copy_file_or_directory(src_path, get_duplicate_name(dst_path, duplicate_count)); return copy_file_or_directory(src_path, get_duplicate_name(dst_path, duplicate_count));
} }
int src_fd = open(src_path.characters(), O_RDONLY); auto source_or_error = Core::File::open(src_path, Core::IODevice::ReadOnly);
if (src_fd < 0) { if (source_or_error.is_error())
return false; return false;
}
ScopeGuard close_fd_guard([src_fd]() { close(src_fd); }); auto& source = *source_or_error.value();
struct stat src_stat; struct stat src_stat;
int rc = fstat(src_fd, &src_stat); int rc = fstat(source.fd(), &src_stat);
if (rc < 0) { if (rc < 0)
return false; return false;
}
if (S_ISDIR(src_stat.st_mode)) { if (source.is_directory())
return copy_directory(src_path, dst_path, src_stat); return copy_directory(src_path, dst_path, src_stat);
}
return copy_file(src_path, dst_path, src_stat, src_fd); return copy_file(dst_path, src_stat, source);
} }
bool copy_directory(const String& src_path, const String& dst_path, const struct stat& src_stat) bool copy_directory(const String& src_path, const String& dst_path, const struct stat& src_stat)
@ -130,14 +129,14 @@ bool copy_directory(const String& src_path, const String& dst_path, const struct
return true; return true;
} }
bool copy_file(const String& src_path, const String& dst_path, const struct stat& src_stat, int src_fd) bool copy_file(const String& dst_path, const struct stat& src_stat, Core::File& source)
{ {
int dst_fd = creat(dst_path.characters(), 0666); int dst_fd = creat(dst_path.characters(), 0666);
if (dst_fd < 0) { if (dst_fd < 0) {
if (errno != EISDIR) { if (errno != EISDIR) {
return false; return false;
} }
auto dst_dir_path = String::format("%s/%s", dst_path.characters(), LexicalPath(src_path).basename().characters()); auto dst_dir_path = String::format("%s/%s", dst_path.characters(), LexicalPath(source.filename()).basename().characters());
dst_fd = creat(dst_dir_path.characters(), 0666); dst_fd = creat(dst_dir_path.characters(), 0666);
if (dst_fd < 0) { if (dst_fd < 0) {
return false; return false;
@ -155,7 +154,7 @@ bool copy_file(const String& src_path, const String& dst_path, const struct stat
for (;;) { for (;;) {
char buffer[32768]; char buffer[32768];
ssize_t nread = read(src_fd, buffer, sizeof(buffer)); ssize_t nread = read(source.fd(), buffer, sizeof(buffer));
if (nread < 0) { if (nread < 0) {
return false; return false;
} }
@ -181,7 +180,6 @@ bool copy_file(const String& src_path, const String& dst_path, const struct stat
return false; return false;
} }
close(src_fd);
return true; return true;
} }

View file

@ -27,6 +27,7 @@
#pragma once #pragma once
#include <AK/String.h> #include <AK/String.h>
#include <LibCore/Forward.h>
#include <sys/stat.h> #include <sys/stat.h>
namespace FileUtils { namespace FileUtils {
@ -34,7 +35,7 @@ namespace FileUtils {
int delete_directory(String directory, String& file_that_caused_error); int delete_directory(String directory, String& file_that_caused_error);
bool copy_file_or_directory(const String& src_path, const String& dst_path); bool copy_file_or_directory(const String& src_path, const String& dst_path);
String get_duplicate_name(const String& path, int duplicate_count); String get_duplicate_name(const String& path, int duplicate_count);
bool copy_file(const String& src_path, const String& dst_path, const struct stat& src_stat, int src_fd); bool copy_file(const String& dst_path, const struct stat& src_stat, Core::File&);
bool copy_directory(const String& src_path, const String& dst_path, const struct stat& src_stat); bool copy_directory(const String& src_path, const String& dst_path, const struct stat& src_stat);
} }