Article 9228 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:9228
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!uknet!pipex!uunet!boulder!wraeththu.cs.colorado.edu!tchrist
From: Tom Christiansen <tchrist@cs.Colorado.EDU>
Subject: Re: filehandles and defined
Message-ID: <CItEJy.3I3@Colorado.EDU>
Originator: tchrist@wraeththu.cs.colorado.edu
Sender: news@Colorado.EDU (USENET News System)
Reply-To: tchrist@cs.colorado.edu (Tom Christiansen)
Organization: University of Colorado, Boulder
References: <1993Dec29.174757.40478@rchland.ibm.com>
Date: Wed, 29 Dec 1993 21:04:45 GMT
Lines: 123

:-> In comp.lang.perl, dgross@rchland.vnet.ibm.com writes:
:
:In perl 4, I'd like to check if a filehandle has been "defined", in other words
:is open. I would use this in a cleanup routine that can be called from any point
:in my program.  It would be nice to be able to close all open filehandles, but if
:a particular one is not open, you get a nasty error message.
:
:	if (defined(FH)) { close(FH); }
:
:isn't legal syntax.
:
:	if (defined(fileno(FH))) { close(FH); }
:
:does not work if FH has never been opened.  This is another case where
:filehandle != variable is confusing.

I notice that you said perl4.  What you have there works in perl5.

Meanwhile, if you do this:

	if (defined($fd = fileno(FH))) { close(FH); }

Then it will work.  It's still not goin to take care of filehandles you
don't know about.  You might experiment with this little program and its
functions.

#!/usr/bin/perl

$PTRLEN = length ( $_main{'_main'} );

<DATA>;

open(TMPR, "< .") || die;
open(TMPW, "> /dev/null") || die;

opendir(TMPD, ".") || die;
@dirlist = readdir(TMPD);

fileno STDERR;
fileno STDIN;
fileno STDOUT;
fileno DATA;
fileno TMPR;
fileno TMPW;
# fileno TMPD;

printf NOWHERE "fileno never is %d\n", defined($t = fileno(NEVEROPEN));
printf NOWHERE "fileno bogus is %d\n", defined($t = fileno(BOGUS));
printf NOWHERE "fileno tmpr  is %d\n", defined($t = fileno(TMPR));

close(NEVEROPEN);

$this_is_a_scalar = ();
@this_is_a_list = ();
%this_is_a_table = ();

&dumpfh('main');

format THIS_IS_A_FORMAT = 
@<<<<
$x
.

sub this_is_a_function {};

sub this_is_a_package'and_this_is_its_function {};

sub get_fhs {
    local(@All_FH);
    local($PrintMe) = 1;
    &dumpfh('main');
    return @All_FH;
} 


foreach $fh ( &get_fhs() ) {
    $fd = fileno ($fh);
    printf "%3s %s\n", defined ($fd) ? $fd : "-", $fh;
} 

sub dumpfh {
    local($packname) = $_[0];
    local(*stab) = eval "*_${packname}";
    local($name, $ptr);
    local($bitsig);
    $Seen{$packname}++;
    while ( ($name, $ptr) =  each %stab ) {

	$bitsig = &stabits($ptr); 
	printf "%10s\t%-20s\t%s\n", $bitsig, $packname, $name if $PrintMe;

	if ($bitsig =~ /^111000100[01]$/ ) {
	    push(@All_FH, $packname  . "'" . $name); 
	}

	if (
	    $ptr         =~ /^StB\000/ 	&& 
	    length($ptr) == $PTRLEN  	&& 
	    $name        =~ /^_/ 
	   )
	{
	    $name =~ s/^_//;
	    &dumpfh($name,1) unless $Seen{$name};
	} 
    } 
} 

sub stabits {
    local($stabptr) = shift;
    local($retval ) = '';
    local(@pieces ) = unpack("A4" x 10, $stabptr);
    foreach $i ( 0..9 ) {
	$retval .= $pieces[$i] ? "1" : "0";
    } 
    return $retval;
} 

__END__
blech
-- 
    Tom Christiansen      tchrist@cs.colorado.edu       
      "Will Hack Perl for Fine Food and Fun"
	Boulder Colorado  303-444-3212


