#74 [wait] hangs on FreeBSD

open
nobody
None
5
2010-04-18
2010-04-18
Sergei Golovan
No

Hi!

Appears that [wait] hangs on FreeBSD if it waits for a spawned process which writes something to the standard output. The following script

#!/usr/bin/env expect
spawn echo blubb
puts [wait]

just prints something like the following on Linux:

spawn echo blubb
6912 exp6 0 0

but hangs on FreeBSD and can be killed only with SIGKILL.

The initial bugreport was submitted to the Debian bugtracker (for Debian kFreeBSD, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578271\), but the bug is reproducible on a stock FreeBSD system as well. [wait] hangs both in 5.44.1.15 and 5.43.0 versions.

Discussion

  • Sergei Golovan
    Sergei Golovan
    2010-07-29

    It seems that this difference is explained by the different strategies Linux and FreeBSD kernels apply to the exiting child process. Citing Ben Hutchings (from the above Debian bugreport):

    "A pipe normally has a buffer of size 1 page, so a process that writes up to 4K to a pipe will not block while writing, but a process that writes more than 4K will block if nothing reads from the other end of the pipe."

    "Neither kernel kills the child process, but Linux allows it to exit immediately whereas FreeBSD appears to make it block on exit if it has output buffered in a pipe. This behaviour is useful because it guarantees that the parent will receive the child's output and its exit code in the 'right' order. However, I think that either behaviour is acceptable."

    So, this bug can be closed as invalid. Though I think it's worth mentioning in Expect documentation. The following code works fine for both OSes:

    spawn echo blubb
    expect {
    eof {puts [wait]}
    }

    and doesn't depend on the amount of echoed data.