| [reply] [Watch: Dir/Any] |
The sad fact is that I've never seen an easy bulletproof implementation of timing out system/qx/backticks or the equivalent fork/exec implementation, especially if you want to grab output. This
topic is more complex than just slapping in an alarm call, and I don't see how the other suggestion to use Sys::AlarmCall makes any difference (since it appears to time out functions).Your code looks ok to me, but when it times out, you'll need
to kill and reap the child with something like this...
if ($@) {
kill $your_favorite_sig, $pid;
waitpid($pid, 0);
} else {
....
}
Otherwise the child can keep running indefinitely, or if
it does die at some point it will be a zombie.
The most straightforward way of capturing output is to send it to a file and then read the file after the command completes (i.e. use ">tmp_file" as part of your exec). This is a hack, but it is easy and more importantly generally safer than the simpleminded "open a pipe, read the pipe, interrupt the read with an alarm" alternative. The problem with this is it assumes that
interrupting the read with a SIGALARM is always safe. It may theoretically be on all platforms (hopefully yours), but I'm not convinced. Also, what does perl do if the alarm occurs and it happens to be filling in and perhaps reallocating the read in buffer? Since I don't want to depend on knowing and I'm generally paranoid when it comes to signals, I'd expect the program to crash occasionally. If you can handle the crashes, great. If you are like me and don't want to, you have to resort to timing out the individual reads (see the IO::Select "can_read" method), take the easy road of using a separate file, or check out Dominus's answer to my first question to PerlMonks about this topic for another solution. | [reply] [Watch: Dir/Any] [d/l] |
| [reply] [Watch: Dir/Any] [d/l] |