#33781 [Opn]: add "stream_set_timeout" support for pipes

From: Date: Wed, 20 Jul 2005 12:54:57 +0000
Subject: #33781 [Opn]: add "stream_set_timeout" support for pipes
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-82210@lists.php.net to get a copy of this message
ID: 33781 Updated by: wez@php.net -Summary: Alarm needed for proc_open pipes Reported By: vesely at tana dot it Status: Open Bug Type: Feature/Change Request Operating System: Unix PHP Version: 4.4.0 New Comment: The simple solution is to NOT use fgets() when you're on a deadline, because of the greedy read semantic. Use fread() instead, in conjunction with stream_select() (which is what is used internally to implement the timeout). Here's an example from our test suite: function system_with_timeout($commandline) { $data = ""; $proc = proc_open($commandline, array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ), $pipes, null, null, array("suppress_errors" => true)); if (!$proc) return false; fclose($pipes[0]); while (true) { /* hide errors from interrupted syscalls */ $r = $pipes; $w = null; $e = null; $n = @stream_select($r, $w, $e, 60); if ($n === 0) { /* timed out */ $data .= "\n ** ERROR: process timed out **\n"; proc_terminate($proc); return $data; } else if ($n > 0) { $line = fread($pipes[1], 8192); if (strlen($line) == 0) { /* EOF */ break; } $data .= $line; } } $stat = proc_get_status($proc); if ($stat['signaled']) { $data .= "\nTermsig=".$stat['stopsig']; } $code = proc_close($proc); return $data; } Previous Comments: ------------------------------------------------------------------------ [2005-07-20 09:40:21] vesely at tana dot it Description: ------------ When using the Apache module it is not possible to use pcntl_alarm (why?). OTOH stream_set_timeout does not work on the "pipe" in descriptorspec. Of course, if the program really doesn't know _if_ there is any data to read, it should use stream_select and fgetc in a loop. Frequently enough, the program knows what it is doing and wants to sleep on fgets until data is available on the pipe. If anything goes wrong here, the two processes may hang waiting for each other. Meanwhile, the user angrily reloads the page knocking out yet another Apache's child... "NEEDED: a timeout for stdout pipe, otherwise a fgets on $pipes[1] can lag forever...)" has been for years in http://www.php.net/manual/en/function.proc-open.php#20866 The global script timeout is quite hard to manage from an included function. stream_select and fgets is good but is not bullet-proof. A request for a timer already exists (bug #9676), hence I guess I should ask for some "guarded-pipe" where the select-fgetc loop is coded in C using a time limit that can be set via stream_set_timeout. Is that cool? ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=33781&edit=1

« previous php.bugs (#82210) next »