php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75749 pcntl_fork does not duplicate stream_sockets
Submitted: 2017-12-30 22:46 UTC Modified: 2023-02-10 14:18 UTC
From: michaela dot merz at roillofone dot com Assigned: bukka (profile)
Status: No Feedback Package: Streams related
PHP Version: 7.0.26 OS: Linux
Private report: No CVE-ID: None
 [2017-12-30 22:46 UTC] michaela dot merz at roillofone dot com
Description:
------------
Process "A" has a number of open network stream sockets and watches those sockets via stream_select. Some are in "accepted" state (the connection has been established). Process "A" maintains static connections (think IRC) itself while http-connections are passed to pcntl_fork() after being accepted.

Let's say parent process "A" has accepted #23 and #24 . #24 is handled in a daughter process "B". If "B" exits .. or fclose(#23) is called by "B" , the resource #23 in "A" is also terminated. According to the (C-) norm. file descriptors should be copied and closing them in a fork()ed process should not influence the master process. Same should be valid for stream resources.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-12-30 23:13 UTC] fmargaine@php.net
Hi,

Could you provide a reproducible test case?
 [2023-02-10 14:18 UTC] bukka@php.net
-Status: Open +Status: No Feedback -Assigned To: +Assigned To: bukka
 [2023-02-10 14:18 UTC] bukka@php.net
I had a look into this and tried to recreate with the following script:

<?php

$s1 = stream_socket_server('127.0.0.1:8501');
$s2 = stream_socket_server('127.0.0.1:8502');

$conn1 = stream_socket_accept($s1);
$conn2 = stream_socket_accept($s2);

$pid = pcntl_fork();

if ($pid > 0) {
    $read = [$conn1, $conn2];
    $write = $except = null;
    var_dump(stream_select($read, $write, $except, 10));
    sleep(1);
    fwrite($conn1, "parent test conn 1\n");
    fwrite($conn2, "parent test conn 2\n");
    fclose($conn1);
    fclose($conn2);
    echo "Parent ends\n";
} else {
    sleep(1);
    fwrite($conn1, "child test conn 1\n");
    fwrite($conn2, "child test conn 2\n");
    fclose($conn1);
    fclose($conn2);
    echo "Child ends\n";
}


Then I tested that in nc and all worked as expected. It means getting either

Child ends
int(0)
Parent ends

conn1 received:
child test conn 1
parent test conn 1

and conn2 received:
child test conn 2
parent test conn 2

It also worked if I wrote something in one of the child connection. Then the parent result was 
Child ends
int(1)
Parent ends

It means that closing connection in child does not impact in any way the parent connectiont which is expected and works like in C which also matches my expectations when looking to the code.

I think we need the already requested test case for this. I will close this bug with "No Feedback" but feel free to open a new GitHub issue if you still experience the problem. As noted a test script will be required.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC