While developing Tzunami (http://tzunami.sourceforge.net for the curious), I found an interesting issue with trying to wrap a timeout around a popen. When there is an uncooperative program in the popen, and a lot of data is being thrown at it, sometimes the Timeout thread locks up totally, along with the rest of my program. What gets exciting is the results are completely dependant on the amount of data thrown at it, as well as the OS, as we will show below: = cut here for sample code from http://profile.sh/hacks/popen- timeout.rb == count = ARGV[0].to_i # try 10,000 here to can it. data = "X" * count f = IO.popen("/usr/bin/tail -f /etc/resolv.conf", 'w') puts "1. popen done, filling with #{count} bytes of data" $timeoutThread = Thread.new do sleep 5 puts "3. Your time has come! You shall be ALRM'd" Process.kill "ALRM", $$ end begin f.puts data puts "2. #{count} bytes of data sent, closing." f.close puts "4. popen closed" rescue SignalException puts "5. Aborted - Caught signal!" rescue SystemCallError puts "5. Error, my pipe probably closed" end $timeoutThread.exit puts "6. Successfully completed. ========================================================= tail -f is just a demo of an 'uncooperative program', ie, one that will never end, no matter how much data we throw at it via stdin. Here is the output of the program, with 1000 as it's argument: -- 1000 byte test --------------------- 1. popen done, filling with 1000 bytes of data search nc.rr.com nameserver 24.93.67.64 nameserver 24.93.67.65 2. 1000 bytes of data sent, closing. 3. Your time has come! You shall be ALRM'd 5. Aborted - Caught signal! 6. Successfully completed. Perfect, no problems. Now, we make it 5000: -- 10000 byte test --------------------- 1. popen done, filling with 10000 bytes of data domain profile.sh nameserver 24.93.67.64 nameserver 24.93.67.65 3. Your time has come! You shall be ALRM'd 5. Aborted - Caught signal! 6. Successfully completed. <LOCK> This I thought was interesting.. it would complete, but ruby would lock up at this point, and never exit. I couldn't reproduce this on FreeBSD 4.4, but definitely reproducible in NetBSD 1.5Y and Darwin 1.4 (the byte values may differ). -- 32000 byte test --------------------- 1. popen done, filling with 30000 bytes of data domain profile.sh nameserver 24.93.67.64 nameserver 24.93.67.65 <LOCK> We lock here at a different point altogether, but lock indeed. Reproducible on FreeBSD (1.6.5), Darwin (1.6.5), NetBSD (1.6.4), but not AIX 4.3.3 (1.6.4) or IRIX 6.5 (1.6.5, but can't test >10k). Strange, eh? / Thomas Stromberg