comparison src/if_python3.c @ 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 c174ec901f7e
children 0fd4d7548b07
comparison
equal deleted inserted replaced
22562:36c3937da44b 22563:48454576b23c
906 #endif 906 #endif
907 907
908 static wchar_t *py_home_buf = NULL; 908 static wchar_t *py_home_buf = NULL;
909 909
910 #if defined(MSWIN) && (PY_VERSION_HEX >= 0x030500f0) 910 #if defined(MSWIN) && (PY_VERSION_HEX >= 0x030500f0)
911 // Python 3.5 or later will abort inside Py_Initialize() when stdin is 911 /*
912 // redirected. Reconnect stdin to NUL. 912 * Return TRUE if stdin is readable from Python 3.
913 */
914 static BOOL
915 is_stdin_readable(void)
916 {
917 DWORD mode, eventnum;
918 struct _stat st;
919 int fd = fileno(stdin);
920 HANDLE hstdin = (HANDLE)_get_osfhandle(fd);
921
922 // Check if stdin is connected to the console.
923 if (GetConsoleMode(hstdin, &mode))
924 // Check if it is opened as input.
925 return GetNumberOfConsoleInputEvents(hstdin, &eventnum);
926
927 return _fstat(fd, &st) == 0;
928 }
929
930 // Python 3.5 or later will abort inside Py_Initialize() when stdin has
931 // been closed (i.e. executed by "vim -"). Reconnect stdin to CONIN$.
913 // Note that the python DLL is linked to its own stdio DLL which can be 932 // Note that the python DLL is linked to its own stdio DLL which can be
914 // differ from Vim's stdio. 933 // differ from Vim's stdio.
915 static void 934 static void
916 reset_stdin(void) 935 reset_stdin(void)
917 { 936 {
918 FILE *(*py__acrt_iob_func)(unsigned) = NULL; 937 FILE *(*py__acrt_iob_func)(unsigned) = NULL;
919 FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL; 938 FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL;
920 char *stdin_name = "NUL";
921 HINSTANCE hinst; 939 HINSTANCE hinst;
922 940
923 # ifdef DYNAMIC_PYTHON3 941 # ifdef DYNAMIC_PYTHON3
924 hinst = hinstPy3; 942 hinst = hinstPy3;
925 # else 943 # else
926 hinst = GetModuleHandle(PYTHON3_DLL); 944 hinst = GetModuleHandle(PYTHON3_DLL);
927 # endif 945 # endif
928 if (hinst == NULL) 946 if (hinst == NULL || is_stdin_readable())
929 return; 947 return;
930 948
931 // Get "freopen" and "stdin" which are used in the python DLL. 949 // Get "freopen" and "stdin" which are used in the python DLL.
932 // "stdin" is defined as "__acrt_iob_func(0)" in VC++ 2015 or later. 950 // "stdin" is defined as "__acrt_iob_func(0)" in VC++ 2015 or later.
933 py__acrt_iob_func = get_dll_import_func(hinst, "__acrt_iob_func"); 951 py__acrt_iob_func = get_dll_import_func(hinst, "__acrt_iob_func");
936 HINSTANCE hpystdiodll = find_imported_module_by_funcname(hinst, 954 HINSTANCE hpystdiodll = find_imported_module_by_funcname(hinst,
937 "__acrt_iob_func"); 955 "__acrt_iob_func");
938 if (hpystdiodll) 956 if (hpystdiodll)
939 pyfreopen = (void *)GetProcAddress(hpystdiodll, "freopen"); 957 pyfreopen = (void *)GetProcAddress(hpystdiodll, "freopen");
940 } 958 }
941 if (isatty(fileno(stdin))) 959
942 stdin_name = "CONIN$"; 960 // Reconnect stdin to CONIN$.
943
944 // Reconnect stdin to NUL or CONIN$.
945 if (pyfreopen != NULL) 961 if (pyfreopen != NULL)
946 pyfreopen(stdin_name, "r", py__acrt_iob_func(0)); 962 pyfreopen("CONIN$", "r", py__acrt_iob_func(0));
947 else 963 else
948 freopen(stdin_name, "r", stdin); 964 freopen("CONIN$", "r", stdin);
949 } 965 }
950 #else 966 #else
951 # define reset_stdin() 967 # define reset_stdin()
952 #endif 968 #endif
953 969