|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #33781 add "stream_set_timeout" support for pipes
Submitted: 2005-07-20 09:40 UTC Modified: 2022-12-27 18:10 UTC
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: vesely at tana dot it Assigned: bukka (profile)
Status: Assigned Package: Streams related
PHP Version: * OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
Solve the problem:
23 - 19 = ?
Subscribe to this entry?

 [2005-07-20 09:40 UTC] vesely at tana dot it
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

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?


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2005-07-20 14:54 UTC]
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;


	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";
			return $data;
		} else if ($n > 0) {
			$line = fread($pipes[1], 8192);
			if (strlen($line) == 0) {
				/* EOF */
			$data .= $line;
	$stat = proc_get_status($proc);
	if ($stat['signaled']) {
		$data .= "\nTermsig=".$stat['stopsig'];
	$code = proc_close($proc);
	return $data;
 [2005-07-21 08:55 UTC] vesely at tana dot it
I have a couple of notes on that example. The function
attempts to fread 8Kbytes, whilst a positive response from
stream_select only guarantees that 1 byte can be read w/o
blocking. Further, 60 secs is really eons.

I'm using this:

   function guarded_fgets($pipes)
      $line = "";
      $time = 2;
      $c = "c";
      while ($time >= 0 && ord($c) != 10)
         $read = array($pipes[1]);
         while (!feof($read[0]) &&
            ($n = stream_select($read, $w = NULL, $e = NULL, $time)) !== FALSE &&
            $n > 0 &&
            strlen($c = fgetc($read[0])) > 0 &&
            ord($c) != 10)
               $line .= $c;

      if (ord($c) != 10)
         // error handling

      return $line;
 [2011-04-08 21:48 UTC]
-Package: Feature/Change Request +Package: Streams related -Operating System: Unix +Operating System: * -PHP Version: 4.4.0 +PHP Version: *
 [2022-12-27 18:10 UTC]
-Assigned To: +Assigned To: bukka
 [2022-12-27 18:10 UTC]
For the record I just created an issue that should address this problem once implemented: .
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat May 18 09:01:33 2024 UTC