fix: ensure that file descriptors 0/1/2 are opened at startup

This fixes an issue where the gpu subprocess was writing messages to a
random pipe or socket. The standard file desciptors are closed in
chromium's subprocesses because of an unfortunate interaction with
libuv's tty handling code leaving them with the FD_CLOEXEC flag.
This commit is contained in:
Andrzej Szombierski 2018-11-01 00:50:26 +02:00 committed by Electron Bot
parent 6fb569cc6c
commit 1e9a75d9f2

View file

@ -25,9 +25,13 @@
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
#else // defined(OS_LINUX)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_library_main.h"
#endif // defined(OS_MACOSX)
@ -55,6 +59,25 @@ bool IsEnvSet(const char* name) {
}
#endif
#if defined(OS_POSIX)
void FixStdioStreams() {
// libuv may mark stdin/stdout/stderr as close-on-exec, which interferes
// with chromium's subprocess spawning. As a workaround, we detect if these
// streams are closed on startup, and reopen them as /dev/null if necessary.
// Otherwise, an unrelated file descriptor will be assigned as stdout/stderr
// which may cause various errors when attempting to write to them.
//
// For details see https://github.com/libuv/libuv/issues/2062
struct stat st;
if (fstat(STDIN_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "r", stdin);
if (fstat(STDOUT_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stdout);
if (fstat(STDERR_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stderr);
}
#endif
} // namespace
#if defined(OS_WIN)
@ -157,6 +180,8 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
@ -176,6 +201,8 @@ int main(int argc, char* argv[]) {
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
}