For further explanations, see:
R. Gugisch: Konstruktion von Isomorphieklassen orientierter Matroide, Bayreuther Mathematische Schriften 72, Bayreuth, 2005
// Simulate an un-buffered fgets so that istream doesnt // hang there waiting for some input function fgets_u($istream) { $pArr = array($istream); if (false === ($num_changed_streams = stream_select($pArr, $write = NULL, $except = NULL, 0))) { print("\$ 001 Socket Error : UNABLE TO WATCH $istream.\n"); return FALSE; } elseif ($num_changed_streams>0) { return trim(fgets($istream, 1024)); } return FALSE; } function start_origen() { global $process; global $pipes; global $command; $REMOTE_ADDR=getenv('REMOTE_ADDR'); $HTTP_USER_AGENT=getenv('HTTP_USER_AGENT'); $fp=fopen("origen.log","a"); fputs($fp,date("[Y/m/d-H:i:s]")." $REMOTE_ADDR: START: origen $command \t($HTTP_USER_AGENT)\n"); fclose($fp); $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("file", "origen.log", "a") // stderr is a file to write to ); $process = proc_open("$command 2>&1", $descriptorspec, $pipes); } function close_origen() { global $process; global $pipes; fclose($pipes[0]); fclose($pipes[1]); proc_close($process); $REMOTE_ADDR=getenv('REMOTE_ADDR'); $HTTP_USER_AGENT=getenv('HTTP_USER_AGENT'); $fp=fopen("origen.log","a"); fputs($fp,date("[Y/m/d-H:i:s]")." $REMOTE_ADDR: DONE(".connection_status()."): $command \t($HTTP_USER_AGENT)\n"); fclose($fp); } // ************************************************** // main program... flush(); ignore_user_abort(true); start_origen(); if (is_resource($process)) { $start=$time=time(); $i=0; $stop=0; $handle=$pipes[1]; while (!feof($pipes[1])) { if(!$stop) { if(connection_status() || $time-$start>=$TIMEOUT) { $stop=1; fwrite($pipes[0], "C"); // causes origen to interrupt itself. } } if(!($line = fgets_u($pipes[1]))) continue; $i++; echo "$line\n"; $now=time(); if($now!=$time) { echo ""; flush(); $time=$now; } } if(connection_status()) { // output would not reach browser; User should press Cancel button above! } else if($time-$start>=$TIMEOUT) { echo ""; } else { // origen finished regularly // --$i; // last line of output was only a comment echo ""; } close_origen(); } ?>