<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.11 $ -->
<!-- splitted from ./en/functions/exec.xml, last change in rev 1.28 -->
  <refentry id='function.proc-open'>
   <refnamediv>
    <refname>proc_open</refname>
    <refpurpose>
     Execute a command and open file pointers for input/output
    </refpurpose>
   </refnamediv>
   <refsect1>
    <title>Description</title>
     <methodsynopsis>
      <type>resource</type><methodname>proc_open</methodname>
      <methodparam><type>string</type><parameter>cmd</parameter></methodparam>
      <methodparam><type>array</type><parameter>descriptorspec</parameter></methodparam>
      <methodparam><type>array</type><parameter>&amp;pipes</parameter></methodparam>
      <methodparam choice="opt"><type>string</type><parameter>cwd</parameter></methodparam>
      <methodparam choice="opt"><type>array</type><parameter>env</parameter></methodparam>
      <methodparam choice="opt"><type>array</type><parameter>other_options</parameter></methodparam>
     </methodsynopsis>
    <para>
     <function>proc_open</function> is similar to <function>popen</function>
     but provides a much greater degree of control over the program execution.
     <parameter>cmd</parameter> is the command to be executed by the shell.
     <parameter>descriptorspec</parameter> is an indexed array where the
     key represents the descriptor number and the value represents how PHP
     will pass that descriptor to the child process.
     <parameter>pipes</parameter> will be set to an indexed array of file
     pointers that correspond to PHP's end of any pipes that are created.
     The return value is a resource representing the process; you should
     free it using <function>proc_close</function> when you are finished
     with it.
    </para>
    <!-- TODO: Document cwd, env, other_options and when they appeared. -->
    <para>
     <informalexample>
      <programlisting role="php">
<![CDATA[
<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
);
$process = proc_open("php", $descriptorspec, $pipes);
if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to /tmp/error-output.txt

    fwrite($pipes[0], "<?php echo \"Hello World!\"; ?>");
    fclose($pipes[0]);

    while (!feof($pipes[1])) {
        echo fgets($pipes[1], 1024);
    }
    fclose($pipes[1]);
    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}
?>
]]>
      </programlisting>
     </informalexample>
    </para>
    <para>
     PHP 5RC2 introduces pty support for systems with Unix98 ptys. This allows
     your script to interact with applications that expect to be talking to a
     terminal.  A pty works like a pipe, but is bi-directional, so there is no
     need to specify a read/write mode.  The example below shows how to use a
     pty; note that you don't have to have all descriptors talking to a pty.
     Also note that only one pty is created, even though pty is specified 3
     times.  In a future version of PHP, it might be possible to do more than
     just read and write to the pty.
    </para>
    <para>
     <informalexample>
      <programlisting role="php">
<![CDATA[
<?php
// Create a pseudo terminal for the child process
$descriptorspec = array(
   0 => array("pty"),
   1 => array("pty"),
   2 => array("pty")
);
$process = proc_open("cvs -d:pserver:cvsread@cvs.php.net:/repository login", $descriptorspec, $pipes);
if (is_resource($process)) {
   // work with it here
}
?>
]]>
      </programlisting>
     </informalexample>
    </para>
    <para>
     The file descriptor numbers in <parameter>descriptorspec</parameter> are
     not limited to 0, 1 and 2 - you may specify any valid file descriptor
     number and it will be passed to the child process. This allows your
     script to interoperate with other scripts that run as "co-processes".
     In particular, this is useful for passing passphrases to programs like
     PGP, GPG and openssl in a more secure manner.  It is also useful for
     reading status information provided by those programs on auxiliary
     file descriptors.
    </para>
    <note>
     <para>
      Windows compatibility: Descriptors beyond 2 (stderr) are made
      available to the child process as inheritable handles, but since
      the Windows architecture does not associate file descriptor numbers
      with low-level handles, the child process does not (yet) have a means
      of accessing those handles.  Stdin, stdout and stderr work as expected.
     </para>
    </note>
    <note>
     <para>
      If you only need a uni-directional (one-way) process pipe, use
      <function>popen</function> instead, as it is much easier to use.
     </para>
    </note>

    <para>
     See also <function>stream_select</function>, <function>exec</function>,
     <function>system</function>,
     <function>passthru</function>, <function>popen</function>,
     <function>escapeshellcmd</function>, and the <link
     linkend="language.operators.execution">backtick operator</link>.
    </para>

   </refsect1>
  </refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->