1*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric 9*06c3fb27SDimitry Andric #include <__config> 10*06c3fb27SDimitry Andric #include <cstdlib> 11*06c3fb27SDimitry Andric #include <print> 12*06c3fb27SDimitry Andric 13*06c3fb27SDimitry Andric #if defined(_LIBCPP_WIN32API) 14*06c3fb27SDimitry Andric # define WIN32_LEAN_AND_MEAN 15*06c3fb27SDimitry Andric # define NOMINMAX 16*06c3fb27SDimitry Andric # include <io.h> 17*06c3fb27SDimitry Andric # include <windows.h> 18*06c3fb27SDimitry Andric 19*06c3fb27SDimitry Andric # include <__system_error/system_error.h> 20*06c3fb27SDimitry Andric 21*06c3fb27SDimitry Andric # include "filesystem/error.h" 22*06c3fb27SDimitry Andric #endif 23*06c3fb27SDimitry Andric 24*06c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 25*06c3fb27SDimitry Andric 26*06c3fb27SDimitry Andric #ifdef _WIN32 27*06c3fb27SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) { 28*06c3fb27SDimitry Andric // Note the Standard does this in one call, but it's unclear whether 29*06c3fb27SDimitry Andric // an invalid handle is allowed when calling GetConsoleMode. 30*06c3fb27SDimitry Andric // 31*06c3fb27SDimitry Andric // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170 32*06c3fb27SDimitry Andric // https://learn.microsoft.com/en-us/windows/console/getconsolemode 33*06c3fb27SDimitry Andric intptr_t __handle = _get_osfhandle(fileno(__stream)); 34*06c3fb27SDimitry Andric if (__handle == -1) 35*06c3fb27SDimitry Andric return false; 36*06c3fb27SDimitry Andric 37*06c3fb27SDimitry Andric unsigned long __mode; 38*06c3fb27SDimitry Andric return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode); 39*06c3fb27SDimitry Andric } 40*06c3fb27SDimitry Andric 41*06c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 42*06c3fb27SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void 43*06c3fb27SDimitry Andric __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wstring_view __view) { 44*06c3fb27SDimitry Andric // https://learn.microsoft.com/en-us/windows/console/writeconsole 45*06c3fb27SDimitry Andric if (WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fileno(__stream))), // clang-format aid 46*06c3fb27SDimitry Andric __view.data(), 47*06c3fb27SDimitry Andric __view.size(), 48*06c3fb27SDimitry Andric nullptr, 49*06c3fb27SDimitry Andric nullptr) == 0) { 50*06c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 51*06c3fb27SDimitry Andric // There is no __throw_system_error overload that takes an error code. 52*06c3fb27SDimitry Andric throw system_error{filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"}; 53*06c3fb27SDimitry Andric # else // _LIBCPP_HAS_NO_EXCEPTIONS 54*06c3fb27SDimitry Andric std::abort(); 55*06c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 56*06c3fb27SDimitry Andric } 57*06c3fb27SDimitry Andric } 58*06c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 59*06c3fb27SDimitry Andric 60*06c3fb27SDimitry Andric #endif // _WIN32 61*06c3fb27SDimitry Andric 62*06c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 63