/*
    Copyright (C) 2012 Samsung Electronics

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "ProcessLauncher.h"

#include "Connection.h"
#include "ProcessExecutablePath.h"
#include <WebCore/AuthenticationChallenge.h>
#include <WebCore/FileSystem.h>
#include <WebCore/NetworkingContext.h>
#include <WebCore/ResourceHandle.h>
#include <WebCore/RunLoop.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>

using namespace WebCore;

namespace WebKit {

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;
    }
}

void ProcessLauncher::terminateProcess()
{
    if (!m_processIdentifier)
        return;
    kill(m_processIdentifier, SIGKILL);
}

void ProcessLauncher::platformInvalidate()
{
}

} // namespace WebKit
