maclypse has asked for the wisdom of the Perl Monks concerning the following question:

How do I check if a filehandle is open for reading or writing? The -X functions are not really doing it for me, since the filehandle doesn't necessarily point to a file. It could be a file, a fifo, a pipe... Is there a universal way?

-- Bow before Zod!

Replies are listed 'Best First'.
Re: Filehandle open?
by fruiture (Curate) on Sep 24, 2002 at 13:29 UTC

    You'll get a warning if you try to tell() on that filehandle but that warning can be suppressed, for we know what we're doing. An unopened handle will return -1 as position:

    sub opened($) { my $fh = shift; no warnings; #turn 'em off locally return tell($fh)==-1 ? undef : 1 }

    HTH

    --
    http://fruiture.de
      And since we're using the pragma, we can also be more specific about which warnings we don't want. Then we can lose the prototype for errorchecking too (which it only does shoddily anyway). And lastly, undef is a one-element list and evaluates as true in list context, so we just let Perl decide what value the boolean expression should return.
      sub is_opened { no warnings qw(closed unopened); return tell $_[0] != -1; }

      Update: Oops. s/==/!=/ - otherwise the truth value is reversed of course. Thanks, blakem.

      Update 2: and of course, check perldoc perllexwarn about the detailed warning names you can use to enable/disable specifically.

      Update 3 (the neverending story): fruiture informs me that you have to disable not only the closed category, but unopened as well. Code updated accordingly.

      Makeshifts last the longest.

      no warnings;

      Kinky. I never saw that piece of code before. I like it though. Thank you.

      -- Bow before Zod!
Re: Filehandle open?
by Zaxo (Archbishop) on Sep 24, 2002 at 14:17 UTC

    The fcntl function allows you to read the filehandle's modes. If *FOO is open and you want to see if it is writeable:

    # named constants for portability use Fcntl qw( F_GETFL O_WRONLY O_RDONLY O_RDWR); if ( (O_WRONLY | O_RDWR) & fcntl( FOO, F_GETFL, 0) ) { # g'wan and write }
    On many systems fcntl will return '0 but true' if the handle is open read only, so a writeable handle will return numeric zero or else have the O_RDWR bit set.

    If the handle is not open fcntl returns undef.

    Update: Aristotle, yes, but it would be good to check $! the see just what the error was. EBADF says the handle isn't open.

    After Compline,
    Zaxo

      Wouldn't it then suffice to check like so?
      sub is_opened { return defined fcntl $_[0], F_GETFL, 0; }

      Makeshifts last the longest.