#!/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 = ; close(CMD); #release the lock $mutex->release; } } if (&timeout("ping -t tmrprod100", 1, \@output)) { print @output; } else { print "timed out...\n"; }