#34972 [Asn->Fbk]: STDIN won't allow nonblocking.
| From: | jani@php.net | Date: | Tue, 17 Jul 2007 14:28:04 +0000 |
| Subject: | #34972 [Asn->Fbk]: STDIN won't allow nonblocking. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-115146@lists.php.net to get a copy of this message | ||
ID: 34972
Updated by: jani@php.net
Reported By: VJTD3 at VJTD3 dot com
-Status: Assigned
+Status: Feedback
Bug Type: Streams related
Operating System: *
PHP Version: php5.1-200603270630
Assigned To: wez
New Comment:
Please try using this CVS snapshot:
http://snaps.php.net/php5.2-latest.tar.gz
For Windows (zip):
http://snaps.php.net/win32/php5.2-win32-latest.zip
For Windows (installer):
http://snaps.php.net/win32/php5.2-win32-installer-latest.msi
I can't reproduce this (or very likely didn't understand the problem :)
Previous Comments:
------------------------------------------------------------------------
[2006-03-27 14:12:28] VJTD3 at VJTD3 dot com
error in last message, "stream_select()" was ment.
code using "stream_select()" that still blocks:
<?php
set_time_limit('0');
# note for php4 or lower STDIN isn't a defined "constant".
if (version_compare(phpversion(), '5.0.0', '<')) {
define('STDIN', fopen('php://stdin', 'r'));
}
for ($i=1;$i<11;$i++) {
unset($read);
$read[] = STDIN;
stream_select($read, $write = null, $except = null, $tv = 0);
if (count($read)) {
$data4 = @fread(STDIN, 1500);
$data4 = str_replace("\r\n", "\n", $data4);
$data4 = str_replace("\n\r", "\n", $data4);
$data4 = str_replace("\r", "\n", $data4);
$data4 = str_replace("\n", '', $data4);
}
echo 'pass: '.$i.' -> data: '.(strlen(@$data4) ? $data4 :
'empty')."\n";
unset($data4);
sleep('1');
}
?>
the second you type/click a arrow key/anything it goes into blocking
mode again.
------------------------------------------------------------------------
[2006-03-27 13:32:01] VJTD3 at VJTD3 dot com
bug #36030 is very similar to my bug, they might be related.
It looks like anything to STDIN (reguardless of access method like
php://stdin and constant('STDIN') and STDIN are all effected.)
When doing anything, be it select, timeout, or anything to "monitor"
the resource where a window is set (ie to timeout the blocking, set
nonblocking, or similar.) the input "stalls" (it's not really a stall,
it's just waiting for the input.) or fails (such as timeout setting that
fails and returns false.)
Tested on:
php4-STABLE-200603270430
php5.1-200603270630
php6.0-200602191730
Also tested as well on their *nix snaps version and all with the same
result. (blocking when they should not be blocking.)
Better code to make debugging easier and includes examples from
suggestions that don't work:
<?php
set_time_limit('0');
# note for php4 or lower STDIN isn't a defined "constant".
if (version_compare(phpversion(), '5.0.0', '<')) {
define('STDIN', fopen('php://stdin', 'r'));
}
echo 'notice how the data loads unblocked reguardless if there is
data.'."\n";
$demo1 = @fsockopen('yahoo.com', 80, $errno, $errstr, 60);
stream_set_blocking($demo1, FALSE);
fwrite($demo1, 'GET /'."\n\n");
for ($i=1;$i<11;$i++) {
$data1 = @fread($demo1, 1500);
$data1 = str_replace("\r\n", "\n", $data1);
$data1 = str_replace("\n\r", "\n", $data1);
$data1 = str_replace("\r", "\n", $data1);
$data1 = str_replace("\n", '', $data1);
echo 'pass: '.$i.' -> data: '.(strlen($data1) ? $data1 :
'empty')."\n";
sleep('1');
}
echo 'notice how the data loads unblocked and clearly there is no data
because this IP is invalid to connect to.'."\n";
$demo2 = @fsockopen('0.0.0.0', 80, $errno, $errstr, 1);
stream_set_blocking($demo2, FALSE);
for ($i=1;$i<11;$i++) {
# this is expected to be a invalid resource.
$data2 = @fread($demo2, 1500);
$data2 = str_replace("\r\n", "\n", $data2);
$data2 = str_replace("\n\r", "\n", $data2);
$data2 = str_replace("\r", "\n", $data2);
$data2 = str_replace("\n", '', $data2);
echo 'pass: '.$i.' -> data: '.(strlen($data2) ? $data2 :
'empty')."\n";
sleep('1');
}
echo 'a person said to use select, this shows select won\'t work. (and
shouldn\'t it\'s not a socket.) It won\'t even allow input during select
calls.'."\n";
for ($i=1;$i<11;$i++) {
unset($read);
$read[] = STDIN;
socket_select($read, $write = null, $except = null, $tv = 0);
print_r($read);
sleep('1');
}
echo 'same code as yahoo and 0.0.0.0 with fread and blocked
reguardless of setting this to nonblocking.'."\n";
stream_set_blocking(STDIN, FALSE);
for ($i=1;$i<11;$i++) {
echo 'Watch me stall till you type enter I\'m blocking you!'."\n";
$data3 = fread(STDIN, 10);
$data3 = str_replace("\r\n", "\n", $data3);
$data3 = str_replace("\n\r", "\n", $data3);
$data3 = str_replace("\r", "\n", $data3);
$data3 = str_replace("\n", '', $data3);
echo 'pass: '.$i.' -> data: '.(strlen($data3) ? $data3 :
'empty')."\n";
sleep('1');
}
?>
anything I can do to help with details/make the bug easier to fix?
------------------------------------------------------------------------
[2005-11-09 20:58:26] sniper@php.net
Assigned to the streams maintainer.
------------------------------------------------------------------------
[2005-10-25 04:23:31] VJTD3 at VJTD3 dot com
<?php
# Make life easier to test bothe versions
# option:
# 1: Yahoo HTTP example
# 2: STDIN example.
$test = 1;
# note for php4 or lower:
# STDIN isn't a defined "constant" so uncomment this.
#define('STDIN', fopen('php://stdin', 'r'));
# ment to paste fread was playing with other methods and
# just pasted the wrong version. The result is the same.
# notice how after the data is done it's still going and
# not blocked.
if($test == '1') {
$demo = fsockopen('yahoo.com', 80);
stream_set_blocking($demo, FALSE);
fwrite($demo, 'GET /'."\n\n");
while (1) {
$data = fread($demo, 1500);
echo (strlen($data) ? 'read:'.$data :
"\nread:".'empty'."\n");
sleep(1);
}
}
# same code with fread and blocked reguardless of setting
# to nonblocked.
if($test == '2') {
echo 'Watch me stall till you type enter I\'m blocking you!'."\n";
stream_set_blocking(STDIN, FALSE);
while (1) {
$data = fread(STDIN, 10);
# I do know I could use trim, but if blocking was
# working it will act weird if it's mid of a end of
# line.
$data = str_replace("\n", '', $data);
$data = str_replace("\r", '', $data);
echo (strlen($data) ? 'read:'.$data :
"\nread:".'empty'."\n");
sleep(1);
}
}
# stream_select() can't be used, when i try the file
# descriptor just gets locks and all future selects won't
# work. and there is no reason to even select i know what
# resource to monitor i just need blocking to stop so i
# can monitor and process as i need just liek in the
# yahoo http example.
?>
------------------------------------------------------------------------
[2005-10-25 01:26:58] wez@php.net
FYI, using fgets() with a non-blocking resource makes no sense.
To implement what you're after, use stream_select() and fread(); these
work on stdin just fine.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/34972
--
Edit this bug report at http://bugs.php.net/?id=34972&edit=1