cygwin 3.3.x: another problem that may be related to pipes
Takashi Yano
takashi.yano@nifty.ne.jp
Mon Nov 15 08:18:11 GMT 2021
On Sun, 14 Nov 2021 20:50:59 +0000 (UTC)
bf wrote:
> I've a shell script that processes several hundred xz-compressed text files with a pipeline of the form:
>
> find . -depth -type f ... -print0 | \
> xargs -0tI @ xzcat -- @ | \
> iconv --byte-subst='�' --unicode-subst='�' --widechar-subst='�' -f MS-ANSI -t UTF-8 -- | \
> grep ... \
> sed ... | \
> sort ... | \
> sort ...
>
> . Since updating to cygwin 3.3.x (but not on cygwin 3.2.x) the script consistently fails when decompressing a portion of the files, resulting in lost data, and error messages of the form:
>
> xzcat: (stdout): Write error: Bad address
Thanks for the report.
I could reproduce your problem and found the cause.
raw_read()/raw_write() in fhandler_pipe.cc seems to need handling
of STATUS_PENDING in nonblocking mode.
I also confirmed the following patch fixes the issue. However, I
am not very sure that this is the right thing.
Corinna, Ken, what do you think?
>From 2261c7d7df0173d2fb6755f6b9ccccf02b27015e Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Mon, 15 Nov 2021 12:30:53 +0900
Subject: [PATCH] Cygwin: pipe: Call CancelIo() if I/O is pending in
nonblocking mode.
- Currently, handling for STATUS_PENDING in raw_read()/raw_write()
in nonblocking mode is missing. This patch fixes the issue.
Addresses:
https://cygwin.com/pipermail/cygwin/2021-November/249910.html
---
winsup/cygwin/fhandler_pipe.cc | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
index 1ebf4de10..0de01befb 100644
--- a/winsup/cygwin/fhandler_pipe.cc
+++ b/winsup/cygwin/fhandler_pipe.cc
@@ -355,6 +355,9 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
else
status = io.Status;
}
+ else if (status == STATUS_PENDING)
+ /* CancelIo() if STATUS_PENDING in nonblocking mode. */
+ CancelIo (get_handle ());
if (isclosed ()) /* A signal handler might have closed the fd. */
{
if (waitret == WAIT_OBJECT_0)
@@ -538,6 +541,9 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
else
status = io.Status;
}
+ else if (status == STATUS_PENDING)
+ /* CancelIo() if STATUS_PENDING in nonblocking mode. */
+ CancelIo (get_handle ());
if (isclosed ()) /* A signal handler might have closed the fd. */
{
if (waitret == WAIT_OBJECT_0)
--
2.33.0
--
Takashi Yano <takashi.yano@nifty.ne.jp>
More information about the Cygwin
mailing list