OK, so if I understand correctly,
- The passphrase comes from file
- The input (ciphertext) is in a file and gpg is given this file on its command line, and
- The output goes into another file, again directed by a command line option.
The first thing to notice is that the cat might be unnecesary. In other words,
should have the same effect as
cat file | gpg
but the second is simpler and eliminates an unnecesary pipeline stage. In either case the contents of file becomes the standard input for gpg. The only reason it would matter is if for some reason gpg really insisted that the passphrase-fd be a pipe.
If that will do, then you may be able to reduce the whole thing down to something as simple as this:
# Open the file
open(FILE, "<file") || die;
# Run gpg
# Notice that we are not going to bother to try to
# make the file become stdin to gpg. We're just going
# to tell gpg which file descriptor it's already
# accessible as.
system("gpg", "--passphrase-fd=" . fileno(FILE),
"--decrypt", "--output", "cleartext-filename",
That's the true intent of gpg's passphrase-fd option: to give it a file descriptor for some other file besides the three stdio ones.