#61 ExpInputProc should catch ECONNRESET

open
nobody
None
5
2009-03-04
2009-03-04
Ed Attfield
No

We've encountered a problem while using a tcl TCP connection which has been converted to a spawn_id (so that the expect command can be used to parse the output).

I haven't been able to construct a simple test program, and the problem is intermittent, so I'll have to explain it.

Essentially, the exp_chan.c ExpInputProc() should have a few lines added to it so that it looks more like the TcpInputProc in tcl and acts as if it saw an eof.

My versions are expect-5.43, tcl8.4.12, SunOS 5.8.

Simplified expect code would be something like this:

catch {socket $server $port} serverSocket
fconfigure $serverSocket -blocking 1 -buffering line
spawn -noecho -leaveopen $serverSocket
exp_send "exit\r"
expect {
eof {
puts "got eof, and leaving"
return "bleagh"
}
timeout {
puts "timeout on command."
}
-re "prompt:" {
puts "($spawn_id) gave prompt"
}
}

On a random basis, about 1 in 20 tries, the closing TCP connection gets ECONNRESET at the read in ExpInputProc() instead of a nice bytesRead=0. This causes a nasty error exit instead of a call to the eof case.

exp_chan.c ExpInputProc() should have a few lines added to it so that it looks more like the TcpInputProc in tcl:

bytesRead = read(esPtr->fdin, buf, (size_t) toRead);
/*printf("ExpInputProc: read(%d,,) = %d\r\n",esPtr->fdin,bytesRead);*/
if (bytesRead > -1) {
/* strip parity if requested */
if (esPtr->parity == 0) {
char *end = buf+bytesRead;
for (;buf < end;buf++) {
*buf &= 0x7f;
}
}
return bytesRead;
}
else if (errno == ECONNRESET) {
/* Turn ECONNRESET into a soft EOF condition. */
return 0;
}
else {
*errorCodePtr = errno;
return -1;
}

Discussion