file_util: Remove goto usages from Copy()

We can just leverage std::unique_ptr to automatically close these for us
in error cases instead of jumping to the end of the function to call
fclose on them.
This commit is contained in:
Lioncash 2018-07-21 23:04:24 -04:00 committed by zhupengfei
parent 4a3c4f5f67
commit d3a52e45e3

View file

@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <array>
#include <memory>
#include "common/assert.h" #include "common/assert.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_paths.h" #include "common/common_paths.h"
@ -273,14 +275,10 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
GetLastErrorMsg()); GetLastErrorMsg());
return false; return false;
#else #else
using CFilePointer = std::unique_ptr<FILE, decltype(&std::fclose)>;
// buffer size
#define BSIZE 1024
char buffer[BSIZE];
// Open input file // Open input file
FILE* input = fopen(srcFilename.c_str(), "rb"); CFilePointer input{fopen(srcFilename.c_str(), "rb"), std::fclose};
if (!input) { if (!input) {
LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename, LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg()); destFilename, GetLastErrorMsg());
@ -288,44 +286,36 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
} }
// open output file // open output file
FILE* output = fopen(destFilename.c_str(), "wb"); CFilePointer output{fopen(destFilename.c_str(), "wb"), std::fclose};
if (!output) { if (!output) {
fclose(input);
LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename, LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg()); destFilename, GetLastErrorMsg());
return false; return false;
} }
// copy loop // copy loop
while (!feof(input)) { std::array<char, 1024> buffer;
while (!feof(input.get())) {
// read input // read input
size_t rnum = fread(buffer, sizeof(char), BSIZE, input); size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
if (rnum != BSIZE) { if (rnum != buffer.size()) {
if (ferror(input) != 0) { if (ferror(input.get()) != 0) {
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}", LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
srcFilename, destFilename, GetLastErrorMsg()); srcFilename, destFilename, GetLastErrorMsg());
goto bail; return false;
} }
} }
// write output // write output
size_t wnum = fwrite(buffer, sizeof(char), rnum, output); size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
if (wnum != rnum) { if (wnum != rnum) {
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename, LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg()); destFilename, GetLastErrorMsg());
goto bail; return false;
} }
} }
// close files
fclose(input);
fclose(output);
return true; return true;
bail:
if (input)
fclose(input);
if (output)
fclose(output);
return false;
#endif #endif
} }