2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Process\Pipes ;
use Symfony\Component\Process\Process ;
/**
* UnixPipes implementation uses unix pipes as handles .
*
* @ author Romain Neutron < imprec @ gmail . com >
*
* @ internal
*/
class UnixPipes extends AbstractPipes
{
/** @var bool */
private $ttyMode ;
/** @var bool */
private $ptyMode ;
/** @var bool */
private $disableOutput ;
public function __construct ( $ttyMode , $ptyMode , $input , $disableOutput )
{
$this -> ttyMode = ( bool ) $ttyMode ;
$this -> ptyMode = ( bool ) $ptyMode ;
$this -> disableOutput = ( bool ) $disableOutput ;
2016-04-20 09:56:34 -07:00
parent :: __construct ( $input );
2015-08-17 17:00:26 -07:00
}
public function __destruct ()
{
$this -> close ();
}
/**
* { @ inheritdoc }
*/
public function getDescriptors ()
{
if ( $this -> disableOutput ) {
$nullstream = fopen ( '/dev/null' , 'c' );
return array (
array ( 'pipe' , 'r' ),
$nullstream ,
$nullstream ,
);
}
if ( $this -> ttyMode ) {
return array (
array ( 'file' , '/dev/tty' , 'r' ),
array ( 'file' , '/dev/tty' , 'w' ),
array ( 'file' , '/dev/tty' , 'w' ),
);
}
if ( $this -> ptyMode && Process :: isPtySupported ()) {
return array (
array ( 'pty' ),
array ( 'pty' ),
array ( 'pty' ),
);
}
return array (
array ( 'pipe' , 'r' ),
array ( 'pipe' , 'w' ), // stdout
array ( 'pipe' , 'w' ), // stderr
);
}
/**
* { @ inheritdoc }
*/
public function getFiles ()
{
return array ();
}
/**
* { @ inheritdoc }
*/
public function readAndWrite ( $blocking , $close = false )
{
$this -> unblock ();
2016-04-20 09:56:34 -07:00
$w = $this -> write ();
2015-08-17 17:00:26 -07:00
2016-04-20 09:56:34 -07:00
$read = $e = array ();
$r = $this -> pipes ;
2015-08-17 17:00:26 -07:00
unset ( $r [ 0 ]);
// let's have a look if something changed in streams
2016-04-20 09:56:34 -07:00
if (( $r || $w ) && false === $n = @ stream_select ( $r , $w , $e , 0 , $blocking ? Process :: TIMEOUT_PRECISION * 1E6 : 0 )) {
2015-08-17 17:00:26 -07:00
// if a system call has been interrupted, forget about it, let's try again
// otherwise, an error occurred, let's reset pipes
if ( ! $this -> hasSystemCallBeenInterrupted ()) {
$this -> pipes = array ();
}
return $read ;
}
foreach ( $r as $pipe ) {
// prior PHP 5.4 the array passed to stream_select is modified and
// lose key association, we have to find back the key
2016-04-20 09:56:34 -07:00
$read [ $type = array_search ( $pipe , $this -> pipes , true )] = '' ;
2015-08-17 17:00:26 -07:00
2016-04-20 09:56:34 -07:00
do {
$data = fread ( $pipe , self :: CHUNK_SIZE );
$read [ $type ] .= $data ;
2017-02-02 16:28:38 -08:00
} while ( isset ( $data [ 0 ]) && ( $close || isset ( $data [ self :: CHUNK_SIZE - 1 ])));
2015-08-17 17:00:26 -07:00
2016-04-20 09:56:34 -07:00
if ( ! isset ( $read [ $type ][ 0 ])) {
unset ( $read [ $type ]);
2015-08-17 17:00:26 -07:00
}
2016-04-20 09:56:34 -07:00
if ( $close && feof ( $pipe )) {
fclose ( $pipe );
unset ( $this -> pipes [ $type ]);
2015-08-17 17:00:26 -07:00
}
}
return $read ;
}
/**
* { @ inheritdoc }
*/
public function areOpen ()
{
return ( bool ) $this -> pipes ;
}
/**
2015-10-08 11:40:12 -07:00
* Creates a new UnixPipes instance .
2015-08-17 17:00:26 -07:00
*
* @ param Process $process
* @ param string | resource $input
*
2017-02-02 16:28:38 -08:00
* @ return static
2015-08-17 17:00:26 -07:00
*/
public static function create ( Process $process , $input )
{
return new static ( $process -> isTty (), $process -> isPty (), $input , $process -> isOutputDisabled ());
}
}