. */ $text = implode(" ", array_slice($argv, 1)); $descriptor = array(0 => array("pipe", "r"),1 => array("pipe", "w"),2 => array("pipe", "w")); $proc = proc_open('bc -l -q', $descriptor, $pipes); if(!is_resource($proc)) { echo"internal calc error - please contact an administrator.\n"; die(); } fwrite($pipes[0], $text."\nquit\n"); $start = time(); $read=array($pipes[1]); $write=NULL; $except=NULL; while(1) { $data = proc_get_status($proc); if(!$data['running']) { $out=""; while(!feof($pipes[1])) { $out .= fgets($pipes[1], 128); } if($out == "") { $out="\0034"; while(!feof($pipes[2])) { $out .= fgets($pipes[2], 128); } $out.=""; } $out=str_replace("\n","",$out); $out=str_replace("\r","",$out); $out=str_replace("\\","",$out); if(strlen($text) > 20) { if(strlen($out) > 450) { echo "output too long (".strlen($out).")\n"; } else { echo "".$text."\n"; echo $out."\n"; } } else { $fout="".$text." = ".$out; if(strlen($fout) > 450) { echo "output too long (".strlen($out).")"; } else { echo $fout."\n"; } } fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($proc); die(); } else { if($start+3 > time()) { usleep(200000); //200ms } else { //TIMEOUT fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); //can't simply use proc_terminate: https://bugs.php.net/bug.php?id=39992 $ppid = $data['pid']; //use ps to get all the children of this process, and kill them $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid $ppid`); foreach($pids as $pid) { if(is_numeric($pid)) { posix_kill($pid, 9); //SIGKILL signal } } proc_close($proc); echo "calculator timeout. (maximum of 3 seconds exceeded)\n"; die(); } } } ?>