mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:07:45 +00:00
LibCore: Add ensure_parent_directories to LibCore::File
Moved the implementation in SystemServer/Service.cpp to LibCore.
This commit is contained in:
parent
c1fc27cab2
commit
fec4152220
3 changed files with 38 additions and 25 deletions
|
@ -27,10 +27,13 @@
|
||||||
#ifdef __serenity__
|
#ifdef __serenity__
|
||||||
# include <Kernel/API/Syscall.h>
|
# include <Kernel/API/Syscall.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <AK/ScopeGuard.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -132,6 +135,37 @@ String File::real_path_for(const String& filename)
|
||||||
return real_path;
|
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__
|
#ifdef __serenity__
|
||||||
|
|
||||||
String File::read_link(const StringView& link_path)
|
String File::read_link(const StringView& link_path)
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
static bool exists(const String& filename);
|
static bool exists(const String& filename);
|
||||||
static String real_path_for(const String& filename);
|
static String real_path_for(const String& filename);
|
||||||
static String read_link(const StringView& link_path);
|
static String read_link(const StringView& link_path);
|
||||||
|
static bool ensure_parent_directories(const String& path);
|
||||||
|
|
||||||
virtual bool open(IODevice::OpenMode) override;
|
virtual bool open(IODevice::OpenMode) override;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <AK/JsonArray.h>
|
#include <AK/JsonArray.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <LibCore/ConfigFile.h>
|
#include <LibCore/ConfigFile.h>
|
||||||
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/Socket.h>
|
#include <LibCore/Socket.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
@ -84,36 +85,13 @@ Service* Service::find_by_pid(pid_t pid)
|
||||||
return (*it).value;
|
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()
|
void Service::setup_socket()
|
||||||
{
|
{
|
||||||
ASSERT(!m_socket_path.is_null());
|
ASSERT(!m_socket_path.is_null());
|
||||||
ASSERT(m_socket_fd == -1);
|
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
|
// 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
|
// all the clients. We'll make the one we do need to pass down !CLOEXEC later
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue