ueventd: convert mkdir_recursive() to std::string

Bug: 36250207

Test: Boot bullhead
Test: Boot sailfish, observe no boot time regression
Test: init unit tests

Change-Id: I5a2ac369d846e044230b709fd07eb21ad12d47bb
This commit is contained in:
Tom Cherry 2017-04-12 14:27:51 -07:00
parent 780a71e779
commit 060b74baad
4 changed files with 49 additions and 31 deletions

View File

@ -148,8 +148,9 @@ LOCAL_SRC_FILES := \
util_test.cpp \
LOCAL_SHARED_LIBRARIES += \
libcutils \
libbase \
libcutils \
libselinux \
LOCAL_STATIC_LIBRARIES := libinit
LOCAL_SANITIZE := integer

View File

@ -194,37 +194,18 @@ bool write_file(const std::string& path, const std::string& content) {
return success;
}
int mkdir_recursive(const char *pathname, mode_t mode)
{
char buf[128];
const char *slash;
const char *p = pathname;
int width;
int ret;
struct stat info;
while ((slash = strchr(p, '/')) != NULL) {
width = slash - pathname;
p = slash + 1;
if (width < 0)
break;
if (width == 0)
continue;
if ((unsigned int)width > sizeof(buf) - 1) {
LOG(ERROR) << "path too long for mkdir_recursive";
return -1;
}
memcpy(buf, pathname, width);
buf[width] = 0;
if (stat(buf, &info) != 0) {
ret = make_dir(buf, mode);
if (ret && errno != EEXIST)
return ret;
int mkdir_recursive(const std::string& path, mode_t mode) {
std::string::size_type slash = 0;
while ((slash = path.find('/', slash + 1)) != std::string::npos) {
auto directory = path.substr(0, slash);
struct stat info;
if (stat(directory.c_str(), &info) != 0) {
auto ret = make_dir(directory.c_str(), mode);
if (ret && errno != EEXIST) return ret;
}
}
ret = make_dir(pathname, mode);
if (ret && errno != EEXIST)
return ret;
auto ret = make_dir(path.c_str(), mode);
if (ret && errno != EEXIST) return ret;
return 0;
}

View File

@ -60,7 +60,7 @@ std::ostream& operator<<(std::ostream& os, const Timer& t);
unsigned int decode_uid(const char *s);
int mkdir_recursive(const char *pathname, mode_t mode);
int mkdir_recursive(const std::string& pathname, mode_t mode);
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
void import_kernel_cmdline(bool in_qemu,
const std::function<void(const std::string&, const std::string&, bool)>&);

View File

@ -120,3 +120,39 @@ TEST(util, decode_uid) {
EXPECT_EQ(UINT_MAX, decode_uid("toot"));
EXPECT_EQ(123U, decode_uid("123"));
}
TEST(util, is_dir) {
TemporaryDir test_dir;
EXPECT_TRUE(is_dir(test_dir.path));
TemporaryFile tf;
EXPECT_FALSE(is_dir(tf.path));
}
// sehandle is needed for make_dir()
// TODO: Remove once sehandle is encapsulated
#include <selinux/label.h>
selabel_handle* sehandle;
TEST(util, mkdir_recursive) {
TemporaryDir test_dir;
std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
EXPECT_EQ(0, mkdir_recursive(path, 0755));
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
}
TEST(util, mkdir_recursive_extra_slashes) {
TemporaryDir test_dir;
std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path);
EXPECT_EQ(0, mkdir_recursive(path, 0755));
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
}