https://bugs.winehq.org/show_bug.cgi?id=57008
Bug ID: 57008 Summary: _fdopen(0) does not return stdin after it was closed Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: msvcrt Assignee: wine-bugs@winehq.org Reporter: pipcet@protonmail.com Distribution: ---
GNU Emacs contains the following code (abbreviated slightly):
HANDLE stdin_save = INVALID_HANDLE_VALUE; DuplicateHandle (parent, GetStdHandle (STD_INPUT_HANDLE), parent, &stdin_save, 0, FALSE, DUPLICATE_SAME_ACCESS); fclose (stdin); if (stdin_save != INVALID_HANDLE_VALUE) _open_osfhandle ((intptr_t) stdin_save, O_TEXT); else _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY); _fdopen (0, "r");
The idea is that the last call to _fdopen will return stdin, so we can continue using stdin after this code runs, but its HANDLE will have become non-inheritable.
This doesn't work on wine, which allocates a new FILE * in msvcrt_alloc_fp:
for (i = 3; i < MSVCRT_max_streams; i++) { file = msvcrt_get_file(i); if (!file) return NULL;
if (file->_flag == 0) { ... return file; } }
The loop starts at index 3, not 0, so the stdin/stdout/stderr handles are never reused.
Of course, what Emacs does is highly dodgy and not documented to work; apparently, it doesn't work with UCRT on native Windows either. However, there is interest in keeping Emacs usable on very old Windows systems, so it's possible that changing the Emacs code would break things subtly.
Is there any possibility or interest in changing wine so it emulates MSVCRT behavior for this application? Changing "i = 3" to "i = 0" would probably suffice...