Implement Relaunch on Linux
This commit is contained in:
parent
c3fe2dae9d
commit
a3f39e9d0b
7 changed files with 104 additions and 12 deletions
|
@ -158,6 +158,7 @@ int AtomMainDelegate::RunProcess(
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) {
|
||||
return process_type != kRelauncherProcess;
|
||||
}
|
||||
|
@ -166,6 +167,7 @@ bool AtomMainDelegate::DelaySandboxInitialization(
|
|||
const std::string& process_type) {
|
||||
return process_type == kRelauncherProcess;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<brightray::ContentClient>
|
||||
AtomMainDelegate::CreateContentClient() {
|
||||
|
|
|
@ -27,8 +27,10 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
|||
int RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) override;
|
||||
#if defined(OS_MACOSX)
|
||||
bool ShouldSendMachPort(const std::string& process_type) override;
|
||||
bool DelaySandboxInitialization(const std::string& process_type) override;
|
||||
#endif
|
||||
|
||||
// brightray::MainDelegate:
|
||||
std::unique_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
|
@ -33,6 +34,17 @@ Browser* Browser::Get() {
|
|||
return AtomBrowserMainParts::Get()->browser();
|
||||
}
|
||||
|
||||
void Browser::Relaunch(const std::vector<std::string>& args,
|
||||
const std::string& app) {
|
||||
base::FilePath exe_path;
|
||||
PathService::Get(base::FILE_EXE, &exe_path);
|
||||
|
||||
std::vector<std::string> args_with_app(args);
|
||||
args_with_app.insert(args_with_app.begin(),
|
||||
app.empty() ? exe_path.value() : app);
|
||||
relauncher::RelaunchApp(args_with_app);
|
||||
}
|
||||
|
||||
void Browser::Quit() {
|
||||
if (is_quiting_)
|
||||
return;
|
||||
|
|
|
@ -8,27 +8,16 @@
|
|||
#include "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void Browser::Relaunch(const std::vector<std::string>& args,
|
||||
const std::string& app) {
|
||||
std::vector<std::string> args_with_app(args);
|
||||
args_with_app.insert(
|
||||
args_with_app.begin(),
|
||||
app.empty() ? brightray::MainApplicationBundlePath().value() : app);
|
||||
relauncher::RelaunchApp(args_with_app);
|
||||
}
|
||||
|
||||
void Browser::Focus() {
|
||||
[[AtomApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
|
|
@ -11,18 +11,24 @@
|
|||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#endif
|
||||
|
||||
namespace relauncher {
|
||||
|
||||
namespace internal {
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
const int kRelauncherSyncFD = STDERR_FILENO + 1;
|
||||
#endif
|
||||
|
||||
const char* kRelauncherTypeArg = "--type=relauncher";
|
||||
const char* kRelauncherArgSeparator = "---";
|
||||
|
||||
|
@ -59,6 +65,7 @@ bool RelaunchAppWithHelper(const std::string& helper,
|
|||
|
||||
relaunch_args.insert(relaunch_args.end(), args.begin(), args.end());
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
int pipe_fds[2];
|
||||
if (HANDLE_EINTR(pipe(pipe_fds)) != 0) {
|
||||
PLOG(ERROR) << "pipe";
|
||||
|
@ -85,9 +92,12 @@ bool RelaunchAppWithHelper(const std::string& helper,
|
|||
base::FileHandleMappingVector fd_map;
|
||||
fd_map.push_back(
|
||||
std::make_pair(pipe_write_fd.get(), internal::kRelauncherSyncFD));
|
||||
#endif
|
||||
|
||||
base::LaunchOptions options;
|
||||
#if defined(OS_POSIX)
|
||||
options.fds_to_remap = &fd_map;
|
||||
#endif
|
||||
if (!base::LaunchProcess(relaunch_args, options).IsValid()) {
|
||||
LOG(ERROR) << "base::LaunchProcess failed";
|
||||
return false;
|
||||
|
@ -96,6 +106,7 @@ bool RelaunchAppWithHelper(const std::string& helper,
|
|||
// The relauncher process is now starting up, or has started up. The
|
||||
// original parent process continues.
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
pipe_write_fd.reset(); // close(pipe_fds[1]);
|
||||
|
||||
// Synchronize with the relauncher process.
|
||||
|
@ -113,6 +124,7 @@ bool RelaunchAppWithHelper(const std::string& helper,
|
|||
// Since a byte has been successfully read from the relauncher process, it's
|
||||
// guaranteed to have set up its kqueue monitoring this process for exit.
|
||||
// It's safe to exit now.
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
74
atom/browser/relauncher_linux.cc
Normal file
74
atom/browser/relauncher_linux.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/relauncher.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/signalfd.h>
|
||||
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/process/launch.h"
|
||||
|
||||
namespace relauncher {
|
||||
|
||||
namespace internal {
|
||||
|
||||
void RelauncherSynchronizeWithParent() {
|
||||
base::ScopedFD relauncher_sync_fd(kRelauncherSyncFD);
|
||||
|
||||
// Don't execute signal handlers of SIGUSR2.
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGUSR2);
|
||||
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
|
||||
PLOG(ERROR) << "sigprocmask";
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a signalfd that watches for SIGUSR2.
|
||||
int usr2_fd = signalfd(-1, &mask, 0);
|
||||
if (usr2_fd < 0) {
|
||||
PLOG(ERROR) << "signalfd";
|
||||
return;
|
||||
}
|
||||
|
||||
// Send SIGUSR2 to current process when parent process ends.
|
||||
if (HANDLE_EINTR(prctl(PR_SET_PDEATHSIG, SIGUSR2)) != 0) {
|
||||
PLOG(ERROR) << "prctl";
|
||||
return;
|
||||
}
|
||||
|
||||
// Write a '\0' character to the pipe.
|
||||
if (HANDLE_EINTR(write(relauncher_sync_fd.get(), "", 1)) != 1) {
|
||||
PLOG(ERROR) << "write";
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait the SIGUSR2 signal to happen.
|
||||
struct signalfd_siginfo si;
|
||||
HANDLE_EINTR(read(usr2_fd, &si, sizeof(si)));
|
||||
}
|
||||
|
||||
int LaunchProgram(const std::vector<std::string>& relauncher_args,
|
||||
const std::string& program,
|
||||
const std::vector<std::string>& args) {
|
||||
std::vector<std::string> argv;
|
||||
argv.reserve(1 + args.size());
|
||||
argv.push_back(program);
|
||||
argv.insert(argv.end(), args.begin(), args.end());
|
||||
|
||||
base::LaunchOptions options;
|
||||
options.allow_new_privs = true;
|
||||
options.new_process_group = true; // detach
|
||||
base::Process process = base::LaunchProcess(argv, options);
|
||||
return process.IsValid() ? 0 : 1;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace relauncher
|
|
@ -225,6 +225,7 @@
|
|||
'atom/browser/net/url_request_fetch_job.h',
|
||||
'atom/browser/node_debugger.cc',
|
||||
'atom/browser/node_debugger.h',
|
||||
'atom/browser/relauncher_linux.cc',
|
||||
'atom/browser/relauncher_mac.cc',
|
||||
'atom/browser/relauncher.cc',
|
||||
'atom/browser/relauncher.h',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue