165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/* 265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved. 365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without 665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions 765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met: 865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright 965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * notice, this list of conditions and the following disclaimer. 1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright 1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * notice, this list of conditions and the following disclaimer in the 1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * documentation and/or other materials provided with the distribution. 1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE. 2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */ 2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h" 2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ProcessLauncher.h" 2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Connection.h" 3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "RunLoop.h" 3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebProcess.h" 3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QApplication> 3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QDebug> 3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QFile> 3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QLocalServer> 3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QMetaType> 3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QProcess> 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QString> 4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <QtCore/qglobal.h> 4181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <WebCore/NotImplemented.h> 422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <errno.h> 432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <fcntl.h> 442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <runtime/InitializeThreading.h> 452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <string> 4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <sys/resource.h> 472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <sys/socket.h> 4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <unistd.h> 492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/HashSet.h> 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/PassRefPtr.h> 512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/Threading.h> 522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/text/WTFString.h> 532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if defined Q_OS_LINUX 542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <sys/prctl.h> 552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <signal.h> 562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif 5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore; 5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit { 6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass QtWebProcess : public QProcess 6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Q_OBJECT 6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochpublic: 6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QtWebProcess(QObject* parent = 0) 6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch : QProcess(parent) 6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch { 6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockprotected: 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block virtual void setupChildProcess(); 7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 752fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid QtWebProcess::setupChildProcess() 7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if defined Q_OS_LINUX 782bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef NDEBUG 792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (getenv("QT_WEBKIT_KEEP_ALIVE_WEB_PROCESS")) 802bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 812bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block prctl(PR_SET_PDEATHSIG, SIGKILL); 832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif 8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if OS(SYMBIAN) 872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// FIXME: Symbian's POSIX layer doesn't have a socketpair(), so 882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// the following is just to fix the build until a pure Symbian 892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// IPC implementation lands on trunk 902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int socketpair(int, int, int , int[2]) 912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return -1; 932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 962fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid ProcessLauncher::launchProcess() 9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 982bde8e466a4451c7319e3a072d118917957d6554Steve Block QString applicationPath = QLatin1String("%1 %2"); 9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1002bde8e466a4451c7319e3a072d118917957d6554Steve Block if (QFile::exists(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess"))) { 1012bde8e466a4451c7319e3a072d118917957d6554Steve Block applicationPath = applicationPath.arg(QCoreApplication::applicationDirPath() + QLatin1String("/QtWebProcess")); 10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } else { 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block applicationPath = applicationPath.arg(QLatin1String("QtWebProcess")); 10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int sockets[2]; 1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) { 1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block qDebug() << "Creation of socket failed with errno:" << errno; 1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Don't expose the ui socket to the web process 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC) == -1) { 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (errno != EINTR) { 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (close(sockets[0]) == -1 && errno == EINTR) { } 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (close(sockets[1]) == -1 && errno == EINTR) { } 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block QString program(applicationPath.arg(sockets[0])); 12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QProcess* webProcess = new QtWebProcess(); 12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch webProcess->setProcessChannelMode(QProcess::ForwardedChannels); 12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch webProcess->start(program); 12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Don't expose the web socket to possible future web processes 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1) { 1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (errno != EINTR) { 1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_NOT_REACHED(); 1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block delete webProcess; 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!webProcess->waitForStarted()) { 13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch qDebug() << "Failed to start" << program; 14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT_NOT_REACHED(); 14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch delete webProcess; 14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch setpriority(PRIO_PROCESS, webProcess->pid(), 10); 14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RunLoop::main()->scheduleWork(WorkItem::create(this, &WebKit::ProcessLauncher::didFinishLaunchingProcess, webProcess, sockets[1])); 14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid ProcessLauncher::terminateProcess() 15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!m_processIdentifier) 15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QObject::connect(m_processIdentifier, SIGNAL(finished(int)), m_processIdentifier, SLOT(deleteLater()), Qt::QueuedConnection); 15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_processIdentifier->terminate(); 15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid ProcessLauncher::platformInvalidate() 16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit 16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ProcessLauncherQt.moc" 167