Mercurial > vim
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 |