Merge "libbase: return different result depend on the errno"
This commit is contained in:
commit
40ad8e2ade
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue