Subject: lang/tcl-expect bug (w/ patch)
To: None <tech-pkg@netbsd.org>
From: john heasley <heas@shrubbery.net>
List: tech-pkg
Date: 08/18/2006 16:06:58
There is a bug that affects expect on solaris and linux.  I think that the
problem is really in TCL, but I've never invested the time to track it down
and the authors haven't either (over 2+ years).

What happens is a bunch of data comes in from the network, the script takes
a portion of it, say up to the first \n, then loops on the expect.  However,
even though there is data in it's input buffer, it tries to read from the
network again in a blocking fashion.  If there is no more input to be had,
it hangs here.

For example, if I have input from a network device like:
line 1
line 2
prompt>
And, all of that input was read at once and I read each line separately,
then after processing line1, expect will hang because the device is waiting
for input from expect [and expect is waiting for the device].

I found the following hack works well.  Would this be acceptable for pkgsrc?
Is it possible to apply patches selectively on an O/S basis?

# expect 5.40

--- exp_chan.c.FCS	Thu Jun  3 20:31:46 2004
+++ exp_chan.c	Fri Jun  4 00:05:03 2004
@@ -109,6 +109,7 @@
     ExpState *esPtr = (ExpState *) instanceData;
     int bytesRead;			/* How many bytes were actually
                                          * read from the input device? */
+struct pollfd fds[1];
 
     *errorCodePtr = 0;
     
@@ -118,6 +119,16 @@
      * possible, if the channel is in blocking mode. If the channel is
      * nonblocking, the read will never block.
      */
+fds[0].fd = esPtr->fdin;
+fds[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
+bytesRead = poll(fds, 1, 0);
+if (bytesRead <= 0) {
+	*errorCodePtr = EWOULDBLOCK;
+	return(-1);
+} else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
+	*errorCodePtr = EBADF;
+	return(-1);
+}
 
     bytesRead = read(esPtr->fdin, buf, (size_t) toRead);
     /*printf("ExpInputProc: read(%d,,) = %d\r\n",esPtr->fdin,bytesRead);*/