REGRESSION (r141051): Broke plugin support on non-Mac WebKit2 Ports
[WebKit-https.git] / Source / WebKit2 / UIProcess / Launcher / gtk / ProcessLauncherGtk.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY MOTOROLA INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "ProcessLauncher.h"
29
30 #include "Connection.h"
31 #include "ProcessExecutablePath.h"
32 #include <WebCore/AuthenticationChallenge.h>
33 #include <WebCore/FileSystem.h>
34 #include <WebCore/NetworkingContext.h>
35 #include <WebCore/ResourceHandle.h>
36 #include <WebCore/RunLoop.h>
37 #include <errno.h>
38 #include <locale.h>
39 #include <wtf/text/CString.h>
40 #include <wtf/text/WTFString.h>
41 #include <wtf/gobject/GOwnPtr.h>
42 #include <wtf/gobject/GlibUtilities.h>
43
44 #if OS(LINUX)
45 #include <sys/prctl.h>
46 #endif
47
48 #ifdef SOCK_SEQPACKET
49 #define SOCKET_TYPE SOCK_SEQPACKET
50 #else
51 #define SOCKET_TYPE SOCK_STREAM
52 #endif
53
54 using namespace WebCore;
55
56 namespace WebKit {
57
58 static void childSetupFunction(gpointer userData)
59 {
60     int socket = GPOINTER_TO_INT(userData);
61     close(socket);
62
63     // Make child process inherit parent's locale.
64     g_setenv("LC_ALL", setlocale(LC_ALL, 0), TRUE);
65 }
66
67 static void childFinishedFunction(GPid, gint status, gpointer userData)
68 {
69     if (WIFEXITED(status) && !WEXITSTATUS(status))
70         return;
71
72     close(GPOINTER_TO_INT(userData));
73 }
74
75 void ProcessLauncher::launchProcess()
76 {
77     GPid pid = 0;
78
79     int sockets[2];
80     if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) < 0) {
81         g_printerr("Creation of socket failed: %s.\n", g_strerror(errno));
82         ASSERT_NOT_REACHED();
83         return;
84     }
85
86     String executablePath, pluginPath;
87     CString realExecutablePath, realPluginPath;
88     if (m_launchOptions.processType == WebProcess)
89         executablePath = executablePathOfWebProcess();
90     else {
91         executablePath = executablePathOfPluginProcess();
92         pluginPath = m_launchOptions.extraInitializationData.get("plugin-path");
93         realPluginPath = fileSystemRepresentation(pluginPath);
94     }
95
96     realExecutablePath = fileSystemRepresentation(executablePath);
97     GOwnPtr<gchar> socket(g_strdup_printf("%d", sockets[0]));
98     char* argv[4];
99     argv[0] = const_cast<char*>(realExecutablePath.data());
100     argv[1] = socket.get();
101     argv[2] = const_cast<char*>(realPluginPath.data());
102     argv[3] = 0;
103
104     GOwnPtr<GError> error;
105     int spawnFlags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD;
106     if (!g_spawn_async(0, argv, 0, static_cast<GSpawnFlags>(spawnFlags), childSetupFunction, GINT_TO_POINTER(sockets[1]), &pid, &error.outPtr())) {
107         g_printerr("Unable to fork a new WebProcess: %s.\n", error->message);
108         ASSERT_NOT_REACHED();
109     }
110
111     close(sockets[0]);
112     m_processIdentifier = pid;
113
114     // Monitor the child process, it calls waitpid to prevent the child process from becomming a zombie,
115     // and it allows us to close the socket when the child process crashes.
116     g_child_watch_add(m_processIdentifier, childFinishedFunction, GINT_TO_POINTER(sockets[1]));
117
118     // We've finished launching the process, message back to the main run loop.
119     RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, sockets[1]));
120 }
121
122 void ProcessLauncher::terminateProcess()
123 {   
124     if (!m_processIdentifier)
125         return;
126
127     kill(m_processIdentifier, SIGKILL);
128 }
129
130 void ProcessLauncher::platformInvalidate()
131 {
132 }
133
134 } // namespace WebKit