Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: msys
Compiler: gcc
Compilation CFLAGS: -march=nocona -msahf -mtune=generic -O2 -pipe
-D_STATIC_BUILD
uname output: MINGW64_NT-10.0-26200 3.6.5-22c95533.x86_64 2025-10-10 12:02
UTC x86_64 Msys
Machine Type: x86_64-pc-msys

Bash Version: 5.2
Patch Level: 37
Release Status: release

Description:
With the bash in Git for Windows 2.51.1 (an MSYS2 build, MSYS2
runtime 3.6.5, Windows 11), a here-string or here-document whose
expanded text, including the trailing newline, is 65,537 to 65,664
bytes long never reaches its command: the shell blocks forever
writing the document into a pipe. Documents of 65,536 bytes or
fewer, and of 65,665 or more, work.

here_document_to_fd writes the document into a pipe when
document_len <= HEREDOC_PIPESIZE, which defaults to the PIPESIZE
measured at build time. This build behaves as if that value were
65,664, but a pipe on this runtime holds 65,536 bytes. The MSYS2
runtime's fcntl header (from Cygwin's newlib) has no F_GETPIPE_SZ,
so the run-time capacity check is not compiled in, and
heredoc_write blocks, because nothing reads the pipe until the
redirection is complete.

65,664 is 65,536 + 128. builtins/psize.sh runs
"./psize.aux | sleep 3", and psize.aux counts the 128-byte writes
that complete, so it looks as though this runtime lets one more
128-byte write through than a single large write can use. I have
not seen this build's pipesize.h, so that part is inference.

bash 5.3 has the same logic in here_document_to_fd, and MSYS2's
current package is bash 5.3 patch 20, so I expect it is affected
too. I have not tested 5.3, or Cygwin's bash, which I would expect
to behave the same way.

Commit 03e7298d on the devel branch (PIPESIZE_DYNAMIC: make the
pipe's write end nonblocking and fall back to a temporary file
when the write fails) fixes the same kind of failure on macOS.
Defining PIPESIZE_DYNAMIC on Cygwin and MSYS2 hosts may fix this
as well. I have not checked how a nonblocking write larger than
the free space behaves on those runtimes (a short write or EAGAIN).

Repeat-By:
$ printf -v x '%*s' 65535 ''
$ timeout 5 bash -c 'wc -c <<<"$1"' _ "$x"; echo "status $?"
65536
status 0
$ printf -v x '%*s' 65536 ''
$ timeout 5 bash -c 'wc -c <<<"$1"' _ "$x"; echo "status $?"
status 124

65,663 bytes of text also hangs (status 124); 65,664 prints 65665.
A here-document of the same size hangs the same way:

$ printf -v x '%*s' 65600 ''
$ timeout 5 bash -c 'wc -c <<EOF
$1
EOF' _ "$x"; echo "status $?"
status 124

Fix:
Users can set BASH_COMPAT=50, which makes here_document_to_fd use
a temporary file, or keep documents out of that range. A build
can define HEREDOC_PIPESIZE (for example -DHEREDOC_PIPESIZE=65536)
so that the build-time measurement is not used. A lasting fix is
probably not to trust a build-time PIPESIZE on hosts without
F_GETPIPE_SZ, as PIPESIZE_DYNAMIC now does on macOS.
  • here-document... Daryl Watkins via Bug reports for the GNU Bourne Again SHell

Reply via email to