[comp.lang.perl] filename from FILEHANDLE?

tchrist@convex.COM (Tom Christiansen) (05/01/91)

From the keyboard of dnb@meshugge.media.mit.edu (David N. Blank):
:  Is there a way to determine the file name which an open FILEHANDLE
:represents?   In my case I was wondering if given:
:
:open(FRED,"bedrock");
:&process(FRED);
:
:sub process {
:  ...
:}
:
:could I determine in &process the actual name of the file I would be
:working with?  Thanks.

Not in general, without at least some cooperation from the calling process:

    sub fdpath { local(*FH) = @_; $name{*FH}; }
    open(FRED, $name{*FRED} = "/etc/motd");

    # all these should (or shouldn't :-) work...
    print "FRED is opened to ", &fdpath( FRED ), "\n";
    print "FRED is opened to ", &fdpath('FRED'), "\n";
    print "FRED is opened to ", &fdpath(*FRED ), "\n";

On a Convex, such cooperation is unnecessary -- there's a syscall for it:

sub fdpath {
   local(*FH) = @_;
   local($path, $pathlen);

   $SYS_fdpath = 227;	# from syscall.h
   $MAXPATHLEN = 1024;	# from sys/param.h

   $pathlen = pack('L', length($path = "\0" x $MAXPATHLEN));
   warn "fdpath: $!" if syscall($SYS_fdpath, fileno(FH), $path, $pathlen);
   substr($path, unpack('L', $pathlen)) = '';
   $path;
} 

Nifty, eh?  It'll even give you the full pathname and works on FIFOs, too.



--tom