diff options
author | Elliott Hughes <enh@google.com> | 2015-04-24 21:57:16 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2015-04-24 21:57:16 -0700 |
commit | 56085edbf8c74a3a123f08e44be6e8f294deb465 (patch) | |
tree | e90f3ed376df21fc248a65ed76c6b58852b83477 /base | |
parent | df5d4482074fc68a25a6a33992f3fc5164c2d3ec (diff) | |
download | core-56085edbf8c74a3a123f08e44be6e8f294deb465.tar.gz core-56085edbf8c74a3a123f08e44be6e8f294deb465.tar.bz2 core-56085edbf8c74a3a123f08e44be6e8f294deb465.zip |
Add ReadFully and WriteFully to libbase.
Change-Id: I6b7aa2a93398e7acdd1d74c71d9abed08a72b3c4
Diffstat (limited to 'base')
-rw-r--r-- | base/file.cpp | 24 | ||||
-rw-r--r-- | base/file_test.cpp | 25 | ||||
-rw-r--r-- | base/include/base/file.h | 3 |
3 files changed, 52 insertions, 0 deletions
diff --git a/base/file.cpp b/base/file.cpp index a51c5ffa8..6b19818e0 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<uint8_t*>(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<const uint8_t*>(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 fc48b32a7..e5cf696fe 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 ef977421b..acd29b30e 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 |