ID:               34972
 User updated by:  VJTD3 at VJTD3 dot com
 Reported By:      VJTD3 at VJTD3 dot com
 Status:           Assigned
 Bug Type:         Streams related
 Operating System: *
-PHP Version:      5CVS-2005-11-09 (snap)
+PHP Version:      php6.0-200602191730, php5.1-200603270630,
                   php4-STABLE-200603270430 (also in *nix equaliviants)
 Assigned To:      wez
 New Comment:

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?


Previous Comments:
------------------------------------------------------------------------

[2005-11-09 20:58:26] [EMAIL PROTECTED]

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] [EMAIL PROTECTED]

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.

------------------------------------------------------------------------

[2005-10-24 23:07:00] VJTD3 at VJTD3 dot com

Description:
------------
STDIN won't allow nonblocking.

Reproduce code:
---------------
<?php

 stream_set_blocking(STDIN, FALSE);
 while (1) {
  echo 'infinate loop showing nonblocking problem'."\n";
  echo 'said:'.fgets(STDIN, 1024);
 }

?>

Expected result:
----------------
The test code should be a infinate loop with "infinate loop showing
nonblocking problem" said trillions of times fast like a infinate loop
is suposto do when you make a boo boo. instead it will say it once then
wait for input then wait again etc as a blocked resource is expected.
but "stream_set_blocking(STDIN, FALSE);" should be allowing it to do
the loop unblocked resulting in major screen flooding yet unblocking
the resource is ignored.

This means you can't do something like a client program in your shell
that is "interactive" like a Telnet client or similar.

I can dig the whole not reading as typing because that would be too
"raw" for common usage... [ie phrasing the backspaces etc though maybe
a seperate abaility? this would allow arrow key kinda stuff and
similar...] But waiting for a "\n" or whatever file ending shouldn't
have any effect on that loop. It should act just like a TCP or any
other connection when unblocked there the resource just has a return of
no data.

"php -f test.php" I use to run it.

Actual result:
--------------
uses blocking when "stream_set_blocking(STDIN, FALSE);" was used.


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=34972&edit=1

Reply via email to