Commit 891128f4 authored by loislo@chromium.org's avatar loislo@chromium.org

AppendToFile implementation.

DevTools wants to save very big files like HeapSnapshots.
It is not possible at the moment because the file can be about ~6Gb.

BUG=none
TEST=FileUtilTest.AppendToFile


Review URL: http://codereview.chromium.org/10263003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134492 0039d316-1c4b-4281-b951-d872f2087c98
parent 19bacfe4
...@@ -378,6 +378,10 @@ BASE_EXPORT int WriteFile(const FilePath& filename, const char* data, int size); ...@@ -378,6 +378,10 @@ BASE_EXPORT int WriteFile(const FilePath& filename, const char* data, int size);
// Append the data to |fd|. Does not close |fd| when done. // Append the data to |fd|. Does not close |fd| when done.
BASE_EXPORT int WriteFileDescriptor(const int fd, const char* data, int size); BASE_EXPORT int WriteFileDescriptor(const int fd, const char* data, int size);
#endif #endif
// Append the given buffer into the file. Returns the number of bytes written,
// or -1 on error.
BASE_EXPORT int AppendToFile(const FilePath& filename,
const char* data, int size);
// Gets the current working directory for the process. // Gets the current working directory for the process.
BASE_EXPORT bool GetCurrentDirectory(FilePath* path); BASE_EXPORT bool GetCurrentDirectory(FilePath* path);
......
...@@ -664,6 +664,18 @@ int WriteFileDescriptor(const int fd, const char* data, int size) { ...@@ -664,6 +664,18 @@ int WriteFileDescriptor(const int fd, const char* data, int size) {
return bytes_written_total; return bytes_written_total;
} }
int AppendToFile(const FilePath& filename, const char* data, int size) {
base::ThreadRestrictions::AssertIOAllowed();
int fd = HANDLE_EINTR(open(filename.value().c_str(), O_WRONLY | O_APPEND));
if (fd < 0)
return -1;
int bytes_written = WriteFileDescriptor(fd, data, size);
if (int ret = HANDLE_EINTR(close(fd)) < 0)
return ret;
return bytes_written;
}
// Gets the current working directory for the process. // Gets the current working directory for the process.
bool GetCurrentDirectory(FilePath* dir) { bool GetCurrentDirectory(FilePath* dir) {
// getcwd can return ENOENT, which implies it checks against the disk. // getcwd can return ENOENT, which implies it checks against the disk.
......
...@@ -1790,6 +1790,34 @@ TEST_F(FileUtilTest, FileEnumeratorTest) { ...@@ -1790,6 +1790,34 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
// (we don't care what). // (we don't care what).
} }
TEST_F(FileUtilTest, AppendToFile) {
FilePath data_dir =
temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
// Create a fresh, empty copy of this directory.
if (file_util::PathExists(data_dir)) {
ASSERT_TRUE(file_util::Delete(data_dir, true));
}
ASSERT_TRUE(file_util::CreateDirectory(data_dir));
// Create a fresh, empty copy of this directory.
if (file_util::PathExists(data_dir)) {
ASSERT_TRUE(file_util::Delete(data_dir, true));
}
ASSERT_TRUE(file_util::CreateDirectory(data_dir));
FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
std::string data("hello");
EXPECT_EQ(-1, file_util::AppendToFile(foobar, data.c_str(), data.length()));
EXPECT_EQ(static_cast<int>(data.length()),
file_util::WriteFile(foobar, data.c_str(), data.length()));
EXPECT_EQ(static_cast<int>(data.length()),
file_util::AppendToFile(foobar, data.c_str(), data.length()));
const std::wstring read_content = ReadTextFile(foobar);
EXPECT_EQ(L"hellohello", read_content);
}
TEST_F(FileUtilTest, Contains) { TEST_F(FileUtilTest, Contains) {
FilePath data_dir = FilePath data_dir =
temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
......
...@@ -722,6 +722,38 @@ int WriteFile(const FilePath& filename, const char* data, int size) { ...@@ -722,6 +722,38 @@ int WriteFile(const FilePath& filename, const char* data, int size) {
return -1; return -1;
} }
int AppendToFile(const FilePath& filename, const char* data, int size) {
base::ThreadRestrictions::AssertIOAllowed();
base::win::ScopedHandle file(CreateFile(filename.value().c_str(),
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
0,
NULL));
if (!file) {
DLOG(WARNING) << "CreateFile failed for path " << filename.value()
<< " error code=" << GetLastError();
return -1;
}
DWORD written;
BOOL result = ::WriteFile(file, data, size, &written, NULL);
if (result && static_cast<int>(written) == size)
return written;
if (!result) {
// WriteFile failed.
DLOG(WARNING) << "writing file " << filename.value()
<< " failed, error code=" << GetLastError();
} else {
// Didn't write all the bytes.
DLOG(WARNING) << "wrote" << written << " bytes to "
<< filename.value() << " expected " << size;
}
return -1;
}
// Gets the current working directory for the process. // Gets the current working directory for the process.
bool GetCurrentDirectory(FilePath* dir) { bool GetCurrentDirectory(FilePath* dir) {
base::ThreadRestrictions::AssertIOAllowed(); base::ThreadRestrictions::AssertIOAllowed();
......
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