Bug 1528963 - Attach console before launching child. r=aklotz
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 29 Mar 2019 18:05:03 +0000
changeset 466801 e3bb3f30b313de16b3a8021d37de20dd40c4f307
parent 466800 97f6ade10460b0d2e528418afd52a843acc28cdd
child 466802 7cc45cebde1c57b3fc4a4fa38dfe104061a88aeb
push id35780
push useropoprus@mozilla.com
push dateFri, 29 Mar 2019 21:53:01 +0000
treeherdermozilla-central@414f37afbe07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1528963
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1528963 - Attach console before launching child. r=aklotz Differential Revision: https://phabricator.services.mozilla.com/D23807
browser/app/winlauncher/LauncherProcessWin.cpp
browser/app/winlauncher/moz.build
toolkit/xre/nsAppRunner.h
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsNativeAppSupportWin.cpp
widget/windows/WindowsConsole.cpp
widget/windows/WindowsConsole.h
widget/windows/moz.build
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/CmdLineAndEnvUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/DynamicallyLinkedFunctionPtr.h"
 #include "mozilla/glue/Debug.h"
 #include "mozilla/LauncherResult.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/SafeMode.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/WindowsConsole.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/WinHeaderOnlyUtils.h"
 #include "nsWindowsHelpers.h"
 
 #include <windows.h>
 #include <processthreadsapi.h>
 
 #include "DllBlocklistWin.h"
@@ -214,16 +215,18 @@ Maybe<int> LauncherMain(int& argc, wchar
       imgLoadPol.PreferSystem32Images = 1;
 
       DebugOnly<BOOL> setOk = pSetProcessMitigationPolicy(
           ProcessImageLoadPolicy, &imgLoadPol, sizeof(imgLoadPol));
       MOZ_ASSERT(setOk);
     }
   }
 
+  mozilla::UseParentConsole();
+
   if (!SetArgv0ToFullBinaryPath(argv)) {
     HandleLauncherError(LAUNCHER_ERROR_GENERIC());
     return Nothing();
   }
 
   LauncherFlags flags = ProcessCmdLine(argc, argv);
 
   nsAutoHandle mediumIlToken;
--- a/browser/app/winlauncher/moz.build
+++ b/browser/app/winlauncher/moz.build
@@ -26,13 +26,14 @@ OS_LIBS += [
 
 TEST_DIRS += [
     'test',
 ]
 
 if CONFIG['MOZ_LAUNCHER_PROCESS']:
     UNIFIED_SOURCES += [
         '/toolkit/xre/LauncherRegistryInfo.cpp',
+        '/widget/windows/WindowsConsole.cpp',
     ]
     for var in ('MOZ_APP_BASENAME', 'MOZ_APP_VENDOR'):
         DEFINES[var] = '"%s"' % CONFIG[var]
 
 DisableStlWrapping()
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAppRunner_h__
 #define nsAppRunner_h__
 
 #ifdef XP_WIN
 #  include <windows.h>
+#  include "mozilla/WindowsConsole.h"
 #else
 #  include <limits.h>
 #endif
 
 #ifndef MAXPATHLEN
 #  ifdef PATH_MAX
 #    define MAXPATHLEN PATH_MAX
 #  elif defined(_MAX_PATH)
@@ -95,17 +96,16 @@ void OverrideDefaultLocaleIfNeeded();
 
 /**
  * Allow exit() calls to complete. This should be done from a proper Gecko
  * shutdown path. Otherwise we aim to catch improper shutdowns.
  */
 void MozExpectedExit();
 
 #ifdef XP_WIN
-void UseParentConsole();
 
 BOOL WinLaunchChild(const wchar_t* exePath, int argc, char** argv,
                     HANDLE userToken = nullptr, HANDLE* hProcess = nullptr);
 
 #  define PREF_WIN_REGISTER_APPLICATION_RESTART \
     "toolkit.winRegisterApplicationRestart"
 
 #  if defined(MOZ_LAUNCHER_PROCESS)
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -75,16 +75,19 @@
 
 #include "mozilla/plugins/PluginProcessChild.h"
 #include "mozilla/dom/ContentProcess.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/XPCShellEnvironment.h"
+#if defined(XP_WIN)
+#  include "mozilla/WindowsConsole.h"
+#endif
 #include "mozilla/WindowsDllBlocklist.h"
 
 #include "GMPProcessChild.h"
 #include "mozilla/gfx/GPUProcessImpl.h"
 #include "mozilla/net/SocketProcessImpl.h"
 
 #include "GeckoProfiler.h"
 
@@ -376,29 +379,17 @@ nsresult XRE_InitChildProcess(int aArgc,
 
 #if defined(XP_WIN)
   // From the --attach-console support in nsNativeAppSupportWin.cpp, but
   // here we are a content child process, so we always attempt to attach
   // to the parent's (ie, the browser's) console.
   // Try to attach console to the parent process.
   // It will succeed when the parent process is a command line,
   // so that stdio will be displayed in it.
-  if (AttachConsole(ATTACH_PARENT_PROCESS)) {
-    // Change std handles to refer to new console handles.
-    // Before doing so, ensure that stdout/stderr haven't been
-    // redirected to a valid file
-    if (_fileno(stdout) == -1 || _get_osfhandle(fileno(stdout)) == -1)
-      freopen("CONOUT$", "w", stdout);
-    // Merge stderr into CONOUT$ since there isn't any `CONERR$`.
-    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
-    if (_fileno(stderr) == -1 || _get_osfhandle(fileno(stderr)) == -1)
-      freopen("CONOUT$", "w", stderr);
-    if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1)
-      freopen("CONIN$", "r", stdin);
-  }
+  UseParentConsole();
 
 #  if defined(MOZ_SANDBOX)
   if (aChildData->sandboxTargetServices) {
     SandboxTarget::Instance()->SetTargetServices(
         aChildData->sandboxTargetServices);
   }
 #  endif
 #endif
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -1,18 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNativeAppSupportBase.h"
 #include "nsNativeAppSupportWin.h"
 
-#include <windows.h>
-#include <fcntl.h>
+#include "mozilla/WindowsConsole.h"
 
 using namespace mozilla;
 
 /*
  * This code attaches the process to the appropriate console.
  */
 
 class nsNativeAppSupportWin : public nsNativeAppSupportBase {
@@ -21,35 +20,16 @@ class nsNativeAppSupportWin : public nsN
   // option: "--console", which dynamically creates a Windows
   // console.
   void CheckConsole();
 
  private:
   ~nsNativeAppSupportWin() {}
 };  // nsNativeAppSupportWin
 
-void UseParentConsole() {
-  if (AttachConsole(ATTACH_PARENT_PROCESS)) {
-    // Redirect the standard streams to the existing console, but
-    // only if they haven't been redirected to a valid file.
-    // Visual Studio's _fileno() returns -2 for the standard
-    // streams if they aren't associated with an output stream.
-    if (_fileno(stdout) == -2) {
-      freopen("CONOUT$", "w", stdout);
-    }
-    // There is no CONERR$, so use CONOUT$ for stderr as well.
-    if (_fileno(stderr) == -2) {
-      freopen("CONOUT$", "w", stderr);
-    }
-    if (_fileno(stdin) == -2) {
-      freopen("CONIN$", "r", stdin);
-    }
-  }
-}
-
 void nsNativeAppSupportWin::CheckConsole() {
   for (int i = 1; i < gArgc; ++i) {
     if (strcmp("-console", gArgv[i]) == 0 ||
         strcmp("--console", gArgv[i]) == 0 ||
         strcmp("/console", gArgv[i]) == 0) {
       if (AllocConsole()) {
         // Redirect the standard streams to the new console, but
         // only if they haven't been redirected to a valid file.
copy from toolkit/xre/nsNativeAppSupportWin.cpp
copy to widget/windows/WindowsConsole.cpp
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/widget/windows/WindowsConsole.cpp
@@ -1,36 +1,21 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsNativeAppSupportBase.h"
-#include "nsNativeAppSupportWin.h"
+#include "WindowsConsole.h"
 
 #include <windows.h>
 #include <fcntl.h>
 
-using namespace mozilla;
-
-/*
- * This code attaches the process to the appropriate console.
- */
+namespace mozilla {
 
-class nsNativeAppSupportWin : public nsNativeAppSupportBase {
- public:
-  // Utility function to handle a Win32-specific command line
-  // option: "--console", which dynamically creates a Windows
-  // console.
-  void CheckConsole();
-
- private:
-  ~nsNativeAppSupportWin() {}
-};  // nsNativeAppSupportWin
-
+// This code attaches the process to the appropriate console.
 void UseParentConsole() {
   if (AttachConsole(ATTACH_PARENT_PROCESS)) {
     // Redirect the standard streams to the existing console, but
     // only if they haven't been redirected to a valid file.
     // Visual Studio's _fileno() returns -2 for the standard
     // streams if they aren't associated with an output stream.
     if (_fileno(stdout) == -2) {
       freopen("CONOUT$", "w", stdout);
@@ -40,50 +25,9 @@ void UseParentConsole() {
       freopen("CONOUT$", "w", stderr);
     }
     if (_fileno(stdin) == -2) {
       freopen("CONIN$", "r", stdin);
     }
   }
 }
 
-void nsNativeAppSupportWin::CheckConsole() {
-  for (int i = 1; i < gArgc; ++i) {
-    if (strcmp("-console", gArgv[i]) == 0 ||
-        strcmp("--console", gArgv[i]) == 0 ||
-        strcmp("/console", gArgv[i]) == 0) {
-      if (AllocConsole()) {
-        // Redirect the standard streams to the new console, but
-        // only if they haven't been redirected to a valid file.
-        // Visual Studio's _fileno() returns -2 for the standard
-        // streams if they aren't associated with an output stream.
-        if (_fileno(stdout) == -2) {
-          freopen("CONOUT$", "w", stdout);
-        }
-        // There is no CONERR$, so use CONOUT$ for stderr as well.
-        if (_fileno(stderr) == -2) {
-          freopen("CONOUT$", "w", stderr);
-        }
-        if (_fileno(stdin) == -2) {
-          freopen("CONIN$", "r", stdin);
-        }
-      }
-    } else if (strcmp("-attach-console", gArgv[i]) == 0 ||
-               strcmp("--attach-console", gArgv[i]) == 0 ||
-               strcmp("/attach-console", gArgv[i]) == 0) {
-      UseParentConsole();
-    }
-  }
-}
-
-// Create and return an instance of class nsNativeAppSupportWin.
-nsresult NS_CreateNativeAppSupport(nsINativeAppSupport **aResult) {
-  nsNativeAppSupportWin *pNative = new nsNativeAppSupportWin;
-  if (!pNative) return NS_ERROR_OUT_OF_MEMORY;
-
-  // Check for dynamic console creation request.
-  pNative->CheckConsole();
-
-  *aResult = pNative;
-  NS_ADDREF(*aResult);
-
-  return NS_OK;
-}
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/windows/WindowsConsole.h
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_WindowsConsole_h
+#define mozilla_WindowsConsole_h
+
+namespace mozilla {
+
+// This code attaches the process to the appropriate console.
+void UseParentConsole();
+
+}  // namespace mozilla
+
+#endif  // mozilla_WindowsConsole_h
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -14,16 +14,17 @@ TEST_DIRS += ['tests']
 
 EXPORTS += [
     'nsdefs.h',
     'WindowHook.h',
     'WinUtils.h',
 ]
 
 EXPORTS.mozilla += [
+    'WindowsConsole.h',
     'WinHeaderOnlyUtils.h',
 ]
 
 EXPORTS.mozilla.widget += [
     'AudioSession.h',
     'CompositorWidgetChild.h',
     'CompositorWidgetParent.h',
     'InProcessWinCompositorWidget.h',
@@ -70,16 +71,17 @@ UNIFIED_SOURCES += [
     'ScreenHelperWin.cpp',
     'TaskbarPreview.cpp',
     'TaskbarPreviewButton.cpp',
     'TaskbarTabPreview.cpp',
     'TaskbarWindowPreview.cpp',
     'WidgetTraceEvent.cpp',
     'WinCompositorWindowThread.cpp',
     'WindowHook.cpp',
+    'WindowsConsole.cpp',
     'WinIMEHandler.cpp',
     'WinPointerEvents.cpp',
     'WinTaskbar.cpp',
     'WinTextEventDispatcherListener.cpp',
     'WinUtils.cpp',
 ]
 
 # The following files cannot be built in unified mode because of name clashes.