Loading base/file.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -55,10 +55,11 @@ bool ReadFdToString(int fd, std::string* content) { return (n == 0) ? true : false; } bool ReadFileToString(const std::string& path, std::string* content) { bool ReadFileToString(const std::string& path, std::string* content, bool follow_symlinks) { content->clear(); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_BINARY)); int flags = O_RDONLY | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags)); if (fd == -1) { return false; } Loading Loading @@ -91,8 +92,10 @@ static bool CleanUpAfterFailedWrite(const std::string& path) { #if !defined(_WIN32) bool WriteStringToFile(const std::string& content, const std::string& path, mode_t mode, uid_t owner, gid_t group) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY; mode_t mode, uid_t owner, gid_t group, bool follow_symlinks) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode)); if (fd == -1) { PLOG(ERROR) << "android::WriteStringToFile open failed"; Loading @@ -118,8 +121,10 @@ bool WriteStringToFile(const std::string& content, const std::string& path, } #endif bool WriteStringToFile(const std::string& content, const std::string& path) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY; bool WriteStringToFile(const std::string& content, const std::string& path, bool follow_symlinks) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, DEFFILEMODE)); if (fd == -1) { return false; Loading base/file_test.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,24 @@ TEST(file, ReadFileToString_WriteStringToFile) { EXPECT_EQ("abc", s); } // symlinks require elevated privileges on Windows. #if !defined(_WIN32) TEST(file, ReadFileToString_WriteStringToFile_symlink) { TemporaryFile target, link; ASSERT_EQ(0, unlink(link.path)); ASSERT_EQ(0, symlink(target.path, link.path)); ASSERT_FALSE(android::base::WriteStringToFile("foo", link.path, false)); ASSERT_EQ(ELOOP, errno); ASSERT_TRUE(android::base::WriteStringToFile("foo", link.path, true)); std::string s; ASSERT_FALSE(android::base::ReadFileToString(link.path, &s)); ASSERT_EQ(ELOOP, errno); ASSERT_TRUE(android::base::ReadFileToString(link.path, &s, true)); ASSERT_EQ("foo", s); } #endif // WriteStringToFile2 is explicitly for setting Unix permissions, which make no // sense on Windows. #if !defined(_WIN32) Loading base/include/android-base/file.h +6 −3 Original line number Diff line number Diff line Loading @@ -28,14 +28,17 @@ namespace android { namespace base { bool ReadFdToString(int fd, std::string* content); bool ReadFileToString(const std::string& path, std::string* content); bool ReadFileToString(const std::string& path, std::string* content, bool follow_symlinks = false); bool WriteStringToFile(const std::string& content, const std::string& path); bool WriteStringToFile(const std::string& content, const std::string& path, bool follow_symlinks = false); bool WriteStringToFd(const std::string& content, int fd); #if !defined(_WIN32) bool WriteStringToFile(const std::string& content, const std::string& path, mode_t mode, uid_t owner, gid_t group); mode_t mode, uid_t owner, gid_t group, bool follow_symlinks = false); #endif bool ReadFully(int fd, void* data, size_t byte_count); Loading Loading
base/file.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -55,10 +55,11 @@ bool ReadFdToString(int fd, std::string* content) { return (n == 0) ? true : false; } bool ReadFileToString(const std::string& path, std::string* content) { bool ReadFileToString(const std::string& path, std::string* content, bool follow_symlinks) { content->clear(); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_BINARY)); int flags = O_RDONLY | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags)); if (fd == -1) { return false; } Loading Loading @@ -91,8 +92,10 @@ static bool CleanUpAfterFailedWrite(const std::string& path) { #if !defined(_WIN32) bool WriteStringToFile(const std::string& content, const std::string& path, mode_t mode, uid_t owner, gid_t group) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY; mode_t mode, uid_t owner, gid_t group, bool follow_symlinks) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode)); if (fd == -1) { PLOG(ERROR) << "android::WriteStringToFile open failed"; Loading @@ -118,8 +121,10 @@ bool WriteStringToFile(const std::string& content, const std::string& path, } #endif bool WriteStringToFile(const std::string& content, const std::string& path) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY; bool WriteStringToFile(const std::string& content, const std::string& path, bool follow_symlinks) { int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW); int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, DEFFILEMODE)); if (fd == -1) { return false; Loading
base/file_test.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,24 @@ TEST(file, ReadFileToString_WriteStringToFile) { EXPECT_EQ("abc", s); } // symlinks require elevated privileges on Windows. #if !defined(_WIN32) TEST(file, ReadFileToString_WriteStringToFile_symlink) { TemporaryFile target, link; ASSERT_EQ(0, unlink(link.path)); ASSERT_EQ(0, symlink(target.path, link.path)); ASSERT_FALSE(android::base::WriteStringToFile("foo", link.path, false)); ASSERT_EQ(ELOOP, errno); ASSERT_TRUE(android::base::WriteStringToFile("foo", link.path, true)); std::string s; ASSERT_FALSE(android::base::ReadFileToString(link.path, &s)); ASSERT_EQ(ELOOP, errno); ASSERT_TRUE(android::base::ReadFileToString(link.path, &s, true)); ASSERT_EQ("foo", s); } #endif // WriteStringToFile2 is explicitly for setting Unix permissions, which make no // sense on Windows. #if !defined(_WIN32) Loading
base/include/android-base/file.h +6 −3 Original line number Diff line number Diff line Loading @@ -28,14 +28,17 @@ namespace android { namespace base { bool ReadFdToString(int fd, std::string* content); bool ReadFileToString(const std::string& path, std::string* content); bool ReadFileToString(const std::string& path, std::string* content, bool follow_symlinks = false); bool WriteStringToFile(const std::string& content, const std::string& path); bool WriteStringToFile(const std::string& content, const std::string& path, bool follow_symlinks = false); bool WriteStringToFd(const std::string& content, int fd); #if !defined(_WIN32) bool WriteStringToFile(const std::string& content, const std::string& path, mode_t mode, uid_t owner, gid_t group); mode_t mode, uid_t owner, gid_t group, bool follow_symlinks = false); #endif bool ReadFully(int fd, void* data, size_t byte_count); Loading