> 
> > > I am making a call to gpg on the command line, a couple of
> > > the parameters that gpg will accept are file descriptor
> > > numbers that it then writes to, and I would like to capture
> > > that output and then read from it.
> > >
> > > I have successfully made it read directly from a file on the
> > > local file system like so:
> > >
> > > my $pass_fh = IO::File->new('/path/to/localfile');
> > > fcntl $pass_fh, F_SETFD, 0; # don't close over exec
> > > my $pass_fd = $pass_fh->fileno(); # get the file descriptor number
> > >
> > > and then calling gpg on the command line like so:
> > >
> > > gpg [other options here, etc.] --passphrase-fd $pass_fd [etc.]

Ok, let me make sure I understand. You probably know more about this stuff
than i do, but maybe discussion will lead you to a resolution. I have
strayed away from C since i started with perl, but i I do have a copy of
steven's "advance Programmin..." here so maybe it can  help us.

Now when you say you are calling gpg on the command line, how does it know
what $pass_fd is? is this a  fork and exec? and env variable ? , system
call?  

> > >
> > > Which works very well. And I can successfully create a new
> > > file handle,
> > >
> > > my $logger_fh = IO::Handle->new();
> > >
> > > And then presumably could use the same methods as above, but
> > > the file handle has to be open to determine its number and
> > > then to pass the file descriptor to the command line. Which I
> > > determined is what fdopen is for, so now to my question(s)
> > > (finally, sorry about that) how do I determine what the FD
> > > (file descriptor number) should be that I pass to fdopen? Is
> > > this an arbitrary number (not 0,1,2), can I have the system
> > > suggest a number?  If the program were to choose the same
> > > number in different forks would it matter?  Is there a better
> > > more appropriate way of handling all of this?  (Besides using
> > > one of the GPG modules from CPAN, which I would absolutely
> > > love, but after spending a number of days checking them out,
> > > each one has one or more quirks which doesn't allow it to
> > > work in our app.)
> > 

> I had seen that and been through it a couple times, for 
> another issue, but went through it again, can't hurt right 
> ;-), but all of the examples seem to open an already existing 
> file, creating a file, or using a handle as part of a pipe.  
> It did give me the idea of trying to open a new file handle 
> with the "-|" syntax to open but that just errored, and left 
> $! blank which is odd to me...

what about the part where it describes grabbing the fd from the sytem proc
files and/or env variables. the c sys functions like dup and fnctl operate
on the kernel's proc table-> fd table (and it gets hairy from here :-) Here
is a snip of what part i am talking about:
------
If you really want the new program to gain access to a filehandle other than
these three, you can, but you have to do one of two things. When Perl opens
a new file (or pipe or socket), it checks the current setting of the $^F
($SYSTEM_FD_MAX) variable. If the numeric file descriptor used by that new
filehandle is greater than $^F, the descriptor is marked as one to close.
Otherwise, Perl leaves it alone, and new programs you exec will inherit
access.

It's not always easy to predict what file descriptor your newly opened
filehandle will have, but you can temporarily set your maximum system file
descriptor to some outrageously high number for the duration of the open: 

# open file and mark INPUT to be left open across execs
{ 
    local $^F = 10_000;
    open(INPUT, "< /etc/motd")   or die "/etc/motd: $!";
} # old value of $^F restored on scope exit

Now all you have to do is get the new program to pay attention to the
descriptor number of the filehandle you just opened. The cleanest solution
(on systems that support this) is to pass a special filename that equates to
a file descriptor. If your system has a directory called /dev/fd or
/proc/$$/fd containing files numbered from 0 through the maximum number of
supported descriptors, you can probably use this strategy. (Many Linux
operating systems have both, but only the /proc version tends to be
correctly populated. BSD and Solaris prefer /dev/fd. You'll have to poke
around at your system to see which looks better for you.) First, open and
mark your filehandle as one to be left open across execs as shown in the
previous code, then fork like this: 
if ($pid = fork) { wait } 
else {
    defined($pid)                or die "fork: $!";
    $fdfile = "/dev/fd/" . fileno(INPUT);
    exec("cat", "-n", $fdfile)   or die "exec cat: $!";
}
--------
...... 
and a litte further down, using the env to get at it:

-----------

If your system doesn't support file descriptors named in the filesystem, and
you want to pass a filehandle other than STDIN, STDOUT, or STDERR, you can
still do so, but you'll have to make special arrangements with that program.
Common strategies for this are to pass the descriptor number through an
environment variable or a command-line option. 

If the executed program is in Perl, you can use open to convert a file
descriptor into a filehandle. Instead of specifying a filename, use "&="
followed by the descriptor number. 

if (defined($ENV{input_fdno}) && $ENV{input_fdno}) =~ /^\d$/) { 
    open(INPUT, "<&=$ENV{input_fdno}")
        or die "can't fdopen $ENV{input_fdno} for input: $!";
}

----------

 > 
> Right, but I am not sure how to get an existing FD without 
> attaching it to an actual normal file through an open call.  
> the fdopen essentially attaches a separate handle to the 
> existing file descriptor, but I need to know how to generate 
> a file descriptor without attaching it to a file on the 
> filesytem, if this can be done at all, at least at Perl's 
> high level, as this is seemingly done by 'pipe'.

would you be open to writing this in C ?


> 
> > So i assume the open method in IO::File is really the open2
> > system call.
> 
> I believe IO::File is just a sub class of IO::Handle, and 
> fdopen just wraps a regular open call.

no, i think it wraps the actual C fdopen call

> 
> > Also are you loading the Fcntl module in the program so you 
> get all of the
> > constants from cntl.h? 
> 
> Yes, that is how I am setting the filehandle to stay open 
> through the exec (system in my case). But I am not familar 
> with what that gets me as I don't make much of a C programmer 
> (yet hopefully ;-)), any suggestions on what I can use from 
> it for this problem?

not off the top of my head, but I just cracked open the book....


THanks
Jim


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

Reply via email to