From 56085edbf8c74a3a123f08e44be6e8f294deb465 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 24 Apr 2015 21:57:16 -0700 Subject: Add ReadFully and WriteFully to libbase. Change-Id: I6b7aa2a93398e7acdd1d74c71d9abed08a72b3c4 --- base/file.cpp | 24 ++++++++++++++++++++++++ base/file_test.cpp | 25 +++++++++++++++++++++++++ base/include/base/file.h | 3 +++ 3 files changed, 52 insertions(+) diff --git a/base/file.cpp b/base/file.cpp index a51c5ff..6b19818 100644 --- a/base/file.cpp +++ b/base/file.cpp @@ -120,5 +120,29 @@ bool WriteStringToFile(const std::string& content, const std::string& path) { return result || CleanUpAfterFailedWrite(path); } +bool ReadFully(int fd, void* data, size_t byte_count) { + uint8_t* p = reinterpret_cast(data); + size_t remaining = byte_count; + while (remaining > 0) { + ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining)); + if (n <= 0) return false; + p += n; + remaining -= n; + } + return true; +} + +bool WriteFully(int fd, const void* data, size_t byte_count) { + const uint8_t* p = reinterpret_cast(data); + size_t remaining = byte_count; + while (remaining > 0) { + ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining)); + if (n == -1) return false; + p += n; + remaining -= n; + } + return true; +} + } // namespace base } // namespace android diff --git a/base/file_test.cpp b/base/file_test.cpp index fc48b32..e5cf696 100644 --- a/base/file_test.cpp +++ b/base/file_test.cpp @@ -79,3 +79,28 @@ TEST(file, WriteStringToFd) { ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << errno; EXPECT_EQ("abc", s); } + +TEST(file, ReadFully) { + int fd = open("/proc/version", O_RDONLY); + ASSERT_NE(-1, fd) << strerror(errno); + + char buf[1024]; + memset(buf, 0, sizeof(buf)); + ASSERT_TRUE(android::base::ReadFully(fd, buf, 5)); + ASSERT_STREQ("Linux", buf); + + ASSERT_EQ(0, lseek(fd, 0, SEEK_SET)) << strerror(errno); + + ASSERT_FALSE(android::base::ReadFully(fd, buf, sizeof(buf))); + + close(fd); +} + +TEST(file, WriteFully) { + TemporaryFile tf; + ASSERT_TRUE(tf.fd != -1); + ASSERT_TRUE(android::base::WriteFully(tf.fd, "abc", 3)); + std::string s; + ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s)) << errno; + EXPECT_EQ("abc", s); +} diff --git a/base/include/base/file.h b/base/include/base/file.h index ef97742..acd29b3 100644 --- a/base/include/base/file.h +++ b/base/include/base/file.h @@ -34,6 +34,9 @@ bool WriteStringToFile(const std::string& content, const std::string& path, mode_t mode, uid_t owner, gid_t group); #endif +bool ReadFully(int fd, void* data, size_t byte_count); +bool WriteFully(int fd, const void* data, size_t byte_count); + } // namespace base } // namespace android -- cgit v1.1