]> granicus.if.org Git - vim/commitdiff
patch 8.2.1381: MS-Windows: crash with Python 3.5 when stdin is redirected v8.2.1381
authorBram Moolenaar <Bram@vim.org>
Thu, 6 Aug 2020 19:47:11 +0000 (21:47 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 6 Aug 2020 19:47:11 +0000 (21:47 +0200)
Problem:    MS-Windows: crash with Python 3.5 when stdin is redirected.
Solution:   Reconnect stdin. (Yasuhiro Matsumoto, Ken Takata, closes #6641)

src/Make_cyg_ming.mak
src/Make_mvc.mak
src/if_python3.c
src/version.c

index dedc98d7905944478b29cbad8e4a4c85a2a44271..1c519d9b5e53e76a72914ef01eec4135dff63b3b 100644 (file)
@@ -588,6 +588,8 @@ ifdef PYTHON3
 CFLAGS += -DFEAT_PYTHON3
  ifeq (yes, $(DYNAMIC_PYTHON3))
 CFLAGS += -DDYNAMIC_PYTHON3 -DDYNAMIC_PYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
+ else
+CFLAGS += -DPYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
  endif
 endif
 
index 3b72001a80983bcc6d3f49053f7c90e3d72956a2..d66ff717a595c324c58a3ccd3cc17abcc2952ad4 100644 (file)
@@ -1026,6 +1026,9 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
 ! ifndef PYTHON3_VER
 PYTHON3_VER = 36
 ! endif
+! ifndef DYNAMIC_PYTHON3_DLL
+DYNAMIC_PYTHON3_DLL = python$(PYTHON3_VER).dll
+! endif
 ! message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)"
 ! if "$(DYNAMIC_PYTHON3)" == "yes"
 !  message Python3 DLL will be loaded dynamically
@@ -1035,9 +1038,10 @@ PYTHON3_OBJ = $(OUTDIR)\if_python3.obj
 PYTHON3_INC = /I "$(PYTHON3)\Include" /I "$(PYTHON3)\PC"
 ! if "$(DYNAMIC_PYTHON3)" == "yes"
 CFLAGS = $(CFLAGS) -DDYNAMIC_PYTHON3 \
-               -DDYNAMIC_PYTHON3_DLL=\"python$(PYTHON3_VER).dll\"
+               -DDYNAMIC_PYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
 PYTHON3_LIB = /nodefaultlib:python$(PYTHON3_VER).lib
 ! else
+CFLAGS = $(CFLAGS) -DPYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
 PYTHON3_LIB = $(PYTHON3)\libs\python$(PYTHON3_VER).lib
 ! endif
 !endif
index 843fa079f1eee26de8dd78bf589d53171c8a6e61..214ba29830e72c4497577660baf6ecea195b277f 100644 (file)
@@ -907,6 +907,47 @@ 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 CONIN$.
+// Note that the python DLL is linked to its own stdio DLL which can be
+// differ from Vim's stdio.
+    static void
+reset_stdin(void)
+{
+    FILE *(*py__acrt_iob_func)(unsigned) = NULL;
+    FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL;
+    HINSTANCE hinst;
+
+# ifdef DYNAMIC_PYTHON3
+    hinst = hinstPy3;
+# else
+    hinst = GetModuleHandle(PYTHON3_DLL);
+# endif
+    if (hinst == NULL)
+       return;
+
+    // Get "freopen" and "stdin" which are used in the python DLL.
+    // "stdin" is defined as "__acrt_iob_func(0)" in VC++ 2015 or later.
+    py__acrt_iob_func = get_dll_import_func(hinst, "__acrt_iob_func");
+    if (py__acrt_iob_func)
+    {
+       HINSTANCE hpystdiodll = find_imported_module_by_funcname(hinst,
+                                                       "__acrt_iob_func");
+       if (hpystdiodll)
+           pyfreopen = (void*)GetProcAddress(hpystdiodll, "freopen");
+    }
+
+    // Reconnect stdin to CONIN$.
+    if (pyfreopen)
+       pyfreopen("CONIN$", "r", py__acrt_iob_func(0));
+    else
+       freopen("CONIN$", "r", stdin);
+}
+#else
+# define reset_stdin()
+#endif
+
     static int
 Python3_Init(void)
 {
@@ -939,6 +980,7 @@ Python3_Init(void)
 
        PyImport_AppendInittab("vim", Py3Init_vim);
 
+       reset_stdin();
        Py_Initialize();
 
        // Initialise threads, and below save the state using
index 3b5fedc9045a0f8652ba48d4ad3e4135a1bf7d58..3d7c5b129bf78bbe705c04fc5cef8ef73c94866f 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1381,
 /**/
     1380,
 /**/