Loading base/file.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -149,5 +149,32 @@ bool WriteFully(int fd, const void* data, size_t byte_count) { return true; } bool RemoveFileIfExists(const std::string& path, std::string* err) { struct stat st; #if defined(_WIN32) //TODO: Windows version can't handle symbol link correctly. int result = stat(path.c_str(), &st); bool file_type_removable = (result == 0 && S_ISREG(st.st_mode)); #else int result = lstat(path.c_str(), &st); bool file_type_removable = (result == 0 && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))); #endif if (result == 0) { if (!file_type_removable) { if (err != nullptr) { *err = "is not a regular or symbol link file"; } return false; } if (unlink(path.c_str()) == -1) { if (err != nullptr) { *err = strerror(errno); } return false; } } return true; } } // namespace base } // namespace android base/file_test.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -96,3 +96,17 @@ TEST(file, WriteFully) { s.resize(1024); ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size())); } TEST(file, RemoveFileIfExist) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); close(tf.fd); tf.fd = -1; std::string err; ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err)) << err; ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path)); TemporaryDir td; ASSERT_FALSE(android::base::RemoveFileIfExists(td.path)); ASSERT_FALSE(android::base::RemoveFileIfExists(td.path, &err)); ASSERT_EQ("is not a regular or symbol link file", err); } base/include/android-base/file.h +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ bool WriteStringToFile(const std::string& content, const std::string& path, bool ReadFully(int fd, void* data, size_t byte_count); bool WriteFully(int fd, const void* data, size_t byte_count); bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr); } // namespace base } // namespace android Loading Loading
base/file.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -149,5 +149,32 @@ bool WriteFully(int fd, const void* data, size_t byte_count) { return true; } bool RemoveFileIfExists(const std::string& path, std::string* err) { struct stat st; #if defined(_WIN32) //TODO: Windows version can't handle symbol link correctly. int result = stat(path.c_str(), &st); bool file_type_removable = (result == 0 && S_ISREG(st.st_mode)); #else int result = lstat(path.c_str(), &st); bool file_type_removable = (result == 0 && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))); #endif if (result == 0) { if (!file_type_removable) { if (err != nullptr) { *err = "is not a regular or symbol link file"; } return false; } if (unlink(path.c_str()) == -1) { if (err != nullptr) { *err = strerror(errno); } return false; } } return true; } } // namespace base } // namespace android
base/file_test.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -96,3 +96,17 @@ TEST(file, WriteFully) { s.resize(1024); ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size())); } TEST(file, RemoveFileIfExist) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); close(tf.fd); tf.fd = -1; std::string err; ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err)) << err; ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path)); TemporaryDir td; ASSERT_FALSE(android::base::RemoveFileIfExists(td.path)); ASSERT_FALSE(android::base::RemoveFileIfExists(td.path, &err)); ASSERT_EQ("is not a regular or symbol link file", err); }
base/include/android-base/file.h +2 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ bool WriteStringToFile(const std::string& content, const std::string& path, bool ReadFully(int fd, void* data, size_t byte_count); bool WriteFully(int fd, const void* data, size_t byte_count); bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr); } // namespace base } // namespace android Loading