From 465fa239eb8f73260379ed0e6c139bab39fd2f94 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 3 Apr 2023 16:37:27 +0000 Subject: Failing test for [9ca87e6286262a62f], Sync fcopy buffers input in ReadChars(). --- tests/io.test | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index 96e5ea6..22b7482 100644 --- a/tests/io.test +++ b/tests/io.test @@ -8276,7 +8276,7 @@ test io-53.11 {Bug 2895565} -setup { removeFile out removeFile in } -result {40 bytes copied} -test io-53.12 {CopyData: foreground short reads, aka bug 3096275} {stdio unix fcopy} { +test io-53.12.0 {CopyData: foreground short reads, aka bug 3096275} {stdio unix fcopy} { file delete $path(pipe) set f1 [open $path(pipe) w] puts -nonewline $f1 { @@ -8295,6 +8295,32 @@ test io-53.12 {CopyData: foreground short reads, aka bug 3096275} {stdio unix fc close $f1 list $::done $ch } {ok A} +test io-53.12.1 { + Issue 9ca87e6286262a62. + CopyData: foreground short reads via ReadChars(). + Related to report 3096275 for ReadBytes(). + + Prior to the fix this test waited forever for read() to return. +} {stdio unix fcopy} { + file delete $path(output) + set f1 [open $path(output) w] + puts -nonewline $f1 { + chan configure stdin -encoding iso8859-1 -translation lf -buffering none + fcopy stdin stdout + } + close $f1 + set f1 [open "|[list [info nameofexecutable] $path(output)]" r+] + try { + chan configure $f1 -encoding utf-6 -buffering none + puts -nonewline $f1 A + set ch [read $f1 1] + } finally { + if {$f1 in [chan names]} { + close $f1 + } + } + lindex $ch +} A test io-53.13 {TclCopyChannel: read error reporting} -setup { proc driver {cmd args} { variable buffer -- cgit v0.12 From 3e6eaa5776cbff53a13c50cbf5592e65307bd6bb Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 3 Apr 2023 17:12:11 +0000 Subject: Fix for [9ca87e6286262a62], sync fcopy buffers input in ReadChars(). --- generic/tclIO.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 287a2f2..73d787a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -196,7 +196,7 @@ static void DiscardOutputQueued(ChannelState *chanPtr); static Tcl_Size DoRead(Channel *chanPtr, char *dst, Tcl_Size bytesToRead, int allowShortReads); static Tcl_Size DoReadChars(Channel *chan, Tcl_Obj *objPtr, Tcl_Size toRead, - int appendFlag); + int allowShortReads, int appendFlag); static int FilterInputBytes(Channel *chanPtr, GetsState *statePtr); static int FlushChannel(Tcl_Interp *interp, Channel *chanPtr, @@ -5899,7 +5899,7 @@ Tcl_ReadChars( return TCL_INDEX_NONE; } - return DoReadChars(chanPtr, objPtr, toRead, appendFlag); + return DoReadChars(chanPtr, objPtr, toRead, 0, appendFlag); } /* *--------------------------------------------------------------------------- @@ -5930,6 +5930,7 @@ DoReadChars( Tcl_Size toRead, /* Maximum number of characters to store, or * TCL_INDEX_NONE to read all available data (up to EOF or * when channel blocks). */ + int allowShortReads, /* Allow half-blocking (pipes,sockets) */ int appendFlag) /* If non-zero, data read from the channel * will be appended to the object. Otherwise, * the data will replace the existing contents @@ -6070,8 +6071,8 @@ DoReadChars( if (GotFlag(statePtr, CHANNEL_EOF)) { break; } - if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) - == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { + if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads) + && GotFlag(statePtr, CHANNEL_BLOCKED)) { break; } result = GetInput(chanPtr); @@ -9762,7 +9763,8 @@ CopyData( !GotFlag(inStatePtr, CHANNEL_NONBLOCKING)); } else { size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, - 0 /* No append */); + !GotFlag(inStatePtr, CHANNEL_NONBLOCKING) + ,0 /* No append */); } underflow = (size >= 0) && ((size_t)size < sizeb); /* Input underflow */ } -- cgit v0.12