To: rancid-discuss
Subject: possible (tcl) hanging fix on linux
Date: Tuesday, August 14, 2001 4:04 PM

disclaimer: i am not at all sure that this is the proper way to fix
this problem (where rancid's *logins hang while collecting info from
devices on linux platforms with tcl8.3* and expect 5.32*) or if it
will have adverse affects on other expect scripts.

what is happening (usually amid write term or show config, cisco-ism
or juniper-ism) is the last chunk of data before the prompt has been
read into the internal ("channel") buffer, expect asks for more data,
but instead of tcl reading from the buffer or checking if the file
descriptor is actually ready for reading, it just calls read() via
expect's ExpInputProc() where it hangs with the router waiting for
input (until the router's session-timeout expires).

i believe this is due to Tcl_WaitForEvent() not differentiating properly
between timeout and "ready_for_read", but i did not unwrap the maze of
callbacks within tcl and don't have time to right now.

the (inefficient) patch below makes sure the filedescriptor is
set non-blocking, so the read will return immediately if the FD
is not ready for reading and thus give the tcl timer functions the
opportunity to timeout an operation (and apparently look at the internal
buffer for more data).  i have no idea why this doesnt happen/affect netbsd.

it works for me with tcl8.3.b2 and expect 5.32.1 on the linux box i have
freewill-access to, or at least do-diffs completed flawlessly 4 times,
whereas before it barely even got out of the gate.  i think this is
RedCrap 6.1 or so...uname says Linux 2.2.16-22, but i'm guessing that's
just the kernel and i'm blissfully unaware of where all the other version
info is hidden.

you'll have to apply this to your expect 5.32.1 source (cd expect-5.32;
patch < patchfile; make install) or apply it manually for more recent
versions.

patch
- - - - - - - - - - - - - c u t  h e r e - - - - - - - - - - - - - -
*** exp_chan.c.FCS	Tue Aug 14 16:55:54 2001
--- exp_chan.c	Tue Aug 14 16:59:25 2001
***************
*** 119,124 ****
--- 119,125 ----
       * nonblocking, the read will never block.
       */

+ fcntl(esPtr->fdin, F_SETFL, O_NONBLOCK);
      bytesRead = read(esPtr->fdin, buf, (size_t) toRead);
      /*printf("ExpInputProc: read(%d,,) = %d\r\n",esPtr->fdin,bytesRead);*/
      if (bytesRead > -1) {

- - - - - - - - - - - - - c u t  h e r e - - - - - - - - - - - - - -