Edit report at https://bugs.php.net/bug.php?id=65650&edit=1

 ID:                 65650
 User updated by:    imprec at gmail dot com
 Reported by:        imprec at gmail dot com
 Summary:            Using proc_open with file handles fails on large
                     buffers
 Status:             Open
 Type:               Bug
 Package:            Program Execution
 Operating System:   Irrelevant
 PHP Version:        5.4.19
 Block user comment: N
 Private report:     N

 New Comment:

Update email


Previous Comments:
------------------------------------------------------------------------
[2013-09-10 15:04:25] imprec at gmail dot com

Description:
------------
When using proc_open with file handles instead of pipes (required on Windows, 
because of bug https://bugs.php.net/bug.php?id=51800), when reading large 
outputs,  
the result might not retrieve what's expected.

The problem has been mentioned when compiling large sass files to stdout on 
windows. The output may sometimes be different than the actual output you can 
get 
running the command in console.

The provided script fails 3 times on 5 on windows environment. Nearly everytime 
on 
OSX.

Test script:
---------------
<?php

error_reporting(E_ALL);

$cmd = sprintf('php -r %s', escapeshellarg('fwrite(STDOUT, $in = 
file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);'));    
$stdout = tmpfile();
$stderr = tmpfile();
$descriptors = array(
    array('pipe', 'r'),
    $stdout,
    $stderr,
);
$handles = array(
    $stdout, $stderr
);

$datastdin = str_repeat('*!', 8192*128);

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

fwrite($pipes[0], $datastdin);
fclose($pipes[0]);
unset($pipes[0]);
$read = array();
while ($handles) {
    $status = proc_get_status($process);
    if (!$status['running']) { 
        proc_close($process);
    }
    $h = $handles;
    foreach ($h as $offset => $handle) {
        fseek($handle, isset($read[$offset]) ? strlen($read[$offset]) : 0);
        
        if (!isset($read[$offset])) {
            $read[$offset] = '';
        }
        $read[$offset] .= fread($handle, 8192);
        if (false === $status['running'] && feof($handle)) {
            fclose($handle);
            unset($handles[$offset]);
        }
    }
}

foreach ($read as $r) {
    assert($r === $datastdin);
}

Expected result:
----------------
No errors, assertion is good.

Actual result:
--------------
PHP Warning:  assert(): Assertion failed in C:\symfony\src\Symfony\Component\Pro
cess\bug.php on line 47
PHP Warning:  assert(): Assertion failed in C:\symfony\src\Symfony\Component\Pro
cess\bug.php on line 47


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



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

Reply via email to