Skip to content

Commit c6ed254

Browse files
committed
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 #7106)
1 parent bd6428b commit c6ed254

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/if_python3.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -908,24 +908,42 @@ python3_loaded(void)
908908
static wchar_t *py_home_buf = NULL;
909909

910910
#if defined(MSWIN) && (PY_VERSION_HEX >= 0x030500f0)
911-
// Python 3.5 or later will abort inside Py_Initialize() when stdin is
912-
// redirected. Reconnect stdin to NUL.
911+
/*
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$.
913932
// Note that the python DLL is linked to its own stdio DLL which can be
914933
// differ from Vim's stdio.
915934
static void
916935
reset_stdin(void)
917936
{
918937
FILE *(*py__acrt_iob_func)(unsigned) = NULL;
919938
FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL;
920-
char *stdin_name = "NUL";
921939
HINSTANCE hinst;
922940

923941
# ifdef DYNAMIC_PYTHON3
924942
hinst = hinstPy3;
925943
# else
926944
hinst = GetModuleHandle(PYTHON3_DLL);
927945
# endif
928-
if (hinst == NULL)
946+
if (hinst == NULL || is_stdin_readable())
929947
return;
930948

931949
// Get "freopen" and "stdin" which are used in the python DLL.
@@ -938,14 +956,12 @@ reset_stdin(void)
938956
if (hpystdiodll)
939957
pyfreopen = (void *)GetProcAddress(hpystdiodll, "freopen");
940958
}
941-
if (isatty(fileno(stdin)))
942-
stdin_name = "CONIN$";
943959

944-
// Reconnect stdin to NUL or CONIN$.
960+
// Reconnect stdin to CONIN$.
945961
if (pyfreopen != NULL)
946-
pyfreopen(stdin_name, "r", py__acrt_iob_func(0));
962+
pyfreopen("CONIN$", "r", py__acrt_iob_func(0));
947963
else
948-
freopen(stdin_name, "r", stdin);
964+
freopen("CONIN$", "r", stdin);
949965
}
950966
#else
951967
# define reset_stdin()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
1830,
753755
/**/
754756
1829,
755757
/**/

0 commit comments

Comments
 (0)