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()
--- 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,