Skip to content

The resource returned by stream_socket_accept may have incorrect metadata #8472

Closed

Description

@ichaoX

Description

The following code:

<?php

function setNonBlocking($stream)
{
    var_dump($block = stream_get_meta_data($stream)['blocked']);
    if ($block) {
        stream_set_blocking($stream, false);
        var_dump(stream_get_meta_data($stream)['blocked']);
    }
}

$server = stream_socket_server("tcp://127.0.0.1:4321");
setNonBlocking($server);

$client = stream_socket_client("tcp://127.0.0.1:4321");

$res = stream_socket_accept($server);
setNonBlocking($res);
// Removing the following line will cause blocking
// stream_set_blocking($res,false);

fwrite($client,str_repeat('0',5));

var_dump(fread($res,4));
var_dump(fread($res,4));

Resulted in this output:

bool(true)
bool(false)
bool(false)
string(4) "0000"

But I expected this output instead:

bool(true)
bool(false)
bool(true)
bool(false)
string(4) "0000"
string(1) "0"

PHP Version

PHP 8.1.2, PHP 7.4.14

Operating System

Debian

Activity

  1. bwoebi commented on May 2, 2022

    @bwoebi
    Member

    The problem lies within php_tcp_sockop_accept / php_openssl_tcp_sockop_accept which unconditionally inherits the properties from the server socket. I.e. if the server socket is non-blocking, the client socket will be marked non-blocking as well, without actually being non-blocking.

    (This behaviour is different between Linux and Windows/BSD I believe? - according to my unscientific research Windows/BSD are actually inheriting the non-blockingness.)

  2. self-assigned this
    on Aug 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions