diff options
Diffstat (limited to 'base/file_util_linux.cc')
-rw-r--r-- | base/file_util_linux.cc | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/base/file_util_linux.cc b/base/file_util_linux.cc index bfcc816..8c1a780 100644 --- a/base/file_util_linux.cc +++ b/base/file_util_linux.cc @@ -4,7 +4,10 @@ #include "base/file_util.h" +#include <fcntl.h> + #include <string> +#include <vector> #include "base/logging.h" #include "base/string_util.h" @@ -23,9 +26,49 @@ bool GetTempDir(std::wstring* path) { } bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) { - // TODO(erikkay): implement - NOTIMPLEMENTED(); - return false; + int infile = open(WideToUTF8(from_path).c_str(), O_RDONLY); + if (infile < 0) + return false; + + int outfile = creat(WideToUTF8(to_path).c_str(), 0666); + if (outfile < 0) { + close(infile); + return false; + } + + const size_t kBufferSize = 32768; + std::vector<char> buffer(kBufferSize); + bool result = true; + + while (result) { + ssize_t bytes_read = read(infile, &buffer[0], buffer.size()); + if (bytes_read < 0) { + result = false; + break; + } + if (bytes_read == 0) + break; + // Allow for partial writes + ssize_t bytes_written_per_read = 0; + do { + ssize_t bytes_written_partial = write( + outfile, + &buffer[bytes_written_per_read], + bytes_read - bytes_written_per_read); + if (bytes_written_partial < 0) { + result = false; + break; + } + bytes_written_per_read += bytes_written_partial; + } while (bytes_written_per_read < bytes_read); + } + + if (close(infile) < 0) + result = false; + if (close(outfile) < 0) + result = false; + + return result; } } // namespace file_util |