# HG changeset patch # User Bram Moolenaar # Date 1602365404 -7200 # Node ID 48454576b23c761975b3bbecdaa3cb7c9ffa26c6 # Parent 36c3937da44b28b720fbc627be405f56da7c5994 patch 8.2.1830: MS-Windows: Python3 issue with stdin Commit: https://github.com/vim/vim/commit/c6ed254d9fda0ff54cdedce5597ff3e0d0218d18 Author: Bram Moolenaar Date: Sat Oct 10 23:26:28 2020 +0200 patch 8.2.1830: MS-Windows: Python3 issue with stdin Problem: MS-Windows: Python3 issue with stdin. Solution: Check if stdin is readable. (Ken Takata, closes https://github.com/vim/vim/issues/7106) diff --git a/src/if_python3.c b/src/if_python3.c --- a/src/if_python3.c +++ b/src/if_python3.c @@ -908,8 +908,27 @@ python3_loaded(void) static wchar_t *py_home_buf = NULL; #if defined(MSWIN) && (PY_VERSION_HEX >= 0x030500f0) -// Python 3.5 or later will abort inside Py_Initialize() when stdin is -// redirected. Reconnect stdin to NUL. +/* + * Return TRUE if stdin is readable from Python 3. + */ + static BOOL +is_stdin_readable(void) +{ + DWORD mode, eventnum; + struct _stat st; + int fd = fileno(stdin); + HANDLE hstdin = (HANDLE)_get_osfhandle(fd); + + // Check if stdin is connected to the console. + if (GetConsoleMode(hstdin, &mode)) + // Check if it is opened as input. + return GetNumberOfConsoleInputEvents(hstdin, &eventnum); + + return _fstat(fd, &st) == 0; +} + +// Python 3.5 or later will abort inside Py_Initialize() when stdin has +// been closed (i.e. executed by "vim -"). Reconnect stdin to CONIN$. // Note that the python DLL is linked to its own stdio DLL which can be // differ from Vim's stdio. static void @@ -917,7 +936,6 @@ reset_stdin(void) { FILE *(*py__acrt_iob_func)(unsigned) = NULL; FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL; - char *stdin_name = "NUL"; HINSTANCE hinst; # ifdef DYNAMIC_PYTHON3 @@ -925,7 +943,7 @@ reset_stdin(void) # else hinst = GetModuleHandle(PYTHON3_DLL); # endif - if (hinst == NULL) + if (hinst == NULL || is_stdin_readable()) return; // Get "freopen" and "stdin" which are used in the python DLL. @@ -938,14 +956,12 @@ reset_stdin(void) if (hpystdiodll) pyfreopen = (void *)GetProcAddress(hpystdiodll, "freopen"); } - if (isatty(fileno(stdin))) - stdin_name = "CONIN$"; - // Reconnect stdin to NUL or CONIN$. + // Reconnect stdin to CONIN$. if (pyfreopen != NULL) - pyfreopen(stdin_name, "r", py__acrt_iob_func(0)); + pyfreopen("CONIN$", "r", py__acrt_iob_func(0)); else - freopen(stdin_name, "r", stdin); + freopen("CONIN$", "r", stdin); } #else # define reset_stdin() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1830, +/**/ 1829, /**/ 1828,