proc_open hang (data > 64k)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • razorfold@gmail.com

    proc_open hang (data > 64k)

    Hi,

    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).

    Thanks,
    -r

    function encryptContent( $fileContent, $encryptionKey)
    {
    if(!$this->gpgVerify())
    {
    $this->displayTextInT able('gpgVerify failed!');
    exit;
    }

    $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($comm and, $descriptorSpec , $gpgPipes);

    if(is_resource( $gpgProcess))
    {
    // this writes $fileContent to GnuPG on STDIN
    if(false === fwrite($gpgPipe s[0], $fileContent,
    strlen($fileCon tent)))
    {
    $this->displayTextInT able('fwrite failed!');
    exit;
    }
    fclose($gpgPipe s[0]);

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

    // this reads the encrypted output from GnuPG from STDOUT
    $encryptedConte nt = '';
    while(!feof($gp gPipes[1]))
    {
    $encryptedConte nt .= fgets($gpgPipes[1], 1024);
    }
    fclose($gpgPipe s[1]);

    // this reads warnings and notices from GnuPG from STDERR
    $gpgErrorMessag e = '';
    while(!feof($gp gPipes[2]))
    {
    $gpgErrorMessag e .= fgets($gpgPipes[2], 1024);
    }
    fclose($gpgPipe s[2]);

    // this collects the exit status of GnuPG
    $processExitSta tus = proc_close($gpg Process);

    // unset variables that are no longer needed
    // and can only cause trouble
    unset(
    $fileContent,
    $encryptionKey,
    $command,
    $descriptorSpec ,
    $gpgProcess,
    $gpgPipes,
    $gpgErrorMessag e,
    $gpgExitStatus
    );
    }
    else
    {
    $this->displayTextInT able('proc_open () failed.');
    exit;
    }

    return $encryptedConte nt;
    }

  • Gordon Burditt

    #2
    Re: proc_open hang (data > 64k)

    >I've written something that takes text and passes it to gpg to encrypt.[color=blue]
    >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).[/color]

    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

    Comment

    • ZeldorBlat

      #3
      Re: proc_open hang (data > 64k)

      >(2) Use non-blocking reads/writes and poll or select.[color=blue]
      >(I haven't looked at whether this is possible with PHP).[/color]

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

      <http://www.php.net/manual/en/function.stream-set-blocking.php>

      Comment

      Working...