ProcessLauncherWPE.cpp [plain text]
#include "config.h"
#include "ProcessLauncher.h"
#include "Connection.h"
#include "ProcessExecutablePath.h"
#include <WebCore/FileSystem.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <wpe/renderer-host.h>
#include <wtf/RunLoop.h>
#include <wtf/glib/GLibUtilities.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
namespace WebKit {
static void childSetupFunction(gpointer userData)
{
int socket = GPOINTER_TO_INT(userData);
close(socket);
}
void ProcessLauncher::launchProcess()
{
GPid pid = 0;
IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection(IPC::Connection::ConnectionOptions::SetCloexecOnServer);
String executablePath;
CString realExecutablePath;
switch (m_launchOptions.processType) {
case ProcessLauncher::ProcessType::Web:
executablePath = executablePathOfWebProcess();
break;
case ProcessLauncher::ProcessType::Network:
executablePath = executablePathOfNetworkProcess();
break;
#if ENABLE(DATABASE_PROCESS)
case ProcessLauncher::ProcessType::Database:
executablePath = executablePathOfDatabaseProcess();
break;
#endif
default:
ASSERT_NOT_REACHED();
return;
}
realExecutablePath = fileSystemRepresentation(executablePath);
GUniquePtr<gchar> wkSocket(g_strdup_printf("%d", socketPair.client));
GUniquePtr<gchar> wpeSocket;
unsigned nargs = 4; if (m_launchOptions.processType == ProcessLauncher::ProcessType::Web) {
wpeSocket = GUniquePtr<gchar>(g_strdup_printf("%d", wpe_renderer_host_create_client()));
nargs = 5;
}
#if ENABLE(DEVELOPER_MODE)
Vector<CString> prefixArgs;
if (!m_launchOptions.processCmdPrefix.isNull()) {
Vector<String> splitArgs;
m_launchOptions.processCmdPrefix.split(' ', splitArgs);
for (auto it = splitArgs.begin(); it != splitArgs.end(); it++)
prefixArgs.append(it->utf8());
nargs += prefixArgs.size();
}
#endif
char** argv = g_newa(char*, nargs);
unsigned i = 0;
#if ENABLE(DEVELOPER_MODE)
for (auto it = prefixArgs.begin(); it != prefixArgs.end(); it++)
argv[i++] = const_cast<char*>(it->data());
#endif
argv[i++] = const_cast<char*>(realExecutablePath.data());
argv[i++] = wkSocket.get();
if (m_launchOptions.processType == ProcessLauncher::ProcessType::Web)
argv[i++] = wpeSocket.get();
argv[i++] = nullptr;
GUniqueOutPtr<GError> error;
if (!g_spawn_async(0, argv, 0, G_SPAWN_LEAVE_DESCRIPTORS_OPEN, childSetupFunction, GINT_TO_POINTER(socketPair.server), &pid, &error.outPtr())) {
g_printerr("Unable to fork a new WebProcess: %s.\n", error->message);
ASSERT_NOT_REACHED();
}
while (fcntl(socketPair.client, F_SETFD, FD_CLOEXEC) == -1)
RELEASE_ASSERT(errno != EINTR);
close(socketPair.client);
m_processIdentifier = pid;
RefPtr<ProcessLauncher> protectedThis(this);
IPC::Connection::Identifier serverSocket = socketPair.server;
RunLoop::main().dispatch([protectedThis, pid, serverSocket] {
protectedThis->didFinishLaunchingProcess(pid, serverSocket);
});
}
void ProcessLauncher::terminateProcess()
{
if (m_isLaunching) {
invalidate();
return;
}
if (!m_processIdentifier)
return;
kill(m_processIdentifier, SIGKILL);
m_processIdentifier = 0;
}
void ProcessLauncher::platformInvalidate()
{
}
}