Skip to content

Closed STDIN returns endless stream of random data #81

Closed
@clue

Description

@clue

While working on #37, I've tested the following simple and quite common code to check possible combinations of readable/writable streams and closing/ending either side:

$stdout = new Stream(STDOUT, $loop);
$stdout->pause();

$stdin = new Stream(STDIN, $loop);
$stdin->pipe($stdout);

Here's what works as expected:

$ php test.php #interactive STDIO
$ echo test | test.php # STDIN ends once receiving input
$ true | php test.php # STDIN ends immediately
$ php test.php < /dev/null # STDIN ends immediately
$ php test.php < /dev/zero # endless STDIN stream
$ php test.php < /dev/urandom #endless STDIN stream
$ php test.php > /dev/null # STDOUT closes when trying to write, thus pausing STDIN

Here's what does not work (on most of my systems, more below):

$ php test.php <&- # no STDIN should error and/or close
$ php test.php >&- # no STDOUT should error and/or close when trying to write

It turns out explicitly passing no handle actually results in a default stream for all STDIO streams (STDIN, STDOUT and STERR). Arguably, this may be a sane default behavior if this default stream would follow expected behavior for closed streams, but unfortunately it does not.

Unfortunately, this default stream behaves just like an endless stream of random data. In fact, it actually is /dev/urandom. This can be verified by checking /proc/{PID}/fd. And it turns out this is not in fact related to ReactPHP at all and can be reproduced with the most simple PHP scripts.

Here's a very simple gist to reproduce this output:

$ LANG=en php -r 'var_dump(!!fstat(STDIN));passthru("ls -o /proc/".getmypid()."/fd");' <&-

This SHOULD show false (because STDIN is not a valid stream) and SHOULD not include file descriptor 0 in the listing.

Note that I could reproduce this in multiple setups, but have seen other setups where this does not occur. As such, I'm opening this ticket to gather more information on why this happens and how this could possibly be avoided.

Unless I'm missing something obvious, it looks like this may boil down to an issue in PHP itself, but I'd rather collect more evidence first.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions