in reply to Re: SIGINT and system calls
in thread SIGINT and system calls

You monks are great! I am running ActiveState 5.8.6 on Windows. So here's what it translates into:
$SIG{INT}=\&myhand; print "Parent pid = $$ \n"; $pid = open(CMD, "ping google.com -n 15 |"); print "Ping running... pid = $pid \n\n"; # replaces print <CMD>; vec( my $rin, fileno(*CMD), 1) = 1; while (select (my $rd = $rin, undef, undef, undef)) { my $bytes = sysread *CMD, my $buf, 4096; print $buf if 0 < $bytes; } print "I am finished with my task. My results are: \n"; # where are my results stored if I want them in a variable? # print $results; # wait added to lay the zombies sub myhand() { print "Parent $$ caught SIGINT.\n"; print "Parent $$ will KILL $pid.\n"; kill 9, $pid; waitpid $pid, 0; exit 0; }
I am not sure if I completely understand what is happening with the output that you have shown -- it appears to me that it stays in the while loop and I can't get it to "I am finished with my task."

Also, do one of those variables currently have the complete results (of the ping output in this case) or will I need to build a new variable if I want it STDOUT as well as in a variable to pass to another routine later?

Thanks!!

Replies are listed 'Best First'.
Re^3: SIGINT and system calls
by Zaxo (Archbishop) on Jan 20, 2005 at 05:43 UTC

    I'm surprised that that works on windows. Both select and signals are pretty unixy for the windows ports to emulate. I didn't know they could do that at all.

    You're right that I omitted a way out of the while select loop. Probably last if 1 > $bytes; at the end of the loop would do it. I'll edit that into the original.

    Update: Yes, concatenation in the loop would work fine, or if you wanted to get fancy I think you could say,

    my $result; while (select my $rd = $rin, undef, undef, 60) { my $bytes = sysread *CMD, substr($result, -1), 4096; last if 1 > $bytes; }
    Or else you could use the offset argument of sysread to position at the end of $result.

    The 60 second timeout is new, too. Adjust to taste.

    After Compline,
    Zaxo

      That works well to break the loop.

      What about putting the results back into a variable (such as $results)? Do I need to do a concatenation in the while( ... $results .= $buf; ... ) or is there a better way to store the output in a variable?
      print "I am finished with my task. My results are: \n"; # where are my results stored if I want them in a variable? # print $results;

      Thanks again!
      I like the opportunity to get fancy, but I noticed an odd reaction of the sysread(). Using:
      my $result; while (select my $rd = $rin, undef, undef, 60) { my $bytes = sysread *CMD, substr($result, -1), 4096; last if 1 > $bytes; } ... print "I am finished with my task. My results are: \n"; print $result."\n";
      My output is:
      I am finished with my task. My result are: Pinging google.com [216.239.37.99] with 32 bytes of data: Reply from 216.239.37.99:bytes=32 time=36ms TTL=244 Ping statistics for 216.239.37.99: Packets: Sent = 15, Received = 15, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 36ms, Maximum = 37ms, Average = 36ms
      What happened to all of the other lines from the ping (should be 15 result lines)? I would expect it to be:
      I am finished with my task. My result are: Pinging google.com [216.239.37.99] with 32 bytes of data: Reply from 216.239.37.99: bytes=32 time=37ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=36ms TTL=244 Reply from 216.239.37.99: bytes=32 time=37ms TTL=244 Reply from 216.239.37.99: bytes=32 time=37ms TTL=244 Reply from 216.239.37.99: bytes=32 time=37ms TTL=244 Ping statistics for 216.239.37.99: Packets: Sent = 15, Received = 15, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 36ms, Maximum = 37ms, Average = 36ms
      What happens that makes the $result apparently overwrite the output of the *CMD? I would still want to output the live results and set the variable, so would it be best to use the concatenation? I can't print $result in the loop, since that would contain all of the output, not just that loop's progress.

      Also, why is the sysread() length set to 4096. Does that have a significant value?

      Thanks!