Solved

eval

Posted on 2008-11-01
12
899 Views
Last Modified: 2012-05-05
the following script properly timesout in unix but not in windows OS  (both have perl 5.10)

eval
{
  $SIG{ALRM} = sub { die "timeout" } ;
  alarm 2;
  `perl -e "while (1) {}"`;
  alarm 0;
};
alarm 0;
if ($@)
{
  print "Error = $@";
}


However if i replace   `perl -e "while (1) {}"`;  with  sleep 10
then it works in windows. somehow it doesn't like when the command is executed with backticks  on windows
0
Comment
Question by:shahkinjal
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
  • +2
12 Comments
 
LVL 43

Expert Comment

by:ravenpl
ID: 22860659
Yes, it looks like You right. Though I don't know why it happens so, I verified that using system() instead of backticks works.
0
 
LVL 6

Expert Comment

by:Talmash
ID: 22861197
Idles / timeouts are offtenly OS dependant.

use
if (OS == windows) {
  1st syntax
} else {
 2nd syntax
}

years ago, I used this dummy solution, without messing with couple of OS types

tal
0
 

Author Comment

by:shahkinjal
ID: 22862396
I tried the following (it timeout correctly if my cmd is perl -e sleep 10  but if my command is "perl -v", the output is directly printed to STDOUT . The variable $out is empty which i m printing in the end

$cmd = "perl -v";

eval
{
  $SIG{ALRM} = sub { die "timeout" } ;
  alarm 2;
   $rc = system ("$cmd") ;
   $out = <STDOUT>;

  alarm 0;
};
alarm 0;
if ($@)
{
  print "Error = $@";
}

print "OUT = $out";
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 43

Expert Comment

by:ravenpl
ID: 22862402
You cannot
 $out = <STDOUT>;
STDOUT will always give You EOF(it's output only) - that's why the variable is empty.
0
 

Author Comment

by:shahkinjal
ID: 22862464
so how can i timeout in windows at the same time return me output if the command does not times out
0
 
LVL 43

Expert Comment

by:ravenpl
ID: 22862476
I'm not following, but did You wanted

>   $rc = system ("$cmd") ;
>   $out = <STDOUT>;

   open(SUB, "$cmd |") ;
   $out = <SUB>;
   close(SUB);
0
 

Author Comment

by:shahkinjal
ID: 22862481
This works fine. it return me output and code

$cmd = "perl -v";
eval
{
  $SIG{ALRM} = sub { die "timeout" } ;
  alarm 2;

  open OUT, "$cmd |" or die "$cmd $!";
  @output = <OUT>;
  close OUT;
  $status = $?;
  alarm 0;
};
alarm 0;
if ($@)
{
  print "Error = $@";
}

print "output = @output \n";
print "code = $status \n";



but this does not time out

$cmd = "perl -e sleep 15";

eval
{
  $SIG{ALRM} = sub { die "timeout" } ;
  alarm 2;

  open OUT, "$cmd |" or die "$cmd $!";
  @output = <OUT>;
  close OUT;
  $status = $?;
  alarm 0;
};
alarm 0;
if ($@)
{
  print "Error = $@";
}

print "output = @output \n";
print "code = $status \n";
0
 

Author Comment

by:shahkinjal
ID: 22862489
if alarm does not work is there any other alternative way to timeout on windows if the command is executed using backticks
0
 
LVL 39

Expert Comment

by:Adam314
ID: 22864015
Although I'm not certain, I'm guessing the alarm signal is going to the child, not your process.  You could try something like:

eval {
  my $start = time();
  my $output = '';
  open OUT, "$cmd |" or die "$cmd $!";
  local $/;
  while(<OUT>) {
    $output .= $_ ;
    die "Timeout\n" if (time() - $start > 2);
  }
  close OUT;
}

With this, you will only have the possibility of timing out whenever the program outputs some data.  So, if you ran "perl -e sleep 10", this would not timeout.  But if the program you want to timeout outputs some data regularly, this might work.

The other thing you could do is create a new child thread, and run the program in the child.  Then you could terminate that thread after the timeout.  I haven't tested this in windows though...
0
 
LVL 8

Expert Comment

by:jhurst
ID: 22872569
Windows is not a real operating system in may respects.  Perl simulates the aspects associated with threading as well as it can.  You have run afoul of that
0
 

Author Comment

by:shahkinjal
ID: 22873046
threads seems to work but 1 issue:

the following code properly timeout on WINDOWS but the problem is even the script is completed, the while loop is still running in the system background and i have to manually clean it. can i get the process id and kill it in the script itself?

use threads;

my $pid;
my $child_thread = threads->new(\&my_function);

eval
{
      local $SIG{ALRM} = sub { die "timeout" };
      alarm 5;
      while ( $child_thread->is_running() ) { sleep 1; }
      alarm 0;
};
alarm 0;
if ($@)
{   print "Timeout: $@ \n";
    $child_thread->kill('KILL')->detach();
}

sub my_function
{
   local $SIG{'KILL'} = sub { threads->exit(); };  
   `perl -e "while (1) {}"`;
}
0
 
LVL 39

Accepted Solution

by:
Adam314 earned 500 total points
ID: 22883081
If you use open with |, the return value will be the PID of the process.  With backticks, I don't think there is a way to get the PID.

So to get the PID:
    my $pid_of_new_process = open(my $P, "your_command goes here|");  #Don't forget the pipe at the end

What you'll have to be careful of is that if the command you run has shell meta-characters, perl will pass the command to the shell for processing, and the shell will then start the program.  So the $pid_of_new_process will be the PID of the shell, not your actual program.

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
compress files in RAR using perl 13 94
pipe to sed or perl, please help 5 144
read an xml file in perl 2 86
parse a file and get data out 11 139
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question