php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64438 proc_open hangs with stdin/out with 4097+ bytes
Submitted: 2013-03-16 03:07 UTC Modified: 2014-09-29 14:37 UTC
Votes:3
Avg. Score:4.7 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: hanskrentel at yahoo dot de Assigned: ab (profile)
Status: Closed Package: Filesystem function related
PHP Version: 5.4.13 OS: windows
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hanskrentel at yahoo dot de
New email:
PHP Version: OS:

 

 [2013-03-16 03:07 UTC] hanskrentel at yahoo dot de
Description:
------------
The stream used to read data from stdin/out/err hangs if the data passed is 
getting larger than 4096 (taht is 4097 and above), always. 

Test script:
---------------
error_reporting(E_ALL);

$cmd = 'php -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"';
$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
$stdin = str_repeat('*', 4097);

$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false));
$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);

foreach ($pipes as $pipe) {
    stream_set_blocking($pipe, false);
}
$writePipes = array($pipes[0]);
$stdinLen = strlen($stdin);
$stdinOffset = 0;

unset($pipes[0]);

while ($pipes || $writePipes) {
    $r = $pipes;
    $w = $writePipes;
    $e = null;
    $n = stream_select($r, $w, $e, 60);

    if (false === $n) {
        break;
    } elseif ($n === 0) {
        proc_terminate($process);

    }
    if ($w) {
        $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192);
        if (false !== $written) {
            $stdinOffset += $written;
        }
        if ($stdinOffset >= $stdinLen) {
            fclose($writePipes[0]);
            $writePipes = null;
        }
    }

    foreach ($r as $pipe) {
        $type = array_search($pipe, $pipes);
        $data = fread($pipe, 8192);
        if (false === $data || feof($pipe)) {
            fclose($pipe);
            unset($pipes[$type]);
        }
    }
}

Expected result:
----------------
Process executes in a fraction of a second and finishes with exit code 0

Actual result:
--------------
Process executes and hangs.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-05-05 12:57 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2013-05-05 12:57 UTC] ab@php.net
What do you see when you echo the $data you fread()?
 [2013-05-05 14:59 UTC] ab@php.net
-Status: Feedback +Status: Duplicate
 [2013-05-05 14:59 UTC] ab@php.net
see bug #51800
 [2014-09-29 14:37 UTC] ab@php.net
-Status: Duplicate +Status: Closed -Assigned To: +Assigned To: ab
 [2014-09-29 14:37 UTC] ab@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 04:01:28 2024 UTC