diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-10-10 23:26:28 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-10-10 23:26:28 +0200 |
commit | c6ed254d9fda0ff54cdedce5597ff3e0d0218d18 (patch) | |
tree | b57574dea129dce570dc8c9806639801d9400deb /src/if_python3.c | |
parent | bd6428b9e79ed85b54ea7eaa11871fa09d63ab6f (diff) | |
download | vim-git-c6ed254d9fda0ff54cdedce5597ff3e0d0218d18.tar.gz |
patch 8.2.1830: MS-Windows: Python3 issue with stdinv8.2.1830
Problem: MS-Windows: Python3 issue with stdin.
Solution: Check if stdin is readable. (Ken Takata, closes #7106)
Diffstat (limited to 'src/if_python3.c')
-rw-r--r-- | src/if_python3.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/if_python3.c b/src/if_python3.c index f6904c380..e148e53bb 100644 --- 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() |