Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 060b74ba authored by Tom Cherry's avatar Tom Cherry
Browse files

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
parent 780a71e7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -148,8 +148,9 @@ LOCAL_SRC_FILES := \
    util_test.cpp \

LOCAL_SHARED_LIBRARIES += \
    libcutils \
    libbase \
    libcutils \
    libselinux \

LOCAL_STATIC_LIBRARIES := libinit
LOCAL_SANITIZE := integer
+10 −29
Original line number Diff line number Diff line
@@ -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;
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;

    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;
        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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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)>&);
+36 −0
Original line number Diff line number Diff line
@@ -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()));
}