> 2020-11-30 Bruno Haible <br...@clisp.org> > > execute, spawn-pipe: Make multithread-safe on native Windows.
Oops, there was a mistake in this change: it caused two tests (test-pipe-filter-ii1.sh, test-pipe-filter-gi1.sh) to hang. The hang is a symptom that there is one extra handle left open to a pipe. (The OS knows that a pipe is done when there is no reader or no writer any more.) This patch fixes it. 2020-12-13 Bruno Haible <br...@clisp.org> spawn-pipe: Fix hanging processes on Windows (regression 2020-11-30). * lib/spawn-pipe.c (create_pipe): After spawning the subprocess, close the stdin_handle and/or stdout_handle. diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c index ba07d20..bd34959 100644 --- a/lib/spawn-pipe.c +++ b/lib/spawn-pipe.c @@ -222,6 +222,8 @@ create_pipe (const char *progname, bool must_close_ofd0 = pipe_stdin; /* Create standard file handles of child process. */ + HANDLE stdin_handle = INVALID_HANDLE_VALUE; + HANDLE stdout_handle = INVALID_HANDLE_VALUE; nulloutfd = -1; stdinfd = -1; stdoutfd = -1; @@ -243,7 +245,7 @@ create_pipe (const char *progname, to pass NULL, the child process would inherit a copy of the environment block - ignoring the effects of putenv() and [un]setenv(). */ { - HANDLE stdin_handle = + stdin_handle = (HANDLE) _get_osfhandle (pipe_stdin ? ofd[0] : prog_stdin == NULL ? STDIN_FILENO : stdinfd); if (pipe_stdin) @@ -261,7 +263,7 @@ create_pipe (const char *progname, close (ofd[0]); /* implies CloseHandle (stdin_handle); */ stdin_handle = duplicate; } - HANDLE stdout_handle = + stdout_handle = (HANDLE) _get_osfhandle (pipe_stdout ? ifd[1] : prog_stdout == NULL ? STDOUT_FILENO : stdoutfd); if (pipe_stdout) @@ -306,10 +308,22 @@ create_pipe (const char *progname, if (nulloutfd >= 0) close (nulloutfd); - if (must_close_ofd0) - close (ofd[0]); - if (must_close_ifd1) - close (ifd[1]); + if (pipe_stdin) + { + if (must_close_ofd0) + close (ofd[0]); + else + if (stdin_handle != INVALID_HANDLE_VALUE) + CloseHandle (stdin_handle); + } + if (pipe_stdout) + { + if (must_close_ifd1) + close (ifd[1]); + else + if (stdout_handle != INVALID_HANDLE_VALUE) + CloseHandle (stdout_handle); + } # else /* __KLIBC__ */ if (!(directory == NULL && strcmp (directory, ".") == 0))