Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Program Execution Functions : proc_close

proc_close

Close a process opened by proc_open and return the exit code of that process. (PHP 4 >= 4.3.0, PHP 5)
int proc_close ( resource process )

proc_close() is similar to pclose() except that it only works on processes opened by proc_open(). proc_close() waits for the process to terminate, and returns its exit code. If you have open pipes to that process, you should fclose() them prior to calling this function in order to avoid a deadlock - the child process may not be able to exit while the pipes are open.

Parameters

process

The proc_open() resource that will be closed.

Return Values

Returns the termination status of the process that was run.

Code Examples / Notes » proc_close

sergey1369

Under PHP/4.3.3RC2, in case of two processes
these function may hangs. Work around is not use
proc_close, or put it after all fcloses done.
For example, this code hangs.
$ph1 = proc_open("cat",
array(0=>array("pipe","r"),1=>array("pipe","w")),
$pipes1);
$ph2 = proc_open("cat",
array(0=>array("pipe","r"),1=>array("pipe","w")),
$pipes2);
fclose($pipes1[0]); fclose($pipes1[1]); proc_close($ph1);
fclose($pipes2[0]); fclose($pipes2[1]); proc_close($ph2);
This code worked for me:
$ph1 = proc_open("cat",
array(0=>array("pipe","r"),1=>array("pipe","w")),
$pipes1);
$ph2 = proc_open("cat",
array(0=>array("pipe","r"),1=>array("pipe","w")),
$pipes2);
fclose($pipes1[0]); fclose($pipes1[1]);
fclose($pipes2[0]); fclose($pipes2[1]);
proc_close($ph1); proc_close($ph2);


e-t172

Just an improvement of my precedent function :
<?php
function proc_close_nobug($proc)
{
$status = proc_get_status($proc);
exec('kill '.$status['pid'].' 2>/dev/null >&- >/dev/null');
proc_close($proc);
}
?>
In fact, proc_close() works when called after "kill". This is useful because it doesn't generate "defunct processes" as the precedent version.


ashnazg

It seems that if you configured --enable-sigchild when you compiled PHP (which from my reading is required for you to use Oracle stuff), then return codes from proc_close() cannot be trusted.
Using proc_open's Example 1998's code on versions I have of PHP4 (4.4.7) and PHP5 (5.2.4), the return code is always "-1".  This is also the only return code I can cause by running other shell commands whether they succeed or fail.
I don't see this caveat mentioned anywhere except on this old bug report -- http://bugs.php.net/bug.php?id=29123


oohay251

From various Internet posts and recent experience, I have observed that you cannot rely on proc_close returning the accurate return code of the child process. The return code also depends on wether or not you read from the stdout/stderr pipes, as my example shows. I work around this by writing the exit code to an additional file descriptor.
<?
$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('pipe', 'w'), // stderr is a pipe that the child will write to
   );
   $proc = @proc_open("/bin/ls -l /etc/passwd", $descriptorspec, $pipes);
   fclose($pipes[0]);
   $output = array();
   while (!feof($pipes[1])) array_push($output, rtrim(fgets($pipes[1],1024),"\n"));
   fclose($pipes[1]);
   while (!feof($pipes[2])) array_push($output, rtrim(fgets($pipes[2],1024),"\n"));
   fclose($pipes[2]);
   $exit=proc_close($proc);
   print_r($output);
   echo "exitcode $exit\n\n";
$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('pipe', 'w'), // stderr is a pipe that the child will write to
   );
   $proc = @proc_open("/bin/ls -l /etc/passwd", $descriptorspec, $pipes);
   fclose($pipes[0]);
   fclose($pipes[1]);
   fclose($pipes[2]);
   $exit=proc_close($proc);
   echo "exitcode $exit\n\n";
$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('pipe', 'w'), // stderr is a pipe that the child will write to
      3 => array('pipe', 'w'), // stderr is a pipe that the child will write to
   );
   $proc = @proc_open("/bin/ls -l /etc/passwd;echo $? >&3", $descriptorspec, $pipes);
   fclose($pipes[0]);
   $output = array();
   //comment next line to get correct exicode
   while (!feof($pipes[1])) array_push($output, rtrim(fgets($pipes[1],1024),"\n"));
   fclose($pipes[1]);
   while (!feof($pipes[2])) array_push($output, rtrim(fgets($pipes[2],1024),"\n"));
   fclose($pipes[2]);
   if (!feof($pipes[3])) $output['exitcode']=rtrim(fgets($pipes[3],5),"\n");
   fclose($pipes[3]);
   proc_close($proc);
   print_r($output);
?>
Outputs on my system:
Array
(
   [0] => -rw-r--r--  1 root root 1460 2005-09-02 09:52 /etc/passwd
   [1] =>
   [2] =>
)
exitcode -1
exitcode 1
Array
(
   [0] => -rw-r--r--  1 root root 1460 2005-09-02 09:52 /etc/passwd
   [1] =>
   [2] =>
   [exitcode] => 0
)


Change Language


Follow Navioo On Twitter
escapeshellarg
escapeshellcmd
exec
passthru
proc_close
proc_get_status
proc_nice
proc_open
proc_terminate
shell_exec
system
eXTReMe Tracker