PHP 5.6.0 released

proc_close

(PHP 4 >= 4.3.0, PHP 5)

proc_close Ferme un processus ouvert par proc_open()

Description

int proc_close ( resource $process )

proc_close() est similaire à pclose() hormis le fait qu'elle fonctionne avec les processus ouverts par proc_open(). proc_close() attend que le processus process se termine, puis retourne son code de sortie. Si vous avez des pipes ouverts avec ce processus, il faut les fermer avec fclose() avant d'appeler cette fonction pour éviter des verrouillages : le processus peut ne pas pouvoir sortir tant que les pipes sont ouverts.

Liste de paramètres

process

La resource proc_open() à fermer

Valeurs de retour

Retourne le code de sortie du processus ou -1 en cas d'echec.

add a note add a note

User Contributed Notes 4 notes

up
1
oohay251 at yahoo dot com
8 years ago
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
)
up
0
ashnazg at php dot net
6 years ago
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
up
0
sergey1369 at narod dot ru
10 years ago
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);
up
-1
morrisdavidd at gmail dot com
6 years ago
Consider the following pseudo code:

$SOME_PROCESS = proc_open(/* something here */);
...
$status = proc_get_status($SOME_PROCESS);
...
$exitCode = proc_close($SOME_PROCESS);

If the external program has exited on its own before the call to proc_get_status, then $exitCode == -1

So consider using:
$actualExitCode = ($status["running"] ? $exitCode : $status["exitcode"] );
To Top