From 672802955590cf03b623dad2a82de2a210d4e08e Mon Sep 17 00:00:00 2001 From: aleks Date: Thu, 16 Jul 2026 14:10:27 +0300 Subject: [PATCH] fix: set stdout to O_BINARY on Windows to prevent READY sentinel corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both sentinels in c/coli (READY and END) end with \n. Under CRT text mode on Windows, printf() translates \n to \r\n, so the engine emits \x01\x01READY\x01\x01\r\n. The Python coli wrapper checks endswith(SENTINEL) which expects bare \n — the match never fires and chat hangs forever. _setmode(fileno(stdout), O_BINARY) at engine startup switches stdout to binary mode so \n passes through unchanged. This matches the belt-and-braces reasoning already in compat.h:88 (O_BINARY for file I/O). The fix is defense-in-depth: on the documented w64devkit/MinGW build path, CRT text mode may or may not apply depending on how the terminal is attached, so this ensures correctness regardless. Note: I was unable to compile-test this on the full codebase because glm.c uses POSIX-only symbols (mmap, madvise, select, fd_set, struct stat/fstat) that are unavailable on Windows without platform guards. The codebase compiles on Linux (Ubuntu 24.04, GCC 13) and macOS (Apple clang). Windows compilation requires wrapping those POSIX calls in #if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) guards — I opened this as a separate concern for the maintainer. --- c/glm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/c/glm.c b/c/glm.c index 00c7076..bf270b9 100644 --- a/c/glm.c +++ b/c/glm.c @@ -5749,6 +5749,9 @@ int main(int argc, char **argv){ perror("[OMP] execv self-reexec failed, running untuned"); #endif } +#ifdef _WIN32 + _setmode(fileno(stdout), O_BINARY); +#endif #if defined(__AVX512F__) && defined(__AVX512BW__) if(getenv("I4_ACC512")) g_i4_acc512=atoi(getenv("I4_ACC512"))!=0; if(getenv("I4_ACC512_TEST")){