Rasoul Hajikhani wrote [with rearrangement]:

> I am using open3 to create a commumnication
> channel to gnupg. I am writing a web based
> interface for encrypting and decrypting
> files.  I am having a lot of trouble with
> decrypting messages. 

open3 is evil.  If you can avoid it, do.  Else
listen up:

I've been working recently with open3 to
write part of the upcoming Games::Golf module.

We are testing solutions to Perl Golf
competitions, and needed to feed and capture
the inputs and outputs.  Also, the players
could give us solutions that never close, or
do other bad things.

If you are patient, and want really robust
code then wait a week or two... and then
download it from CPAN - hopefully I'll have
integrated my efforts by then.  It wouldn't
be short and sweet, unfortunately.

Anyway, onto your problem(s).  [Personal
problems, if they exist, are excempted ;-) ]

>From IPC::Open3 manpage:

open3() returns the process ID of the child process.  It
doesn't return on failure: it just raises an exception
matching /^open3:/.

hence:

open3($fin, $fout, $ferr,"$self->{GPGExec} $cmd")
    || return EXEC_ERROR();

is wrong.  Commenting out that bit
of code won't help either.  To catch
errors you need:

my $pid;
eval {
    $pid = open3(...);
}
return EXEC_ERROR($@) if $@;

which isn't as neat.  Good open3 code
is full of such nasties, just to make
it work reliably.


> # Put the file descriptors in the callers package
> $fin    = (caller)[0] . "::$in";
> $fout   = (caller)[0] . "::$out";
> $ferr   = (caller)[0] . "::$err";

NIMBY, you are flytipping globals into
another package - which you shouldn't
do.  This is one approach to Write-Only (tm)
programs that nobody else wants to touch.
[Gentle hint... bad idea]

You should force the user to create the
filehandles themselves... and you use them.
They can be created easily using the
IO::File module:

use IO::File;
my $fh = IO::File->new;

Okay, thats the primary school stuff...
in comparison to what I'm about to say:

> my @error_output = <FERR>;    # reading the error
> my @plaintext    = <FOUT>;    # reading the output

This works, provided:

* The program closes itself when no more stdin
  is given.
* Less than 1024 bytes (or similar) is given to
  stderr
* The program isn't blocking output, in which
  case we'll hang forever.

In addition, you need to:

* Reap your children you've created,
  otherwise you'll end up with tons of
  zombies infesting your system.
* Remember that SIGCHLD can come before the
  output filehandles are fully read.

And remember:

* You must either close the other script
  when you are finished, or rely on it
  flushing its buffers every time you feed
  it.

> form my programme:

Spell checkers can only do so much!  :P

s/form/from/;
s/programme/program/;

Take care, in the vain hope this makes
even an ounce of sense.

Jonathan Paton

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to