Commit 53bfc89c authored by Alexander Bolodurin's avatar Alexander Bolodurin Committed by Commit Bot

file_util: Export CopyFileContents function

This is a variant of CopyFile to use when the file paths are not
accessible, e.g. passing a file descriptor across containers.

Change-Id: I87a674b389139ced34cfc3ece11df5c2765df640
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2536652
Commit-Queue: Alexander Bolodurin <alexbn@google.com>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#831157}
parent 66971969
......@@ -49,6 +49,35 @@ bool Move(const FilePath& from_path, const FilePath& to_path) {
return internal::MoveUnsafe(from_path, to_path);
}
bool CopyFileContents(File& infile, File& outfile) {
static constexpr size_t kBufferSize = 32768;
std::vector<char> buffer(kBufferSize);
for (;;) {
int bytes_read = infile.ReadAtCurrentPos(buffer.data(), buffer.size());
if (bytes_read < 0) {
return false;
}
if (bytes_read == 0) {
return true;
}
// Allow for partial writes
int bytes_written_per_read = 0;
do {
int bytes_written_partial = outfile.WriteAtCurrentPos(
&buffer[bytes_written_per_read], bytes_read - bytes_written_per_read);
if (bytes_written_partial < 0) {
return false;
}
bytes_written_per_read += bytes_written_partial;
} while (bytes_written_per_read < bytes_read);
}
NOTREACHED();
return false;
}
bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
// We open the file in binary format even if they are text files because
// we are just comparing that bytes are exactly same in both files and not
......
......@@ -138,6 +138,12 @@ BASE_EXPORT bool ReplaceFile(const FilePath& from_path,
// read permissions. i.e. Always 0644.
BASE_EXPORT bool CopyFile(const FilePath& from_path, const FilePath& to_path);
// Copies the contents of one file into another.
// The files are taken as is: the copy is done starting from the current offset
// of |infile| until the end of |infile| is reached, into the current offset of
// |outfile|.
BASE_EXPORT bool CopyFileContents(File& infile, File& outfile);
// Copies the given path, and optionally all subdirectories and their contents
// as well.
//
......
......@@ -132,32 +132,6 @@ bool AdvanceEnumeratorWithStat(FileEnumerator* traversal,
return true;
}
bool CopyFileContents(File* infile, File* outfile) {
static constexpr size_t kBufferSize = 32768;
std::vector<char> buffer(kBufferSize);
for (;;) {
ssize_t bytes_read = infile->ReadAtCurrentPos(buffer.data(), buffer.size());
if (bytes_read < 0)
return false;
if (bytes_read == 0)
return true;
// Allow for partial writes
ssize_t bytes_written_per_read = 0;
do {
ssize_t bytes_written_partial = outfile->WriteAtCurrentPos(
&buffer[bytes_written_per_read], bytes_read - bytes_written_per_read);
if (bytes_written_partial < 0)
return false;
bytes_written_per_read += bytes_written_partial;
} while (bytes_written_per_read < bytes_read);
}
NOTREACHED();
return false;
}
bool DoCopyDirectory(const FilePath& from_path,
const FilePath& to_path,
bool recursive,
......@@ -289,7 +263,7 @@ bool DoCopyDirectory(const FilePath& from_path,
return false;
}
if (!CopyFileContents(&infile, &outfile)) {
if (!CopyFileContents(infile, outfile)) {
DLOG(ERROR) << "CopyDirectory() couldn't copy file: " << current.value();
return false;
}
......@@ -1160,7 +1134,7 @@ bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
if (!outfile.IsValid())
return false;
return CopyFileContents(&infile, &outfile);
return CopyFileContents(infile, outfile);
}
#endif // !defined(OS_APPLE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment