summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-04-24 21:57:16 -0700
committerElliott Hughes <enh@google.com>2015-04-24 21:57:16 -0700
commit56085edbf8c74a3a123f08e44be6e8f294deb465 (patch)
treee90f3ed376df21fc248a65ed76c6b58852b83477 /base
parentdf5d4482074fc68a25a6a33992f3fc5164c2d3ec (diff)
Add ReadFully and WriteFully to libbase.
Change-Id: I6b7aa2a93398e7acdd1d74c71d9abed08a72b3c4
Diffstat (limited to 'base')
-rw-r--r--base/file.cpp24
-rw-r--r--base/file_test.cpp25
-rw-r--r--base/include/base/file.h3
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