Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
I am trying to a write a simple subroutine in perl to take a command as argument, execute the command, if the command does not complete with in specified timeout interval, kill the process. If the program got completed within timeout interval, then return its output to the calling routine.
I did it in Unix without any problem, now I am trying to do it in Windows (ActivePerl 5.6.1), but windows does not support alarm functions, so is there a way to achieve it in Windows? The Win32::Process module may not work for me because it does not give the output of the executed program back.
Here is the code I tried doing, it work well but I think I am really messing up with Mutex, so the program says it is timed out but it is not exiting.
Can anyone suggest any correction or a better way to do it...
#!/usr/local/bin/perl # # set alarm signal to die with timeout message use Win32; use Win32::Mutex; use Win32::IPC; use Win32::Process; # timeout by creating a mutex and spawning a child process # let the child lock the mutex first and attempt lock on # the mutex and timeout after $timeout period. The child # should release the mutex upon completion of the command # so if the parent could not get the mutex during timeout # period, then it means the child is still running. Kill # the child and return the status. # if you are able to get the lock on mutex, then it means # the command got completed. The output is available in # the output_ref. sub timeout { my ($cmd, $timeout, $output_ref) = @_; # create a new mutex $mutex = Win32::Mutex->new; if (not defined($pid = fork())) { warn "can not fork: $!\n"; return; } elsif ($pid) { # parent process # wait for some time and request lock on mutex Win32::Sleep(1000); if ($rc = $mutex->wait($timeout * 1000) == 0) { # timed out # kill the child process and return Win32::Process::KillProcess($pid, 0); $mutex->wait(0); $mutex->release; return 0; } elsif ($rc > 0) { # completed Win32::Process::KillProcess($pid, 0); $mutex->release; return 1; } else { # negative value indicates the mutex is abandoned Win32::Process::KillProcess($pid, 0); $mutex->wait(0); $mutex->release; return -1; } } else { # Child process # get a lock on mutex and run the command $mutex->wait(0); open(CMD, "$cmd|") or die "Error running $cmd: $!\n"; @$output_ref = <CMD>; close(CMD); #release the lock $mutex->release; } } if (&timeout("ping -t tmrprod100", 1, \@output)) { print @output; } else { print "timed out...\n"; }
Edit by tye to add READMORE tag
YAE by jeffa to remove colors
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: command execution & timeout in windows
by BrowserUk (Patriarch) on Dec 05, 2002 at 22:31 UTC | |
by Anonymous Monk on Dec 05, 2002 at 23:03 UTC | |
by BrowserUk (Patriarch) on Dec 06, 2002 at 00:04 UTC | |
|
Re: command execution & timeout in windows
by BrowserUk (Patriarch) on Dec 06, 2002 at 19:05 UTC | |
|
Re: command execution & timeout in windows
by Theseus (Pilgrim) on Dec 07, 2002 at 14:57 UTC | |
by jeffa (Bishop) on Dec 08, 2002 at 19:33 UTC | |
by Aristotle (Chancellor) on Dec 08, 2002 at 21:39 UTC |