Mercurial > vim
changeset 22563:48454576b23c v8.2.1830
patch 8.2.1830: MS-Windows: Python3 issue with stdin
Commit: https://github.com/vim/vim/commit/c6ed254d9fda0ff54cdedce5597ff3e0d0218d18
Author: Bram Moolenaar <Bram@vim.org>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 10 Oct 2020 23:30:04 +0200 |
parents | 36c3937da44b |
children | 2e79e579dd52 |
files | src/if_python3.c src/version.c |
diffstat | 2 files changed, 27 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- 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()