By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,495 Members | 1,280 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,495 IT Pros & Developers. It's quick & easy.

proc_open hang (data > 64k)

P: n/a
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->displayTextInTable('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($command, $descriptorSpec, $gpgPipes);

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

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

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

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

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

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

return $encryptedContent;
}

Oct 26 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
>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).


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
Oct 26 '05 #2

P: n/a
>(2) Use non-blocking reads/writes and poll or select.
(I haven't looked at whether this is possible with PHP).


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

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

Oct 26 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.