diff options
| author | Elliott Hughes <enh@google.com> | 2018-07-13 15:02:49 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-07-13 15:02:49 +0000 |
| commit | 40ad8e2ade10aff36837140c827c7d1233138994 (patch) | |
| tree | 3fa44d4c2e33c3927bf9d0127a12db6aa0bed17f | |
| parent | a73ea65c5aa40fbd3faf05ece4de4c7acc7a8564 (diff) | |
| parent | c63cb070633864fe5424d8a2b6e44f0fd19ef08f (diff) | |
| download | system_core-40ad8e2ade10aff36837140c827c7d1233138994.tar.gz system_core-40ad8e2ade10aff36837140c827c7d1233138994.tar.bz2 system_core-40ad8e2ade10aff36837140c827c7d1233138994.zip | |
Merge "libbase: return different result depend on the errno"
| -rw-r--r-- | base/file.cpp | 10 | ||||
| -rw-r--r-- | base/file_test.cpp | 42 |
2 files changed, 48 insertions, 4 deletions
diff --git a/base/file.cpp b/base/file.cpp index 2f697a1cc..d6fe753d1 100644 --- a/base/file.cpp +++ b/base/file.cpp @@ -199,17 +199,23 @@ bool WriteFully(int fd, const void* data, size_t byte_count) { bool RemoveFileIfExists(const std::string& path, std::string* err) { struct stat st; #if defined(_WIN32) - //TODO: Windows version can't handle symbol link correctly. + // TODO: Windows version can't handle symbolic links 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 == -1) { + if (errno == ENOENT || errno == ENOTDIR) return true; + if (err != nullptr) *err = strerror(errno); + return false; + } + if (result == 0) { if (!file_type_removable) { if (err != nullptr) { - *err = "is not a regular or symbol link file"; + *err = "is not a regular file or symbolic link"; } return false; } diff --git a/base/file_test.cpp b/base/file_test.cpp index 02b431de7..67946523c 100644 --- a/base/file_test.cpp +++ b/base/file_test.cpp @@ -26,6 +26,10 @@ #include "android-base/test_utils.h" +#if !defined(_WIN32) +#include <pwd.h> +#endif + TEST(file, ReadFileToString_ENOENT) { std::string s("hello"); errno = 0; @@ -115,7 +119,7 @@ TEST(file, WriteFully) { ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size())); } -TEST(file, RemoveFileIfExist) { +TEST(file, RemoveFileIfExists) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); close(tf.fd); @@ -126,9 +130,43 @@ TEST(file, RemoveFileIfExist) { 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); + ASSERT_EQ("is not a regular file or symbolic link", err); } +TEST(file, RemoveFileIfExists_ENOTDIR) { + TemporaryFile tf; + close(tf.fd); + tf.fd = -1; + std::string err{"xxx"}; + ASSERT_TRUE(android::base::RemoveFileIfExists(std::string{tf.path} + "/abc", &err)); + ASSERT_EQ("xxx", err); +} + +#if !defined(_WIN32) +TEST(file, RemoveFileIfExists_EACCES) { + // EACCES -- one of the directories in the path has no search permission + // root can bypass permission restrictions, so drop root. + if (getuid() == 0) { + passwd* shell = getpwnam("shell"); + setgid(shell->pw_gid); + setuid(shell->pw_uid); + } + + TemporaryDir td; + TemporaryFile tf(td.path); + close(tf.fd); + tf.fd = -1; + std::string err{"xxx"}; + // Remove dir's search permission. + ASSERT_TRUE(chmod(td.path, S_IRUSR | S_IWUSR) == 0); + ASSERT_FALSE(android::base::RemoveFileIfExists(tf.path, &err)); + ASSERT_EQ("Permission denied", err); + // Set dir's search permission again. + ASSERT_TRUE(chmod(td.path, S_IRWXU) == 0); + ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err)); +} +#endif + TEST(file, Readlink) { #if !defined(_WIN32) // Linux doesn't allow empty symbolic links. |
