예제 #1
0
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;
    }
}
예제 #3
0
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]));
}
예제 #4
0
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;
    }
}