Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Attaches a console for I/O to a Win32 GUI application in a
  4. // reasonably smart fashion
  5. //
  6. //=============================================================================
  7. #include "pch_tier0.h"
  8. #if defined( _WIN32 )
  9. #include <windows.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <iostream>
  13. #endif // defined( _WIN32 )
  14. //-----------------------------------------------------------------------------
  15. //
  16. // Attach a console to a Win32 GUI process and setup stdin, stdout & stderr
  17. // along with the std::iostream (cout, cin, cerr) equivalents to read and
  18. // write to and from that console
  19. //
  20. // 1. Ensure the handle associated with stdio is FILE_TYPE_UNKNOWN
  21. // if it's anything else just return false. This supports cygwin
  22. // style command shells like rxvt which setup pipes to processes
  23. // they spawn
  24. //
  25. // 2. See if the Win32 function call AttachConsole exists in kernel32
  26. // It's a Windows 2000 and above call. If it does, call it and see
  27. // if it succeeds in attaching to the console of the parent process.
  28. // If that succeeds, return false (for no new console allocated).
  29. // This supports someone typing the command from a normal windows
  30. // command window and having the output go to the parent window.
  31. // It's a little funny because a GUI app detaches so the command
  32. // prompt gets intermingled with output from this process
  33. //
  34. // 3. If thigns get to here call AllocConsole which will pop open
  35. // a new window and allow output to go to that window. The
  36. // window will disappear when the process exists so if it's used
  37. // for something like a help message then do something like getchar()
  38. // from stdin to wait for a keypress. if AllocConsole is called
  39. // true is returned.
  40. //
  41. // Return: true if AllocConsole() was used to pop open a new windows console
  42. //
  43. //-----------------------------------------------------------------------------
  44. bool SetupWin32ConsoleIO()
  45. {
  46. #if defined( _WIN32 )
  47. // Only useful on Windows platforms
  48. bool newConsole( false );
  49. if ( GetFileType( GetStdHandle( STD_OUTPUT_HANDLE ) ) == FILE_TYPE_UNKNOWN )
  50. {
  51. HINSTANCE hInst = ::LoadLibrary( "kernel32.dll" );
  52. typedef BOOL ( WINAPI * pAttachConsole_t )( DWORD );
  53. pAttachConsole_t pAttachConsole( ( BOOL ( _stdcall * )( DWORD ) )GetProcAddress( hInst, "AttachConsole" ) );
  54. if ( !( pAttachConsole && (*pAttachConsole)( ( DWORD ) - 1 ) ) )
  55. {
  56. newConsole = true;
  57. AllocConsole();
  58. }
  59. *stdout = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_OUTPUT_HANDLE ) ), _O_TEXT ), "w" );
  60. setvbuf( stdout, NULL, _IONBF, 0 );
  61. *stdin = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_INPUT_HANDLE ) ), _O_TEXT ), "r" );
  62. setvbuf( stdin, NULL, _IONBF, 0 );
  63. *stderr = *_fdopen( _open_osfhandle( reinterpret_cast< intptr_t >( GetStdHandle( STD_ERROR_HANDLE ) ), _O_TEXT ), "w" );
  64. setvbuf( stdout, NULL, _IONBF, 0 );
  65. std::ios_base::sync_with_stdio();
  66. }
  67. return newConsole;
  68. #else // defined( _WIN32 )
  69. return false;
  70. #endif // defined( _WIN32 )
  71. }