php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47817 PHP hangs when running proc_open()
Submitted: 2009-03-28 02:48 UTC Modified: 2009-03-31 07:13 UTC
From: steven dot abarnett at gmail dot com Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 5.2.9 OS: Windows XP
Private report: No CVE-ID: None
 [2009-03-28 02:48 UTC] steven dot abarnett at gmail dot com
Description:
------------
Unfortunately as far as I can tell, I am the only person having this problem- which leads me to wonder if it's an issue with my PHP configuration. Although I keep using default configuration, so I am at a loss. I have tried installing PHP and Apache, I have tried in xampp, and I have tried in WAMP. Every time after running the proc_open() command the PHP script will wait for the process to close before reading the next line- making reading or writing to any pipes impossible.

$fileDesc = array(
    0 => array("pipe", "r"), // STDIN
    1 => array("pipe", "w"), // STDOUT
    2 => array("pipe", "w") // STDERR
);
die("Got this far");
$handle = proc_open("C:/wherever/program.exe", $fileDesc, $pipes);
fwrite($pipes[0], "input");
fclose($pipes[0]);
proc_close($handle);

Displays "Got this far" and dies, as expected. However:

$fileDesc = array(
    0 => array("pipe", "r"), // STDIN
    1 => array("pipe", "w"), // STDOUT
    2 => array("pipe", "w") // STDERR
);
$handle = proc_open("C:/wherever/program.exe", $fileDesc, $pipes);
die("Got this far");
fwrite($pipes[0], "input");
fclose($pipes[0]);
proc_close($handle);

Will simply hang and seem to cease all function. The moment that I close program.exe through task manager the script continues as if nothing were wrong, dying with the output "Got this far". The input is never passed to the program, although no errors are raised when I hit the proc_close() line.

Reproduce code:
---------------
        $descriptors = array(
            0 => array("pipe", "r"), // STDIN. Used to feed input
            1 => array("pipe", "w"), // STDOUT. Used to read output
            2 => array("pipe", "w"), // STDERR. Used to read errors
            3 => array("pipe", "r") // We can feed the passphrase here
        );
        // Build the command line and start the process
        $cmd = '"C:/program files/gnu/gnupg/gpg.exe" --batch --no-verbose --passphrase-fd 3 --output decrypted.zip --decrypt encrypted.zip.gpg';
        $gpg = proc_open( $cmd, $descriptors, $pipes);
        if(is_resource($gpg)) {
            // Push passphrase to custom pipe
            fwrite($pipes[3], $passphrase);
            fclose($pipes[3]);
            proc_close($gpg);
        }

Expected result:
----------------
Expected to find decrypted.zip in the same directory as the PHP script (a decrypted version of encrypted.zip.gpg, which is located in the same directory as the PHP script)

Actual result:
--------------
When localhost/test.php was run the webpage continued to load indefinitely. I waited as long as 20 minutes. The PHP.ini file should stop execution after 30 seconds. When gpg.exe was killed with task manager the page loaded but the .zip file was never created.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-03-29 11:49 UTC] steven dot abarnett at gmail dot com
I have found a fix for now, although I would like to know if better options exist. The fault seems to lie in Windows. Both XP and Vista refuse to allow file descriptors over 2. When I changed the code like so it worked just fine:

        $descriptors = array(
            0 => array("pipe", "r"), // STDIN. Used to feed input
            1 => array("pipe", "r"), // STDOUT. We are writing to it, though
            2 => array("pipe", "w"), // STDERR. Used to read errors
        );
        // Build the command line and start the process
        $cmd = '"C:/program files/gnu/gnupg/gpg.exe" --batch
--no-verbose --passphrase-fd 1 --output decrypted.zip --decrypt
encrypted.zip.gpg';
        $gpg = proc_open( $cmd, $descriptors, $pipes);
        if(is_resource($gpg)) {
            // Push passphrase to custom pipe
            fwrite($pipes[1], $passphrase);
            fclose($pipes[1]);
            proc_close($gpg);
        }


Is there a solution to be able to create more pipes in Windows? It's very inconvenient having to write to STDOUT just to make my program work properly, as it prevents me from reading any output thrown out by the code (other than errors)
 [2009-03-31 07:13 UTC] jani@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2010-05-06 02:01 UTC] php dot net at phor dot net
I have the same problem. I am having occasional hangups on the proc_open command 
like this, but only when run in a class's constructor function. the same code 
works fine in the root context.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 09 07:01:31 2024 UTC