How to check that a filehandle is open?

I

Ilya Zakharevich

Re the subject: 10 years ago I would check

defined fileno $fh

But nowadays, filehandle does not necessarily has an OS file
descriptor associated to it...

I could also check *$fh{IO} - but it would be defined if, e.g., $fh is
\*FOO, and a bareword FOO was *mentioned* in the code at place where
filehandle is expected (the code may not be ever executed, just
mentioning is enough). Moreover, I expect that *$fh{IO} survives
after close()ure of $fh.

I could do

defined eval { seek $fh, 0, 1 }

but the answer is ALWAYS defined (although sometimes ''), and, to add
insult to injury, would send a warning in my wake...

So: what should one do to check that $fh is open()?

Thanks,
Ilya
 
E

Eric Pozharski

Re the subject: 10 years ago I would check

defined fileno $fh

But nowadays, filehandle does not necessarily has an OS file
descriptor associated to it...

I could also check *$fh{IO} - but it would be defined if, e.g., $fh is
\*FOO, and a bareword FOO was *mentioned* in the code at place where
filehandle is expected (the code may not be ever executed, just
mentioning is enough). Moreover, I expect that *$fh{IO} survives
after close()ure of $fh.

I could do

defined eval { seek $fh, 0, 1 }

but the answer is ALWAYS defined (although sometimes ''), and, to add
insult to injury, would send a warning in my wake...

So: what should one do to check that $fh is open()?

IO::Handle provides a bit of hope

perl -MIO::Scalar -wle '
$sfh = IO::Scalar->new(\$data);
print "foo" if $sfh->opened;
print $sfh->fileno;
'
Name "main::data" used only once: possible typo at -e line 2.
foo
Can't locate object method "FILENO" via package "IO::Scalar" at /usr/lib/perl/5.10/IO/Handle.pm line 132.

YMMV however

perl -MIO::Scalar -MUNIVERSAL -wle '
print IO::Scalar->isa("IO::Handle") ? 1 : 0;
print IO::Scalar->can("opened") ? 1 : 0;
'
1
1

but

perl -MIO::Zlib -MUNIVERSAL -wle '
print IO::Zlib->isa("IO::Handle") ? 1 : 0;
print IO::Zlib->can("opened") ? 1 : 0;
'
0
1

I think that's possible to step on class that provides enough API of
B<IO::Handle> for use and lacks B<opened> method.
 
B

Bo Lindbergh

Ilya Zakharevich said:
Re the subject: 10 years ago I would check

defined fileno $fh

But nowadays, filehandle does not necessarily has an OS file
descriptor associated to it...

In which case fileno returns some defined value which can't be mistaken
for a file descriptor. -1 is the traditional choice (used by e.g.
PerlIO::scalar).


/Bo Lindbergh
 
S

smallpond

Re the subject: 10 years ago I would check

   defined fileno $fh

But nowadays, filehandle does not necessarily has an OS file
descriptor associated to it...

I could also check *$fh{IO} - but it would be defined if, e.g., $fh is
\*FOO, and a bareword FOO was *mentioned* in the code at place where
filehandle is expected (the code may not be ever executed, just
mentioning is enough).  Moreover, I expect that *$fh{IO} survives
after close()ure of $fh.

I could do

  defined eval { seek $fh, 0, 1 }

but the answer is ALWAYS defined (although sometimes ''), and, to add
insult to injury, would send a warning in my wake...

So: what should one do to check that $fh is open()?

Thanks,
Ilya


Scalar::Util::eek:penhandle $fh;

returns undef unless $fh is open or tied.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top