void ProcessLauncher::launchProcess() { int sockets[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { ASSERT_NOT_REACHED(); return; } pid_t pid = fork(); if (!pid) { // child process close(sockets[1]); String socket = String::format("%d", sockets[0]); String executablePath; switch (m_launchOptions.processType) { case WebProcess: executablePath = executablePathOfWebProcess(); break; case PluginProcess: executablePath = executablePathOfPluginProcess(); break; default: ASSERT_NOT_REACHED(); return; } #ifndef NDEBUG if (m_launchOptions.processCmdPrefix.isEmpty()) #endif execl(executablePath.utf8().data(), executablePath.utf8().data(), socket.utf8().data(), static_cast<char*>(0)); #ifndef NDEBUG else { String cmd = makeString(m_launchOptions.processCmdPrefix, ' ', executablePath, ' ', socket); if (system(cmd.utf8().data()) == -1) { ASSERT_NOT_REACHED(); return; } } #endif } else if (pid > 0) { // parent process; close(sockets[0]); m_processIdentifier = pid; // We've finished launching the process, message back to the main run loop. RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, pid, sockets[1])); } else { ASSERT_NOT_REACHED(); return; } }
void ProcessLauncher::launchProcess() { int sockets[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { ASSERT_NOT_REACHED(); return; } String processCmdPrefix, executablePath, pluginPath; switch (m_launchOptions.processType) { case WebProcess: executablePath = executablePathOfWebProcess(); break; #if ENABLE(PLUGIN_PROCESS) case PluginProcess: executablePath = executablePathOfPluginProcess(); pluginPath = m_launchOptions.extraInitializationData.get("plugin-path"); break; #endif default: ASSERT_NOT_REACHED(); return; } #ifndef NDEBUG if (!m_launchOptions.processCmdPrefix.isEmpty()) processCmdPrefix = m_launchOptions.processCmdPrefix; #endif Vector<OwnArrayPtr<char>> args = createArgsArray(processCmdPrefix, executablePath, String::number(sockets[0]), pluginPath); // Do not perform memory allocation in the middle of the fork() // exec() below. FastMalloc can potentially deadlock because // the fork() doesn't inherit the running threads. pid_t pid = fork(); if (!pid) { // Child process. close(sockets[1]); execvp(args.data()[0].get(), reinterpret_cast<char* const*>(args.data())); } else if (pid > 0) { // parent process; close(sockets[0]); m_processIdentifier = pid; // We've finished launching the process, message back to the main run loop. RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, pid, sockets[1])); } else { ASSERT_NOT_REACHED(); return; } }
void ProcessLauncher::launchProcess() { GPid pid = 0; int sockets[2]; if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) < 0) { g_printerr("Creation of socket failed: %s.\n", g_strerror(errno)); ASSERT_NOT_REACHED(); return; } String executablePath, pluginPath; CString realExecutablePath, realPluginPath; if (m_launchOptions.processType == WebProcess) executablePath = executablePathOfWebProcess(); else { executablePath = executablePathOfPluginProcess(); pluginPath = m_launchOptions.extraInitializationData.get("plugin-path"); realPluginPath = fileSystemRepresentation(pluginPath); } realExecutablePath = fileSystemRepresentation(executablePath); GOwnPtr<gchar> socket(g_strdup_printf("%d", sockets[0])); char* argv[4]; argv[0] = const_cast<char*>(realExecutablePath.data()); argv[1] = socket.get(); argv[2] = const_cast<char*>(realPluginPath.data()); argv[3] = 0; GOwnPtr<GError> error; int spawnFlags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD; if (!g_spawn_async(0, argv, 0, static_cast<GSpawnFlags>(spawnFlags), childSetupFunction, GINT_TO_POINTER(sockets[1]), &pid, &error.outPtr())) { g_printerr("Unable to fork a new WebProcess: %s.\n", error->message); ASSERT_NOT_REACHED(); } close(sockets[0]); m_processIdentifier = pid; // Monitor the child process, it calls waitpid to prevent the child process from becomming a zombie, // and it allows us to close the socket when the child process crashes. g_child_watch_add(m_processIdentifier, childFinishedFunction, GINT_TO_POINTER(sockets[1])); // We've finished launching the process, message back to the main run loop. RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, sockets[1])); }
void ProcessLauncher::launchProcess() { int sockets[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { ASSERT_NOT_REACHED(); return; } CString executablePath, pluginPath; switch (m_launchOptions.processType) { case WebProcess: executablePath = executablePathOfWebProcess().utf8(); break; #if ENABLE(PLUGIN_PROCESS) case PluginProcess: executablePath = executablePathOfPluginProcess().utf8(); pluginPath = m_launchOptions.extraInitializationData.get("plugin-path").utf8(); break; #endif default: ASSERT_NOT_REACHED(); return; } char socket[5]; snprintf(socket, sizeof(socket), "%d", sockets[0]); #ifndef NDEBUG CString prefixedExecutablePath; if (!m_launchOptions.processCmdPrefix.isEmpty()) { String prefixedExecutablePathStr = m_launchOptions.processCmdPrefix + ' ' + String::fromUTF8(executablePath.data()) + ' ' + socket + ' ' + String::fromUTF8(pluginPath.data()); prefixedExecutablePath = prefixedExecutablePathStr.utf8(); } #endif // Do not perform memory allocation in the middle of the fork() // exec() below. FastMalloc can potentially deadlock because // the fork() doesn't inherit the running threads. pid_t pid = fork(); if (!pid) { // Child process. close(sockets[1]); #ifndef NDEBUG if (!prefixedExecutablePath.isNull()) { // FIXME: This is not correct because it invokes the shell // and keeps this process waiting. Should be changed to // something like execvp(). if (system(prefixedExecutablePath.data()) == -1) { ASSERT_NOT_REACHED(); exit(EXIT_FAILURE); } else exit(EXIT_SUCCESS); } #endif execl(executablePath.data(), executablePath.data(), socket, pluginPath.data(), static_cast<char*>(0)); } else if (pid > 0) { // parent process; close(sockets[0]); m_processIdentifier = pid; // We've finished launching the process, message back to the main run loop. RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, pid, sockets[1])); } else { ASSERT_NOT_REACHED(); return; } }