1/*
2 * Copyright (C) 2011 Igalia S.L.
3 * Copyright (C) 2011 Apple Inc.
4 * Copyright (C) 2012 Samsung Electronics
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 * THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "config.h"
29#include "PluginProcessProxy.h"
30
31#if ENABLE(PLUGIN_PROCESS)
32
33#include "PluginProcessCreationParameters.h"
34#include "ProcessExecutablePath.h"
35#include <WebCore/FileSystem.h>
36#include <wtf/text/CString.h>
37#include <wtf/text/WTFString.h>
38#if PLATFORM(GTK) || PLATFORM(EFL)
39#include <glib.h>
40#endif
41
42using namespace WebCore;
43
44namespace WebKit {
45
46void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
47{
48#if PLATFORM(EFL) && !defined(NDEBUG)
49    const char* commandPrefix = getenv("PLUGIN_PROCESS_COMMAND_PREFIX");
50    if (commandPrefix && *commandPrefix)
51        launchOptions.processCmdPrefix = String::fromUTF8(commandPrefix);
52#endif
53
54    launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path);
55}
56
57void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&)
58{
59}
60
61bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result)
62{
63#if PLATFORM(GTK) || PLATFORM(EFL)
64    CString binaryPath = fileSystemRepresentation(executablePathOfPluginProcess());
65    CString pluginPathCString = fileSystemRepresentation(pluginPath);
66    char* argv[4];
67    argv[0] = const_cast<char*>(binaryPath.data());
68    argv[1] = const_cast<char*>("-scanPlugin");
69    argv[2] = const_cast<char*>(pluginPathCString.data());
70    argv[3] = 0;
71
72    int status;
73    char* stdOut = 0;
74
75    // If the disposition of SIGCLD signal is set to SIG_IGN (default)
76    // then the signal will be ignored and g_spawn_sync() will not be
77    // able to return the status.
78    // As a consequence, we make sure that the disposition is set to
79    // SIG_DFL before calling g_spawn_sync().
80    struct sigaction action;
81    sigaction(SIGCLD, 0, &action);
82    if (action.sa_handler == SIG_IGN) {
83        action.sa_handler = SIG_DFL;
84        sigaction(SIGCLD, &action, 0);
85    }
86
87    if (!g_spawn_sync(0, argv, 0, G_SPAWN_STDERR_TO_DEV_NULL, 0, 0, &stdOut, 0, &status, 0))
88        return false;
89
90    if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS || !stdOut) {
91        free(stdOut);
92        return false;
93    }
94
95    String stdOutString(reinterpret_cast<const UChar*>(stdOut));
96    free(stdOut);
97
98    Vector<String> lines;
99    stdOutString.split(UChar('\n'), true, lines);
100
101    if (lines.size() < 3)
102        return false;
103
104    result.name.swap(lines[0]);
105    result.description.swap(lines[1]);
106    result.mimeDescription.swap(lines[2]);
107    return !result.mimeDescription.isEmpty();
108#else // PLATFORM(GTK) || PLATFORM(EFL)
109    return false;
110#endif // PLATFORM(GTK) || PLATFORM(EFL)
111}
112
113} // namespace WebKit
114
115#endif // ENABLE(PLUGIN_PROCESS)
116