proc_open hang (data > 64k)

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

I've written something that takes text and passes it to gpg to encrypt.
It works great except when the text size is greater than 64k at which
point PHP/Apache hangs. Is there any way around this? Below is a code
snippet (which may or may not help).


function encryptContent($fileContent, $encryptionKey)
         $this->displayTextInTable('gpgVerify failed!');

      $command = '/safeModeExecDir/gpg --homedir /data/.gnupg --armor
                  --cipher-algo AES256 --passphrase-fd 3 --batch
--no-tty --yes -c';

      // set up pipes for handling I/O to/from GnuPG
      // 0 === STDIN, a pipe that GnuPG will read the content from
      // 1 === STDOUT, a pipe that GnuPG will write the encrypted
content to
      // 2 === STDERR, a pipe that GnuPG will write to
      // 3 === STDIN, a pipe that GnuPG will read the passphrase from
      $descriptorSpec = array(
         0 => array("pipe", "r"),
         1 => array("pipe", "w"),
         2 => array("pipe", "w"),
         3 => array("pipe", "r")

      $gpgProcess = proc_open($command, $descriptorSpec, $gpgPipes);

         // this writes $fileContent to GnuPG on STDIN
         if(false === fwrite($gpgPipes[0], $fileContent,
            $this->displayTextInTable('fwrite failed!');

         // this writes the $encryptionKey to GnuPG on fd 3
         fwrite($gpgPipes[3], $encryptionKey);

         // this reads the encrypted output from GnuPG from STDOUT
         $encryptedContent = '';
            $encryptedContent .= fgets($gpgPipes[1], 1024);

         // this reads warnings and notices from GnuPG from STDERR
         $gpgErrorMessage = '';
            $gpgErrorMessage .= fgets($gpgPipes[2], 1024);

         // this collects the exit status of GnuPG
         $processExitStatus = proc_close($gpgProcess);

         // unset variables that are no longer needed
         // and can only cause trouble
         $this->displayTextInTable('proc_open() failed.');
      return $encryptedContent;    

Re: proc_open hang (data > 64k)

Quoted text here. Click to load it

If you try to set up a two-way set of pipes between a parent and a
child (in any language, on a POSIX-like OS), you're just begging
for deadlock.  Especially if you can't modify the source code of
the child and it just expects to act like a filter.  Stdio buffering
may create deadlock where you wouldn't otherwise expect it.  There
are a couple of possible solutions:

    (1) Put either the input or the output in a temporary file rather
        than a pipe.  You can do both, but that's overkill.
    (2) Use non-blocking reads/writes and poll or select.
        (I haven't looked at whether this is possible with PHP).
    (3) Some types of filters avoid deadlock, for example, sorting
        produces no output until all the input has been read.

                        Gordon L. Burditt

Re: proc_open hang (data > 64k)

Quoted text here. Click to load it

You can set the blocking mode of streams (including pipes) using
stream_set_blocking() :


Site Timeline