You can use this function system_with_timeout
defined in the "run-tests.php" script, included in the source distribution:
(the key is the last parameter passed to stream_select
)
function system_with_timeout($commandline, $env = null, $stdin = null)
{
global $leak_check, $cwd;
$data = b'';
$bin_env = array();
foreach((array)$env as $key => $value) {
$bin_env[(binary)$key] = (binary)$value;
}
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes, $cwd, $bin_env, array('suppress_errors' => true, 'binary_pipes' => true));
if (!$proc) {
return false;
}
if (!is_null($stdin)) {
fwrite($pipes[0], (binary) $stdin);
}
fclose($pipes[0]);
$timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60);
while (true) {
/* hide errors from interrupted syscalls */
$r = $pipes;
$w = null;
$e = null;
$n = @stream_select($r, $w, $e, $timeout);
if ($n === false) {
break;
} else if ($n === 0) {
/* timed out */
$data .= b"\n ** ERROR: process timed out **\n";
proc_terminate($proc);
return $data;
} else if ($n > 0) {
$line = (binary) fread($pipes[1], 8192);
if (strlen($line) == 0) {
/* EOF */
break;
}
$data .= $line;
}
}
$stat = proc_get_status($proc);
if ($stat['signaled']) {
$data .= b"\nTermsig=" . $stat['stopsig'];
}
$code = proc_close($proc);
return $data;
}
The timeout is given by passing an array like this: array('TEST_TIMEOUT' => 200)
as the second parameter.