spdlog icon indicating copy to clipboard operation
spdlog copied to clipboard

Fix extra carriage returns in piped ANSI output on Windows

Open LowLevelLore opened this issue 6 months ago • 4 comments

Description

This PR fixes incorrect line endings in ANSI-colored output when redirected or piped on Windows terminals. A possible fix for #3138.

Problem

When using fwrite() on Windows, the CRT applies text-mode translation, converting \n to \r\n. This results in an extra carriage return (\r) being injected, especially noticeable when ANSI-colored output is redirected or piped.

Solution

On Windows, replace fwrite() with a direct call to WriteFile() using the native file handle obtained from _get_osfhandle(_fileno(...)). This bypasses the CRT entirely, ensuring output is written exactly as intended, without automatic newline translation.

Code Change

#ifdef _WIN32
    DWORD bytes_written = 0;
    HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(target_file_)));
    // WriteFile bypasses the extra \r injection
    WriteFile(h, color_code.data(), static_cast<DWORD>(color_code.size()), &bytes_written, nullptr);
#else
    // existing fwrite() path
#endif

CMake

Also included ansicolor_sink-inl.h explicitly in the build to avoid linking issues (when linking to static library).

LowLevelLore avatar Jul 18 '25 16:07 LowLevelLore

@gabime any updates / recommendations on this ?

LowLevelLore avatar Jul 22 '25 21:07 LowLevelLore

@gabime Any progress here ?

LowLevelLore avatar Aug 07 '25 20:08 LowLevelLore

The ansicolor sink was never designed for windows. Why not use the wincolor sink

gabime avatar Aug 07 '25 20:08 gabime

New terminal on windows can be set to understand ANSI escape code. https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

flagarde avatar Sep 19 '25 10:09 flagarde