summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-01-30 04:27:44 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-01-30 04:27:44 +0000
commitaef26bb1a4adb953f6bbd5a7e01ca964ed3b386d (patch)
tree4d03506e96dd70acfc3febb6607c5b39bf9aa4d1 /base
parenta9352202dd52a404199fbdca160d9d2d0992cf63 (diff)
parentb6e314aa8664b766222d676a24f6390ff1f3f2c5 (diff)
downloadcore-aef26bb1a4adb953f6bbd5a7e01ca964ed3b386d.tar.gz
core-aef26bb1a4adb953f6bbd5a7e01ca964ed3b386d.tar.bz2
core-aef26bb1a4adb953f6bbd5a7e01ca964ed3b386d.zip
Merge "base: add API to remove file if it exists."
Diffstat (limited to 'base')
-rw-r--r--base/file.cpp27
-rw-r--r--base/file_test.cpp14
-rw-r--r--base/include/android-base/file.h2
3 files changed, 43 insertions, 0 deletions
diff --git a/base/file.cpp b/base/file.cpp
index f444c0c64..bcdfc5e99 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -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
diff --git a/base/file_test.cpp b/base/file_test.cpp
index 1bf83a49f..17755bfed 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -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);
+}
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index acd29b30e..486befcbb 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -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