From fec4152220753b6a2b7b4a9329b5393fe4d3e5b6 Mon Sep 17 00:00:00 2001 From: Itamar Date: Mon, 28 Sep 2020 10:09:05 +0300 Subject: [PATCH] LibCore: Add ensure_parent_directories to LibCore::File Moved the implementation in SystemServer/Service.cpp to LibCore. --- Libraries/LibCore/File.cpp | 34 +++++++++++++++++++++++++++++++ Libraries/LibCore/File.h | 1 + Services/SystemServer/Service.cpp | 28 +++---------------------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Libraries/LibCore/File.cpp b/Libraries/LibCore/File.cpp index db9edd5cca..0aa317ead2 100644 --- a/Libraries/LibCore/File.cpp +++ b/Libraries/LibCore/File.cpp @@ -27,10 +27,13 @@ #ifdef __serenity__ # include #endif +#include #include #include #include +#include #include +#include #include #include @@ -132,6 +135,37 @@ String File::real_path_for(const String& filename) return real_path; } +bool File::ensure_parent_directories(const String& path) +{ + ASSERT(path.starts_with("/")); + + int saved_errno = 0; + ScopeGuard restore_errno = [&saved_errno] { errno = saved_errno; }; + + char* parent_buffer = strdup(path.characters()); + ScopeGuard free_buffer = [parent_buffer] { free(parent_buffer); }; + + const char* parent = dirname(parent_buffer); + + int rc = mkdir(parent, 0755); + saved_errno = errno; + + if (rc == 0 || errno == EEXIST) + return true; + + if (errno != ENOENT) + return false; + + bool ok = ensure_parent_directories(parent); + saved_errno = errno; + if (!ok) + return false; + + rc = mkdir(parent, 0755); + saved_errno = errno; + return rc == 0; +} + #ifdef __serenity__ String File::read_link(const StringView& link_path) diff --git a/Libraries/LibCore/File.h b/Libraries/LibCore/File.h index 7e8b35a32c..3fdbc04496 100644 --- a/Libraries/LibCore/File.h +++ b/Libraries/LibCore/File.h @@ -48,6 +48,7 @@ public: static bool exists(const String& filename); static String real_path_for(const String& filename); static String read_link(const StringView& link_path); + static bool ensure_parent_directories(const String& path); virtual bool open(IODevice::OpenMode) override; diff --git a/Services/SystemServer/Service.cpp b/Services/SystemServer/Service.cpp index f581c0c83d..acc06062a3 100644 --- a/Services/SystemServer/Service.cpp +++ b/Services/SystemServer/Service.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -84,36 +85,13 @@ Service* Service::find_by_pid(pid_t pid) return (*it).value; } -static int ensure_parent_directories(const char* path) -{ - ASSERT(path[0] == '/'); - - char* parent_buffer = strdup(path); - const char* parent = dirname(parent_buffer); - - int rc = 0; - while (true) { - int rc = mkdir(parent, 0755); - - if (rc == 0) - break; - - if (errno != ENOENT) - break; - - ensure_parent_directories(parent); - }; - - free(parent_buffer); - return rc; -} - void Service::setup_socket() { ASSERT(!m_socket_path.is_null()); ASSERT(m_socket_fd == -1); - ensure_parent_directories(m_socket_path.characters()); + auto ok = Core::File::ensure_parent_directories(m_socket_path); + ASSERT(ok); // Note: we use SOCK_CLOEXEC here to make sure we don't leak every socket to // all the clients. We'll make the one we do need to pass down !CLOEXEC later