php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #54717 stream_set_timeout doesn't work for STDIO streams
Submitted: 2011-05-12 11:23 UTC Modified: 2011-05-16 00:49 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: wuschba at yahoo dot de Assigned:
Status: Open Package: Streams related
PHP Version: 5.3.6 OS: Linux
Private report: No CVE-ID: None
 [2011-05-12 11:23 UTC] wuschba at yahoo dot de
Description:
------------
---
From manual page: http://www.php.net/function.stream-set-timeout#Changelog
---

When open a stream with popen or proc_open, stream_set_timeout or stream_ set_ blocking fail (tested on Linux and Windows), while the manual says:
"As of PHP 4.3, this function can (potentially) work on any kind of stream."
(while 'potentially' of course might mean everything ;-))


Test script:
---------------
$proc[0] = popen("/usr/srv/php /my/folder/myscript.php 0 &", "r"); 
$proc[1] = popen("/usr/srv/php /my/folder/myscript.php 1 &", "r");
if (!stream_set_timeout($proc[0], 1, 0)) print "stream_set_timeout failed on stream 1"; 
if (!stream_set_timeout($proc[1], 1, 0)) print "stream_set_timeout failed on stream 2";


Expected result:
----------------
It should NOT output:
stream_set_timeout failed on stream 1
stream_set_timeout failed on stream 2



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-05-16 00:49 UTC] cataphract@php.net
-Summary: stream_set_timeout and popen don't work together +Summary: stream_set_timeout doesn't work for STDIO streams -Type: Bug +Type: Feature/Change Request
 [2011-05-16 00:49 UTC] cataphract@php.net
I can't reproduce this for stream_set_blocking -- it works as expected:

<?php
$proc = popen("tail -f /var/log/syslog &", "r");
if (!stream_set_blocking($proc, 0))
	print "stream_set_blocking has failed\n";
else
	print "stream_set_blocking successful\n";

$readfds = array($proc);
$writefds = $exceptfds = array();
/* in non-blocking mode, if we don't wait for data with this select,
   the fread will return nothing and the process will close before
   tail can write the data, resulting in "tail: write error: Broken pipe"
   This is expected and shows the non-blocking mode is working */
if (stream_select($readfds, $writefds, $exceptfds, 1))
	echo fread($proc, 8192);

If it still doesn't work for you, please add more information (e.g. an actual script we can run).

For stream_set_timeout, it's true it doesn't work, the read timeout is implemented only for sockets (and user space wrappers). Implementing this for the plain wrapper is risky and the return is small because it can be accomplished in userspace by using non-blocking mode and stream_select. It would imply changing the stream to non-blocking upon each read operation and enforcing the timeout ourselves, like we do for sockets. This makes things less efficient and adds complexity to the code, which leads to bugs (e.g. there was a busy waiting bug in ssl code until the last release), not to mention it would imply completely different code for windows. I'm reclassifying it as a feature request, but don't hold your breath.
 [2011-05-16 17:12 UTC] wuchba at yahoo dot de
Thanks for your fast reply! 

You are right: set_blocking_mode works under Linux. I don't know what I made wrong to find my test-cases not working, so sorry for that!

With set_blocking_mode, I was able implement what I need without using stream_set_timeout, so I guess a feature request is not necessary (at least for my cases).

Perhaps the documentation for stream_set_timeout should be changed to be more specific? It says "As of PHP 4.3, this function can (potentially) work on any kind of stream.", but it should say that the read timeout is implemented only for sockets and that it doesn't work on Windows at all.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC