mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1401786 - Move base::LaunchApp options into a LaunchOptions struct, like upstream Chromium. r=billm
MozReview-Commit-ID: 74IXV4oGeWR --HG-- extra : rebase_source : ef4021a60506a8fc5fa5a35e3f3fefb9dbad75d6
This commit is contained in:
parent
9c5a18de90
commit
c7f8a32bf4
@ -95,16 +95,36 @@ void SetAllFDsToCloseOnExec();
|
||||
// given multimap. Only call this function in a child process where you know
|
||||
// that there aren't any other threads.
|
||||
void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
|
||||
|
||||
typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
|
||||
typedef std::map<std::string, std::string> environment_map;
|
||||
#endif
|
||||
|
||||
struct LaunchOptions {
|
||||
// If true, wait for the process to terminate. Otherwise, return
|
||||
// immediately.
|
||||
bool wait = false;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool start_hidden = false;
|
||||
#endif
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
// Environment variables to be applied in addition to the current
|
||||
// process's environment, replacing them where necessary.
|
||||
environment_map environ;
|
||||
|
||||
// A mapping of (src fd -> dest fd) to propagate into the child
|
||||
// process. All other fds will be closed, except std{in,out,err}.
|
||||
file_handle_mapping_vector fds_to_remap;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Runs the given application name with the given command line. Normally, the
|
||||
// first command line argument should be the path to the process, and don't
|
||||
// forget to quote it.
|
||||
//
|
||||
// If wait is true, it will block and wait for the other process to finish,
|
||||
// otherwise, it will just continue asynchronously.
|
||||
//
|
||||
// Example (including literal quotes)
|
||||
// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
|
||||
//
|
||||
@ -113,28 +133,20 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
|
||||
// NOTE: In this case, the caller is responsible for closing the handle so
|
||||
// that it doesn't leak!
|
||||
bool LaunchApp(const std::wstring& cmdline,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle);
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle);
|
||||
|
||||
#elif defined(OS_POSIX)
|
||||
// Runs the application specified in argv[0] with the command line argv.
|
||||
// Before launching all FDs open in the parent process will be marked as
|
||||
// close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to
|
||||
// propagate FDs into the child process.
|
||||
//
|
||||
// As above, if wait is true, execute synchronously. The pid will be stored
|
||||
// in process_handle if that pointer is non-null.
|
||||
// The pid will be stored in process_handle if that pointer is
|
||||
// non-null.
|
||||
//
|
||||
// Note that the first argument in argv must point to the filename,
|
||||
// and must be fully specified.
|
||||
typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
|
||||
// and must be fully specified (i.e., this will not search $PATH).
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
bool wait, ProcessHandle* process_handle);
|
||||
|
||||
typedef std::map<std::string, std::string> environment_map;
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle);
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle);
|
||||
|
||||
// Deleter for the array of strings allocated within BuildEnvironmentArray.
|
||||
struct FreeEnvVarsArray
|
||||
@ -152,7 +164,8 @@ EnvironmentArray BuildEnvironmentArray(const environment_map& env_vars_to_set);
|
||||
// Executes the application specified by cl. This function delegates to one
|
||||
// of the above two platform-specific functions.
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle);
|
||||
const LaunchOptions&,
|
||||
ProcessHandle* process_handle);
|
||||
|
||||
// Used to filter processes by process ID.
|
||||
class ProcessFilter {
|
||||
|
@ -24,17 +24,11 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
|
||||
|
||||
namespace base {
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
return LaunchApp(argv, fds_to_remap, environment_map(),
|
||||
wait, process_handle);
|
||||
}
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle)
|
||||
{
|
||||
bool retval = true;
|
||||
|
||||
char* argv_copy[argv.size() + 1];
|
||||
@ -47,7 +41,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
// as close-on-exec.
|
||||
SetAllFDsToCloseOnExec();
|
||||
|
||||
EnvironmentArray vars = BuildEnvironmentArray(env_vars_to_set);
|
||||
EnvironmentArray vars = BuildEnvironmentArray(options.environ);
|
||||
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
if (posix_spawn_file_actions_init(&file_actions) != 0) {
|
||||
@ -55,11 +49,9 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
|
||||
// Turn fds_to_remap array into a set of dup2 calls.
|
||||
for (file_handle_mapping_vector::const_iterator it = fds_to_remap.begin();
|
||||
it != fds_to_remap.end();
|
||||
++it) {
|
||||
int src_fd = it->first;
|
||||
int dest_fd = it->second;
|
||||
for (const auto& fd_map : options.fds_to_remap) {
|
||||
int src_fd = fd_map.first;
|
||||
int dest_fd = fd_map.second;
|
||||
|
||||
if (src_fd == dest_fd) {
|
||||
int flags = fcntl(src_fd, F_GETFD);
|
||||
@ -90,7 +82,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
} else {
|
||||
gProcessLog.print("==> process %d launched child process %d\n",
|
||||
GetCurrentProcId(), pid);
|
||||
if (wait)
|
||||
if (options.wait)
|
||||
HANDLE_EINTR(waitpid(pid, 0, 0));
|
||||
|
||||
if (process_handle)
|
||||
@ -101,10 +93,9 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle) {
|
||||
// TODO(playmobil): Do we need to respect the start_hidden flag?
|
||||
file_handle_mapping_vector no_files;
|
||||
return LaunchApp(cl.argv(), no_files, wait, process_handle);
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle) {
|
||||
return LaunchApp(cl.argv(), options, process_handle);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -25,33 +25,26 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
|
||||
namespace base {
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
return LaunchApp(argv, fds_to_remap, environment_map(),
|
||||
wait, process_handle);
|
||||
}
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle)
|
||||
{
|
||||
mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
|
||||
// Illegal to allocate memory after fork and before execvp
|
||||
InjectiveMultimap fd_shuffle1, fd_shuffle2;
|
||||
fd_shuffle1.reserve(fds_to_remap.size());
|
||||
fd_shuffle2.reserve(fds_to_remap.size());
|
||||
fd_shuffle1.reserve(options.fds_to_remap.size());
|
||||
fd_shuffle2.reserve(options.fds_to_remap.size());
|
||||
|
||||
EnvironmentArray envp = BuildEnvironmentArray(env_vars_to_set);
|
||||
EnvironmentArray envp = BuildEnvironmentArray(options.environ);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
return false;
|
||||
|
||||
if (pid == 0) {
|
||||
for (file_handle_mapping_vector::const_iterator
|
||||
it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) {
|
||||
fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
|
||||
fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
|
||||
// In the child:
|
||||
for (const auto& fd_map : options.fds_to_remap) {
|
||||
fd_shuffle1.push_back(InjectionArc(fd_map.first, fd_map.second, false));
|
||||
fd_shuffle2.push_back(InjectionArc(fd_map.first, fd_map.second, false));
|
||||
}
|
||||
|
||||
if (!ShuffleFileDescriptors(&fd_shuffle1))
|
||||
@ -69,24 +62,24 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
// only on debug builds; otherwise it's a signal-safe no-op.)
|
||||
DLOG(ERROR) << "FAILED TO exec() CHILD PROCESS, path: " << argv_cstr[0];
|
||||
_exit(127);
|
||||
} else {
|
||||
gProcessLog.print("==> process %d launched child process %d\n",
|
||||
GetCurrentProcId(), pid);
|
||||
if (wait)
|
||||
HANDLE_EINTR(waitpid(pid, 0, 0));
|
||||
|
||||
if (process_handle)
|
||||
*process_handle = pid;
|
||||
}
|
||||
|
||||
// In the parent:
|
||||
gProcessLog.print("==> process %d launched child process %d\n",
|
||||
GetCurrentProcId(), pid);
|
||||
if (options.wait)
|
||||
HANDLE_EINTR(waitpid(pid, 0, 0));
|
||||
|
||||
if (process_handle)
|
||||
*process_handle = pid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden,
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle) {
|
||||
file_handle_mapping_vector no_files;
|
||||
return LaunchApp(cl.argv(), no_files, wait, process_handle);
|
||||
return LaunchApp(cl.argv(), options, process_handle);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
#include "base/process_util.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
@ -24,16 +25,9 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
|
||||
namespace base {
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
return LaunchApp(argv, fds_to_remap, environment_map(),
|
||||
wait, process_handle);
|
||||
}
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle)
|
||||
{
|
||||
bool retval = true;
|
||||
|
||||
char* argv_copy[argv.size() + 1];
|
||||
@ -42,7 +36,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
argv_copy[argv.size()] = NULL;
|
||||
|
||||
EnvironmentArray vars = BuildEnvironmentArray(env_vars_to_set);
|
||||
EnvironmentArray vars = BuildEnvironmentArray(options.environ);
|
||||
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
if (posix_spawn_file_actions_init(&file_actions) != 0) {
|
||||
@ -53,11 +47,9 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
});
|
||||
|
||||
// Turn fds_to_remap array into a set of dup2 calls.
|
||||
for (file_handle_mapping_vector::const_iterator it = fds_to_remap.begin();
|
||||
it != fds_to_remap.end();
|
||||
++it) {
|
||||
int src_fd = it->first;
|
||||
int dest_fd = it->second;
|
||||
for (const auto& fd_map : options.fds_to_remap) {
|
||||
int src_fd = fd_map.first;
|
||||
int dest_fd = fd_map.second;
|
||||
|
||||
if (src_fd == dest_fd) {
|
||||
int flags = fcntl(src_fd, F_GETFD);
|
||||
@ -71,6 +63,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize spawn attributes.
|
||||
posix_spawnattr_t spawnattr;
|
||||
if (posix_spawnattr_init(&spawnattr) != 0) {
|
||||
return false;
|
||||
@ -107,7 +100,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
} else {
|
||||
gProcessLog.print("==> process %d launched child process %d\n",
|
||||
GetCurrentProcId(), pid);
|
||||
if (wait)
|
||||
if (options.wait)
|
||||
HANDLE_EINTR(waitpid(pid, 0, 0));
|
||||
|
||||
if (process_handle)
|
||||
@ -118,10 +111,9 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle) {
|
||||
// TODO(playmobil): Do we need to respect the start_hidden flag?
|
||||
file_handle_mapping_vector no_files;
|
||||
return LaunchApp(cl.argv(), no_files, wait, process_handle);
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle) {
|
||||
return LaunchApp(cl.argv(), options, process_handle);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -272,7 +272,8 @@ void FreeThreadAttributeList(LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList) {
|
||||
}
|
||||
|
||||
bool LaunchApp(const std::wstring& cmdline,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle) {
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle) {
|
||||
|
||||
// We want to inherit the std handles so dump() statements and assertion
|
||||
// messages in the child process can be seen - but we *do not* want to
|
||||
@ -289,7 +290,7 @@ bool LaunchApp(const std::wstring& cmdline,
|
||||
STARTUPINFO &startup_info = startup_info_ex.StartupInfo;
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
startup_info.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startup_info.wShowWindow = start_hidden ? SW_HIDE : SW_SHOW;
|
||||
startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW;
|
||||
|
||||
// Per the comment in CreateThreadAttributeList, lpAttributeList will contain
|
||||
// a pointer to handlesToInherit, so make sure they have the same lifetime.
|
||||
@ -340,7 +341,7 @@ bool LaunchApp(const std::wstring& cmdline,
|
||||
// Handles must be closed or they will leak
|
||||
CloseHandle(process_info.hThread);
|
||||
|
||||
if (wait)
|
||||
if (options.wait)
|
||||
WaitForSingleObject(process_info.hProcess, INFINITE);
|
||||
|
||||
// If the caller wants the process handle, we won't close it.
|
||||
@ -353,9 +354,9 @@ bool LaunchApp(const std::wstring& cmdline,
|
||||
}
|
||||
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle) {
|
||||
return LaunchApp(cl.command_line_string(), wait,
|
||||
start_hidden, process_handle);
|
||||
const LaunchOptions& options,
|
||||
ProcessHandle* process_handle) {
|
||||
return LaunchApp(cl.command_line_string(), options, process_handle);
|
||||
}
|
||||
|
||||
bool KillProcess(ProcessHandle process, int exit_code, bool wait) {
|
||||
|
@ -86,6 +86,7 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
|
||||
: mProcessType(aProcessType),
|
||||
mIsFileContent(aIsFileContent),
|
||||
mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
|
||||
mLaunchOptions(MakeUnique<base::LaunchOptions>()),
|
||||
mProcessState(CREATING_CHANNEL),
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
mEnableSandboxLogging(false),
|
||||
@ -642,17 +643,16 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
// we split the logic here.
|
||||
|
||||
# if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
|
||||
base::environment_map newEnvVars;
|
||||
|
||||
# if defined(MOZ_WIDGET_GTK)
|
||||
if (mProcessType == GeckoProcessType_Content) {
|
||||
// disable IM module to avoid sandbox violation
|
||||
newEnvVars["GTK_IM_MODULE"] = "gtk-im-context-simple";
|
||||
mLaunchOptions->environ["GTK_IM_MODULE"] = "gtk-im-context-simple";
|
||||
|
||||
// Disable ATK accessibility code in content processes because it conflicts
|
||||
// with the sandbox, and we proxy that information through the main process
|
||||
// anyway.
|
||||
newEnvVars["NO_AT_BRIDGE"] = "1";
|
||||
mLaunchOptions->environ["NO_AT_BRIDGE"] = "1";
|
||||
}
|
||||
# endif // defined(MOZ_WIDGET_GTK)
|
||||
|
||||
@ -678,10 +678,10 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
new_ld_lib_path.Append(':');
|
||||
new_ld_lib_path.Append(ld_library_path);
|
||||
}
|
||||
newEnvVars["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
|
||||
mLaunchOptions->environ["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
|
||||
|
||||
# elif OS_MACOSX // defined(OS_LINUX) || defined(OS_BSD)
|
||||
newEnvVars["DYLD_LIBRARY_PATH"] = path.get();
|
||||
mLaunchOptions->environ["DYLD_LIBRARY_PATH"] = path.get();
|
||||
// XXX DYLD_INSERT_LIBRARIES should only be set when launching a plugin
|
||||
// process, and has no effect on other subprocesses (the hooks in
|
||||
// libplugin_child_interpose.dylib become noops). But currently it
|
||||
@ -700,7 +700,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
}
|
||||
interpose.Append(path.get());
|
||||
interpose.AppendLiteral("/libplugin_child_interpose.dylib");
|
||||
newEnvVars["DYLD_INSERT_LIBRARIES"] = interpose.get();
|
||||
mLaunchOptions->environ["DYLD_INSERT_LIBRARIES"] = interpose.get();
|
||||
# endif // defined(OS_LINUX) || defined(OS_BSD)
|
||||
}
|
||||
# endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
|
||||
@ -725,7 +725,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
}
|
||||
// Explicitly construct the std::string to make it clear that this
|
||||
// isn't retaining a pointer to the nsCString's buffer.
|
||||
newEnvVars["LD_PRELOAD"] = std::string(preload.get());
|
||||
mLaunchOptions->environ["LD_PRELOAD"] = std::string(preload.get());
|
||||
}
|
||||
# endif // defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||
|
||||
@ -733,7 +733,8 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
// STDOUT_FILENO, for example
|
||||
int srcChannelFd, dstChannelFd;
|
||||
channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
|
||||
mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
|
||||
mLaunchOptions->fds_to_remap
|
||||
.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
|
||||
|
||||
// no need for kProcessChannelID, the child process inherits the
|
||||
// other end of the socketpair() from us
|
||||
@ -790,7 +791,8 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
&childCrashFd, &childCrashRemapFd))
|
||||
return false;
|
||||
if (0 <= childCrashFd) {
|
||||
mFileMap.push_back(std::pair<int,int>(childCrashFd, childCrashRemapFd));
|
||||
mLaunchOptions->fds_to_remap
|
||||
.push_back(std::pair<int,int>(childCrashFd, childCrashRemapFd));
|
||||
// "true" == crash reporting enabled
|
||||
childArgv.push_back("true");
|
||||
}
|
||||
@ -808,7 +810,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
int srcFd, dstFd;
|
||||
SandboxReporter::Singleton()
|
||||
->GetClientFileDescriptorMapping(&srcFd, &dstFd);
|
||||
mFileMap.push_back(std::make_pair(srcFd, dstFd));
|
||||
mLaunchOptions->fds_to_remap.push_back(std::make_pair(srcFd, dstFd));
|
||||
}
|
||||
# endif // defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||
|
||||
@ -826,13 +828,10 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
childArgv.push_back(childProcessType);
|
||||
|
||||
# if defined(MOZ_WIDGET_ANDROID)
|
||||
LaunchAndroidService(childProcessType, childArgv, mFileMap, &process);
|
||||
LaunchAndroidService(childProcessType, childArgv,
|
||||
mLaunchOptions->fds_to_remap, &process);
|
||||
# else // goes with defined(MOZ_WIDGET_ANDROID)
|
||||
base::LaunchApp(childArgv, mFileMap,
|
||||
# if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
|
||||
newEnvVars,
|
||||
# endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
|
||||
false, &process);
|
||||
base::LaunchApp(childArgv, *mLaunchOptions, &process);
|
||||
# endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
// We're in the parent and the child was launched. Close the child FD in the
|
||||
@ -1064,7 +1063,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
} else
|
||||
# endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
{
|
||||
base::LaunchApp(cmdLine, false, false, &process);
|
||||
base::LaunchApp(cmdLine, *mLaunchOptions, &process);
|
||||
|
||||
# ifdef MOZ_SANDBOX
|
||||
// We need to be able to duplicate handles to some types of non-sandboxed
|
||||
@ -1111,6 +1110,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
mProcessState = PROCESS_CREATED;
|
||||
lock.Notify();
|
||||
|
||||
mLaunchOptions = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXULAppAPI.h" // for GeckoProcessType
|
||||
@ -118,6 +119,11 @@ protected:
|
||||
bool mIsFileContent;
|
||||
Monitor mMonitor;
|
||||
FilePath mProcessPath;
|
||||
// GeckoChildProcessHost holds the launch options so they can be set
|
||||
// up on the main thread using main-thread-only APIs like prefs, and
|
||||
// then used for the actual launch on another thread. This pointer
|
||||
// is set to null to free the options after the child is launched.
|
||||
UniquePtr<base::LaunchOptions> mLaunchOptions;
|
||||
|
||||
// This value must be accessed while holding mMonitor.
|
||||
enum {
|
||||
@ -152,10 +158,6 @@ protected:
|
||||
#endif
|
||||
#endif // XP_WIN
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
base::file_handle_mapping_vector mFileMap;
|
||||
#endif
|
||||
|
||||
ProcessHandle mChildProcessHandle;
|
||||
#if defined(OS_MACOSX)
|
||||
task_t mChildTask;
|
||||
|
@ -34,14 +34,14 @@ GetLSBRelease(nsACString& aDistributor,
|
||||
gLsbReleasePath, "-idrc"
|
||||
};
|
||||
|
||||
std::vector<std::pair<int, int>> fdMap = {
|
||||
{ pipefd[1], STDOUT_FILENO }
|
||||
};
|
||||
base::LaunchOptions options;
|
||||
options.fds_to_remap.push_back({ pipefd[1], STDOUT_FILENO });
|
||||
options.wait = true;
|
||||
|
||||
base::ProcessHandle process;
|
||||
base::LaunchApp(argv, fdMap, true, &process);
|
||||
bool ok = base::LaunchApp(argv, options, &process);
|
||||
close(pipefd[1]);
|
||||
if (!process) {
|
||||
if (!ok) {
|
||||
NS_WARNING("Failed to spawn lsb_release!");
|
||||
close(pipefd[0]);
|
||||
return false;
|
||||
|
@ -576,13 +576,13 @@ nsProcess::RunProcess(bool aBlocking, char** aMyArgv, nsIObserver* aObserver,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_UNIX)
|
||||
base::file_handle_mapping_vector fdMap;
|
||||
base::LaunchOptions options;
|
||||
std::vector<std::string> argvVec;
|
||||
for (char** arg = aMyArgv; *arg != nullptr; ++arg) {
|
||||
argvVec.push_back(*arg);
|
||||
}
|
||||
pid_t newPid;
|
||||
if (base::LaunchApp(argvVec, fdMap, false, &newPid)) {
|
||||
if (base::LaunchApp(argvVec, options, &newPid)) {
|
||||
static_assert(sizeof(pid_t) <= sizeof(int32_t),
|
||||
"mPid is large enough to hold a pid");
|
||||
mPid = static_cast<int32_t>(newPid);
|
||||
|
Loading…
Reference in New Issue
Block a user