mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-03 15:16:14 +00:00
LibWebView+LibCore: Move IPCProcess into WebView::Process
Ladybird's HelperProcess.cpp was the only user of the IPCProcess class. Moving the helper class from LibCore allows for some more interesting LibIPC changes in the upcoming commits.
This commit is contained in:
committed by
Andrew Kaster
parent
e537adad77
commit
9a6eccc590
@@ -14,9 +14,6 @@
|
||||
#include <LibCore/Environment.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/Process.h>
|
||||
#include <LibCore/Socket.h>
|
||||
#include <LibCore/SocketAddress.h>
|
||||
#include <LibCore/StandardPaths.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
@@ -363,101 +360,4 @@ ErrorOr<bool> Process::wait_for_termination()
|
||||
return exited_with_code_0;
|
||||
}
|
||||
|
||||
ErrorOr<IPCProcess::ProcessAndIPCSocket> IPCProcess::spawn_and_connect_to_process(ProcessSpawnOptions const& options)
|
||||
{
|
||||
int socket_fds[2] {};
|
||||
TRY(System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));
|
||||
|
||||
ArmedScopeGuard guard_fd_0 { [&] { MUST(System::close(socket_fds[0])); } };
|
||||
ArmedScopeGuard guard_fd_1 { [&] { MUST(System::close(socket_fds[1])); } };
|
||||
|
||||
auto& file_actions = const_cast<ProcessSpawnOptions&>(options).file_actions;
|
||||
file_actions.append(FileAction::CloseFile { socket_fds[0] });
|
||||
|
||||
auto takeover_string = MUST(String::formatted("{}:{}", options.name, socket_fds[1]));
|
||||
TRY(Environment::set("SOCKET_TAKEOVER"sv, takeover_string, Environment::Overwrite::Yes));
|
||||
|
||||
auto process = TRY(Process::spawn(options));
|
||||
|
||||
auto ipc_socket = TRY(LocalSocket::adopt_fd(socket_fds[0]));
|
||||
guard_fd_0.disarm();
|
||||
TRY(ipc_socket->set_blocking(true));
|
||||
|
||||
return ProcessAndIPCSocket { move(process), move(ipc_socket) };
|
||||
}
|
||||
|
||||
ErrorOr<Optional<pid_t>> IPCProcess::get_process_pid(StringView process_name, StringView pid_path)
|
||||
{
|
||||
if (System::stat(pid_path).is_error())
|
||||
return OptionalNone {};
|
||||
|
||||
Optional<pid_t> pid;
|
||||
{
|
||||
auto pid_file = File::open(pid_path, File::OpenMode::Read);
|
||||
if (pid_file.is_error()) {
|
||||
warnln("Could not open {} PID file '{}': {}", process_name, pid_path, pid_file.error());
|
||||
return pid_file.release_error();
|
||||
}
|
||||
|
||||
auto contents = pid_file.value()->read_until_eof();
|
||||
if (contents.is_error()) {
|
||||
warnln("Could not read {} PID file '{}': {}", process_name, pid_path, contents.error());
|
||||
return contents.release_error();
|
||||
}
|
||||
|
||||
pid = StringView { contents.value() }.to_number<pid_t>();
|
||||
}
|
||||
|
||||
if (!pid.has_value()) {
|
||||
warnln("{} PID file '{}' exists, but with an invalid PID", process_name, pid_path);
|
||||
TRY(System::unlink(pid_path));
|
||||
return OptionalNone {};
|
||||
}
|
||||
if (kill(*pid, 0) < 0) {
|
||||
warnln("{} PID file '{}' exists with PID {}, but process cannot be found", process_name, pid_path, *pid);
|
||||
TRY(System::unlink(pid_path));
|
||||
return OptionalNone {};
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
// This is heavily based on how SystemServer's Service creates its socket.
|
||||
ErrorOr<int> IPCProcess::create_ipc_socket(ByteString const& socket_path)
|
||||
{
|
||||
if (!System::stat(socket_path).is_error())
|
||||
TRY(System::unlink(socket_path));
|
||||
|
||||
#ifdef SOCK_NONBLOCK
|
||||
auto socket_fd = TRY(System::socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
|
||||
#else
|
||||
auto socket_fd = TRY(System::socket(AF_LOCAL, SOCK_STREAM, 0));
|
||||
|
||||
int option = 1;
|
||||
TRY(System::ioctl(socket_fd, FIONBIO, &option));
|
||||
TRY(System::fcntl(socket_fd, F_SETFD, FD_CLOEXEC));
|
||||
#endif
|
||||
|
||||
#if !defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_GNU_HURD)
|
||||
TRY(System::fchmod(socket_fd, 0600));
|
||||
#endif
|
||||
|
||||
auto socket_address = SocketAddress::local(socket_path);
|
||||
auto socket_address_un = socket_address.to_sockaddr_un().release_value();
|
||||
|
||||
TRY(System::bind(socket_fd, reinterpret_cast<sockaddr*>(&socket_address_un), sizeof(socket_address_un)));
|
||||
TRY(System::listen(socket_fd, 16));
|
||||
|
||||
return socket_fd;
|
||||
}
|
||||
|
||||
ErrorOr<IPCProcess::ProcessPaths> IPCProcess::paths_for_process(StringView process_name)
|
||||
{
|
||||
auto runtime_directory = TRY(StandardPaths::runtime_directory());
|
||||
auto socket_path = ByteString::formatted("{}/{}.socket", runtime_directory, process_name);
|
||||
auto pid_path = ByteString::formatted("{}/{}.pid", runtime_directory, process_name);
|
||||
|
||||
return ProcessPaths { move(socket_path), move(pid_path) };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user