I am attempting to deal with the following scenario, and so far my attempts have been unsuccessful.

I want to run a variety of commands, they all should not require user input, but there is a chance one might. Because of this I want to implement a timeout for these calls, so that we don't wait indefinitely.

The most logical way to do this that I see is to fork a process, have that process run the command and monitor the process, if it hasn't returned in X amount of time kill the $pid. But I am running up against a few issues with this, the largest of which is dealing with the sub-process. I am using backticks to actually run the command because I need the output, when I go about killing the forked process, it does not kill the "backticked" sub-proces.

I noticed someone else posted something somewhat similar to what I am seeing, but the solution for that did not work for me.

I have tried the following so far to no avail:

Option 1:

sub _timedFork1 { my ($command, $time) = @_; my @resp1; my $pid; my @pids; local $SIG{ALRM} = sub {kill -15, $pid or die "kill: $!"; die "TIMEOUT!"; }; if ($pid = fork()) { push(@pids, $pid); alarm $time; waitpid($pid, 0); } elsif (defined $pid) { @resp1 = `$command`; return @resp1; exit; } return ($pid, @resp1) }

OPTION 2:

sub _timedFork2 { my ($command, $time) = @_; my $pid; my @resp2; local $SIG{ALRM} = sub {kill 15, $pid or die "kill: $!"; die 'Timeout!'; }; eval { $pid = fork(); unless (defined $pid) { die "Fork failed: $!"; } unless ($pid) { @resp2 = `$command`; } alarm $time; waitpid $pid => 0; }; if ($@ and $@ !~ m/Timeout!/i) { die $@; } return @resp2; }

OPTION 3:

sub _forkFHCommand { my ($command, $time) = @_; my @resp3; my $pid = open COMMAND, "-|", $command or die $!; my $endtime = time() + $time; my $line; while($line = <COMMAND>) { push(@resp3, $line); if (time > $endtime) { kill 15, $pid; last; } } close COMMAND; return (0, @resp3); }

As a note in the $SIG{ALRM}, I tried kill 9, kill -9 and kill 15. None of them worked for me.

I also attempted to do a simple fork function and have the main script sleep for a set amount of time, and then attempt to kill the $pid, this also didn't work out for me.

Essentially the perfect solution would enable me to get back whatever has been returned from the command prior to it being killed. Also, it obviously needs to be able to kill the sub-process.

I am completely open to using threads, but so far my attempts at that have resulted in hangs

So just to summarize the main issue I am having is with processes waiting for input. The _forkFHCommand solution works fine for commands that take a long time but don't require user input (i.e. do a ping -n 100 192.168.1.2 with a timeout of 5 seconds). The other solutions show the same issue of a leftover sub-process regardless if it that sub-process is waiting for input or not.

Any help would be greatly appreciated. Thanks.


In reply to How to deal with a forked proces that is waiting for user input? by gepapa

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.