![electron-roller[bot]](/assets/img/avatar_default.png)
* chore: bump chromium in DEPS to 137.0.7107.0 * chore: bump chromium in DEPS to 137.0.7109.0 * chore: bump chromium in DEPS to 137.0.7111.0 * chore: bump chromium in DEPS to 137.0.7113.0 * 6384240: Remove double-declaration for accessibility on macOS |6384240
* 6422872: Remove unused includes in isolation_info_mojom_traits.h |6422872
* chore: update patches * 6400733: Avoid ipc_message_macros.h usage in some foo_param_traits_macros.h files |6400733
* chore: update patches * 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
* chore: iwyu * refactor: prefer value initialization over memset() From the looks up upstream commits in base/, it looks like memset() could trigger `-Wunsafe-buffer-usage` warnings soon? Value initialization is more C++ish and less error-prone anyway, due to memset()'s easily swappable parameters. * refactor: NotifyIcon::InitIconData() returns a NOTIFYICONDATA This follows F.20 in the C++ Core Guidelines and also removes the need for memset() * 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
remove all uses of: - strcmp() * fixup! 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
* 6433203: Add a PassKey to RegisterDeleteDelegateCallback(). |6433203
* chore: bump chromium in DEPS to 137.0.7115.0 * 6387077: [PermissionOptions] Generalize PermissionRequestDescription |6387077
* chore: update patches * 6387077: [PermissionOptions] Generalize PermissionRequestDescription |6387077
* fix: add pragma for MacSDK unsafe buffers | 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
* chore: bump chromium in DEPS to 137.0.7117.0 * chore: update patches * chore: update filesnames.libcxx.gni * 6431756: Replace SetOwnedByWidget() bool arg with a PassKey. |6431756
* 6387077: [PermissionOptions] Generalize PermissionRequestDescription |6387077
* 6428345: Remove ExtensionService usage from ChromeExtensionRegistrarDelegate |6428345
* 6384315: Migrate extensions_enabled from ExtensionService to Registrar |6384315
* 6428749: [extensions] Refactor ExtensionService for AddNewAndUpdateExtension. |6428749
* chore: bump chromium in DEPS to 137.0.7119.0 * 6440290: corner-shape: support inset shadow |6440290
* 6429230: FSA: Move blocked paths to the PermissionContext class |6429230
* chore: update patches * chore: bump chromium in DEPS to 137.0.7121.0 * chore: update patches * fix: partially revert 6443473: Remove ItemDelete from the Mac version of AppleKeychain |6443473
* fix: update filenames.libcxx.gni * chore: bump chromium in DEPS to 137.0.7123.0 * chore: update patches * chore: "grandfather in" electron views too Lock further access to View::set_owned_by_client() |6448510
* chore: update feat_corner_smoothing_css_rule_and_blink_painting.patch corner-shape: support inset shadow |6440290
* refactor: grandfather in AutofillPopupView as a subclass of WidgetDelegateView Add a PassKey for std::make_unique<WidgetDelegateView>() |6442265
* Provide dbus appmenu information on Wayland |6405535
* [extensions] Move OnExtensionInstalled out of ExtensionService. |6443325
* refactor: grandfather in NativeWindowViews for delete callbacks 6433203: Add a PassKey to RegisterDeleteDelegateCallback(). |6433203
* chore: merge the four "grandfather" patches into one * [A11yPerformance] Remove IsAccessibilityAllowed() | 6404386: [A11yPerformance] Remove IsAccessibilityAllowed() |6404386
NB: the changes here are copied from the upstream changes in chrome/browser/ui/webui/accessibility/accessibility_ui.cc * 6420753: [PermissionOptions] Use PermissionDescriptorPtr in PermissionController |6420753
* 6429573: [accessibility] Move mode change out of AccessibilityNotificationWaiter |6429573
* chore: e patches all * 6419936: [win] Change ScreenWin public static methods to virtual |6419936
* 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
remove all uses of: - fprintf() - fputs() - snprintf() - vsnprintf() * fix: size conversion FTBFS on Win * 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
remove all uses of: - wcscpy_s() * 6423410: Enable unsafe buffer warnings for chromium, try #3. |6423410
remove all uses of: - wcsncpy_s() * chore: update mas_avoid_private_macos_api_usage.patch.patch 6394283: Remove double-declaration for accessibility on iOS |6394283
Lots of context shear in this commit but the only interesting part is: -+ return nullptr; ++ return {}; Which is needed because the return type is sometimes not a pointer. * chore: e patches all * chore: disable -Wmacro-redefined warning in electron_main_win.cc * chore: bump chromium in DEPS to 137.0.7123.5 * refactor: patch electron PermissionTypes into blink 6387077: [PermissionOptions] Generalize PermissionRequestDescription |6387077
* chore: e patches all * chore: remove the box_painter_base.cc part of feat_corner_smoothing_css_rule_and_blink_painting.patch as per code review @ https://github.com/electron/electron/pull/46482#pullrequestreview-2777338370 * test: enable window-smaller-than-64x64 test on Linux * chore: bump chromium in DEPS to 137.0.7124.1 * chore: bump chromium in DEPS to 137.0.7125.1 * chore: bump chromium in DEPS to 137.0.7127.3 * 6459201: [Extensions] Remove ExtensionSystem::FinishDelayedInstallationIfReady() |6459201
* 6454796: [Extensions] Move (most) registrar delayed install logic to //extensions |6454796
* chore: bump chromium in DEPS to 137.0.7128.1 * chore: e patches all * chore: node ./script/gen-libc++-filenames.js * [views] Gate DesktopWindowTreeHostWin::window_enlargement_ behind flag Refs6428649
* feat: allow opt-out animated_content_sampler. Refs6438681
* Trigger CI --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: Keeley Hammond <khammond@slack-corp.com> Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: Keeley Hammond <vertedinde@electronjs.org> Co-authored-by: deepak1556 <hop2deep@gmail.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
233 lines
8.1 KiB
C++
233 lines
8.1 KiB
C++
// Copyright (c) 2015 GitHub, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Most code came from: chrome/browser/chrome_browser_main_posix.cc.
|
|
|
|
#include "base/notreached.h"
|
|
#include "shell/browser/electron_browser_main_parts.h"
|
|
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <pthread.h>
|
|
#include <signal.h>
|
|
#include <sys/resource.h>
|
|
#include <unistd.h>
|
|
|
|
#include "base/compiler_specific.h"
|
|
#include "base/debug/leak_annotations.h"
|
|
#include "base/posix/eintr_wrapper.h"
|
|
#include "base/threading/platform_thread.h"
|
|
#include "content/public/browser/browser_task_traits.h"
|
|
#include "shell/browser/browser.h"
|
|
|
|
namespace electron {
|
|
|
|
namespace {
|
|
|
|
// write |ref|'s raw bytes to |fd|.
|
|
template <typename T>
|
|
void WriteValToFd(int fd, const T& ref) {
|
|
base::span<const uint8_t> bytes = base::byte_span_from_ref(ref);
|
|
while (!bytes.empty()) {
|
|
const ssize_t rv = HANDLE_EINTR(write(fd, bytes.data(), bytes.size()));
|
|
RAW_CHECK(rv >= 0);
|
|
const size_t n_bytes_written = rv >= 0 ? static_cast<size_t>(rv) : 0U;
|
|
bytes = bytes.subspan(n_bytes_written);
|
|
}
|
|
}
|
|
|
|
// See comment in |PreEarlyInitialization()|, where sigaction is called.
|
|
void SIGCHLDHandler(int signal) {}
|
|
|
|
// The OSX fork() implementation can crash in the child process before
|
|
// fork() returns. In that case, the shutdown pipe will still be
|
|
// shared with the parent process. To prevent child crashes from
|
|
// causing parent shutdowns, |g_pipe_pid| is the pid for the process
|
|
// which registered |g_shutdown_pipe_write_fd|.
|
|
// See <http://crbug.com/175341>.
|
|
pid_t g_pipe_pid = -1;
|
|
int g_shutdown_pipe_write_fd = -1;
|
|
int g_shutdown_pipe_read_fd = -1;
|
|
|
|
// Common code between SIG{HUP, INT, TERM}Handler.
|
|
void GracefulShutdownHandler(int signal) {
|
|
// Reinstall the default handler. We had one shot at graceful shutdown.
|
|
struct sigaction action = {};
|
|
action.sa_handler = SIG_DFL;
|
|
RAW_CHECK(sigaction(signal, &action, nullptr) == 0);
|
|
|
|
RAW_CHECK(g_pipe_pid == getpid());
|
|
RAW_CHECK(g_shutdown_pipe_write_fd != -1);
|
|
RAW_CHECK(g_shutdown_pipe_read_fd != -1);
|
|
WriteValToFd(g_shutdown_pipe_write_fd, signal);
|
|
}
|
|
|
|
// See comment in |PostCreateMainMessageLoop()|, where sigaction is called.
|
|
void SIGHUPHandler(int signal) {
|
|
RAW_CHECK(signal == SIGHUP);
|
|
GracefulShutdownHandler(signal);
|
|
}
|
|
|
|
// See comment in |PostCreateMainMessageLoop()|, where sigaction is called.
|
|
void SIGINTHandler(int signal) {
|
|
RAW_CHECK(signal == SIGINT);
|
|
GracefulShutdownHandler(signal);
|
|
}
|
|
|
|
// See comment in |PostCreateMainMessageLoop()|, where sigaction is called.
|
|
void SIGTERMHandler(int signal) {
|
|
RAW_CHECK(signal == SIGTERM);
|
|
GracefulShutdownHandler(signal);
|
|
}
|
|
|
|
class ShutdownDetector : public base::PlatformThread::Delegate {
|
|
public:
|
|
explicit ShutdownDetector(
|
|
int shutdown_fd,
|
|
base::OnceCallback<void()> shutdown_callback,
|
|
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
|
|
|
|
// disable copy
|
|
ShutdownDetector(const ShutdownDetector&) = delete;
|
|
ShutdownDetector& operator=(const ShutdownDetector&) = delete;
|
|
|
|
// base::PlatformThread::Delegate:
|
|
void ThreadMain() override;
|
|
|
|
private:
|
|
const int shutdown_fd_;
|
|
base::OnceCallback<void()> shutdown_callback_;
|
|
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
|
};
|
|
|
|
ShutdownDetector::ShutdownDetector(
|
|
int shutdown_fd,
|
|
base::OnceCallback<void()> shutdown_callback,
|
|
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
|
|
: shutdown_fd_(shutdown_fd),
|
|
shutdown_callback_(std::move(shutdown_callback)),
|
|
task_runner_(task_runner) {
|
|
CHECK_NE(shutdown_fd_, -1);
|
|
CHECK(!shutdown_callback_.is_null());
|
|
CHECK(task_runner_);
|
|
}
|
|
|
|
NOINLINE void ExitPosted() {
|
|
// Ensure function isn't optimized away.
|
|
asm("");
|
|
sleep(UINT_MAX);
|
|
}
|
|
|
|
// read |sizeof(T)| raw bytes from |fd| and return the result
|
|
template <typename T>
|
|
[[nodiscard]] std::optional<T> ReadValFromFd(int fd) {
|
|
auto val = T{};
|
|
base::span<uint8_t> bytes = base::byte_span_from_ref(val);
|
|
while (!bytes.empty()) {
|
|
const ssize_t rv = HANDLE_EINTR(read(fd, bytes.data(), bytes.size()));
|
|
if (rv < 0) {
|
|
NOTREACHED() << "Unexpected error: " << strerror(errno);
|
|
}
|
|
if (rv == 0) {
|
|
NOTREACHED() << "Unexpected closure of shutdown pipe.";
|
|
}
|
|
const size_t n_bytes_read = static_cast<size_t>(rv);
|
|
bytes = bytes.subspan(n_bytes_read);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
void ShutdownDetector::ThreadMain() {
|
|
base::PlatformThread::SetName("CrShutdownDetector");
|
|
|
|
const int signal = ReadValFromFd<int>(shutdown_fd_).value_or(0);
|
|
VLOG(1) << "Handling shutdown for signal " << signal << ".";
|
|
|
|
if (!task_runner_->PostTask(FROM_HERE,
|
|
base::BindOnce(std::move(shutdown_callback_)))) {
|
|
// Without a valid task runner to post the exit task to, there aren't many
|
|
// options. Raise the signal again. The default handler will pick it up
|
|
// and cause an ungraceful exit.
|
|
RAW_LOG(WARNING, "No valid task runner, exiting ungracefully.");
|
|
kill(getpid(), signal);
|
|
|
|
// The signal may be handled on another thread. Give that a chance to
|
|
// happen.
|
|
sleep(3);
|
|
|
|
// We really should be dead by now. For whatever reason, we're not. Exit
|
|
// immediately, with the exit status set to the signal number with bit 8
|
|
// set. On the systems that we care about, this exit status is what is
|
|
// normally used to indicate an exit by this signal's default handler.
|
|
// This mechanism isn't a de jure standard, but even in the worst case, it
|
|
// should at least result in an immediate exit.
|
|
RAW_LOG(WARNING, "Still here, exiting really ungracefully.");
|
|
_exit(signal | (1 << 7));
|
|
}
|
|
ExitPosted();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void ElectronBrowserMainParts::HandleSIGCHLD() {
|
|
// We need to accept SIGCHLD, even though our handler is a no-op because
|
|
// otherwise we cannot wait on children. (According to POSIX 2001.)
|
|
struct sigaction action = {};
|
|
action.sa_handler = SIGCHLDHandler;
|
|
CHECK_EQ(sigaction(SIGCHLD, &action, nullptr), 0);
|
|
}
|
|
|
|
void ElectronBrowserMainParts::InstallShutdownSignalHandlers(
|
|
base::OnceCallback<void()> shutdown_callback,
|
|
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
|
|
int pipefd[2];
|
|
int ret = pipe(pipefd);
|
|
if (ret < 0) {
|
|
PLOG(DFATAL) << "Failed to create pipe";
|
|
return;
|
|
}
|
|
g_pipe_pid = getpid();
|
|
g_shutdown_pipe_read_fd = pipefd[0];
|
|
g_shutdown_pipe_write_fd = pipefd[1];
|
|
#if !defined(ADDRESS_SANITIZER)
|
|
const size_t kShutdownDetectorThreadStackSize = PTHREAD_STACK_MIN * 2;
|
|
#else
|
|
// ASan instrumentation bloats the stack frames, so we need to increase the
|
|
// stack size to avoid hitting the guard page.
|
|
const size_t kShutdownDetectorThreadStackSize = PTHREAD_STACK_MIN * 4;
|
|
#endif
|
|
ShutdownDetector* detector = new ShutdownDetector(
|
|
g_shutdown_pipe_read_fd, std::move(shutdown_callback), task_runner);
|
|
|
|
// PlatformThread does not delete its delegate.
|
|
ANNOTATE_LEAKING_OBJECT_PTR(detector);
|
|
if (!base::PlatformThread::CreateNonJoinable(kShutdownDetectorThreadStackSize,
|
|
detector)) {
|
|
LOG(DFATAL) << "Failed to create shutdown detector task.";
|
|
}
|
|
// Setup signal handlers for shutdown AFTER shutdown pipe is setup because
|
|
// it may be called right away after handler is set.
|
|
|
|
// If adding to this list of signal handlers, note the new signal probably
|
|
// needs to be reset in child processes. See
|
|
// base/process_util_posix.cc:LaunchProcess.
|
|
|
|
// We need to handle SIGTERM, because that is how many POSIX-based distros
|
|
// ask processes to quit gracefully at shutdown time.
|
|
struct sigaction action = {};
|
|
action.sa_handler = SIGTERMHandler;
|
|
CHECK_EQ(sigaction(SIGTERM, &action, nullptr), 0);
|
|
|
|
// Also handle SIGINT - when the user terminates the browser via Ctrl+C. If
|
|
// the browser process is being debugged, GDB will catch the SIGINT first.
|
|
action.sa_handler = SIGINTHandler;
|
|
CHECK_EQ(sigaction(SIGINT, &action, nullptr), 0);
|
|
|
|
// And SIGHUP, for when the terminal disappears. On shutdown, many Linux
|
|
// distros send SIGHUP, SIGTERM, and then SIGKILL.
|
|
action.sa_handler = SIGHUPHandler;
|
|
CHECK_EQ(sigaction(SIGHUP, &action, nullptr), 0);
|
|
}
|
|
|
|
} // namespace electron
|