If you call interact and there's no input ready right away, it mistakes that for EOF and closes the connection, which isn't what you want, in case more input can come along later.
Here's a fix:
--- a/exp_inter.c
+++ b/exp_inter.c
@@ -1433,7 +1433,7 @@ Exp_InteractObjCmd(
switch (rc) {
case EXP_DATA_NEW:
cc = intRead(interp,u,1,0,key);
- if (cc > 0) break;
+ if (cc > 0 || Tcl_InputBlocked(u->channel)) break;
rc = EXP_EOF;
/*
And here's a contrived way to expose it:
expect -c 'package require tcl::transform::core; oo::class create null {superclass tcl::transform::core; method read {c data} {};}; spawn cat /dev/zero; chan push $spawn_id [null new]; interact;'
I expected the above would run forever (there's no EOF in /dev/zero), and with the above fix it does. But currently version 5.45.3 exits (it gets EOF). What's going on is /dev/zero spews null bytes forever, causing interact to call Tcl_ReadChars, but the transformation (null) discards all input, returning empty string. interact should keep going: The the connection isn't EOF. There never will be any input, but that's different.
In blocking mode, Tcl_ReadChars doesn't return until either 1) it consumes charsToRead of input or 2) EOF (possibly after no input or less than charsToRead of input). Or 3) an error. So in blocking mode, 0 <= ret < charsToRead is always EOF. ret == -1 is in case of an error.
But in non-blocking mode (the case here) it returns after 1) charsToRead of input, 2) EOF, 3) it would block, or 4) an error. Both 2) and 3) are possibly after no input or less than charsToRead of input, so 0 <= ret < charsToRead is either EOF or "would block waiting for more input". ret == -1 is in case of an error, still. The only way to distinguish 2) and 3) is with Tcl_Eof and Tcl_InputBlocked.
The actual case where I encountered this is with a channel transformation that strips ANSI escape sequences. (I need to either strip these sequences or add them to all of my interact patterns, which is a major pain.) The transformation works great! unless a chunk of input contains nothing but escape sequences: Then it returns empty string and interact summarily closes the connection :-P
Hi, thank you for the patch. I will try to create a release witht he fix during this weekend once I have verified it.
Awesome, thank you!
This is now fixed in the expect 5.45.4 release.
This is great, thanks again!