Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Close all open file descriptors

by bschmer (Friar)
on Jul 28, 2004 at 13:40 UTC ( #378033=perlquestion: print w/ replies, xml ) Need Help??
bschmer has asked for the wisdom of the Perl Monks concerning the following question:

Good day monks. I have a bit of a head-scratcher that I haven't had much luck with so I hope that the collective mind of the monks can be of some help.

The problem is this, I have a script that starts with some filehandles already open which seem to be inherited via fork and/or exec and these file handles point to files not on the local filesystem which causes some pain when the remote file system goes out to lunch or the local system is rebooted. The annoyance is that I don't use these files in my script at all, so I'd just like to close all files other than STDIN, STDOUT and STDERR. Here's the code that was my attempt:

opendir(DH, "/proc/$$/fd"); while (my $item = readdir DH){ next if ($item =~ /\.\.?/); my @sinfo = stat("/proc/$/fd/" . $item); my $mode = $sinfo[2]; printf("Item is $item: %o\n", $mode); my $fh = FileHandle::fdopen($item, O_RDWR) || warn "Could not dup +$item"; print Dumper($fh); close($fh); } closedir(DH); opendir(DH, "/proc/$$/fd"); while (my $item = readdir DH){ next if ($item =~ /\.\.?/); print "Item is $item\n"; } closedir(DH);
This doesn't do the jobs since the 2nd opendir set prints out all of the same file descriptor numbers that exist at the beginning.

I'd be grateful for any suggestions.

Comment on Close all open file descriptors
Download Code
Re: Close all open file descriptors
by ysth (Canon) on Jul 28, 2004 at 13:49 UTC
    Not an answer to your question, but you should make that regex /^\.\.?\z/ or you'll skip any item name with a period anywhere in it.

    Update: if the stuff in /proc/.../fd are file designators, the above obviously doesn't apply, but you should skip the fdopen and just close them with POSIX::close($item) instead.

      That did the trick. Thanks!
Re: Close all open file descriptors
by belg4mit (Prior) on Jul 28, 2004 at 14:24 UTC
    Unfortunately, unlike open close has little magic and only accepts real filehandles. After quickly perusing the dox and experimenting I see nothing too promising other than a fork (with no dup or pipe) and exit.

    UPDATE: Okay so here's a possibiliy, the details I'll leave to you, but it's not pretty. If you look at the symbol table (%main:: for package main) entries with value /*::.+/ seem to correspond to filehandles, this gets you a list of things to close.

    --
    I'm not belgian but I play one on TV.

Re: Close all open file descriptors
by zentara (Archbishop) on Jul 28, 2004 at 14:41 UTC
    Just a quick thought which may lead you into the right direction. In /proc/$$/fd is a list of the open file desciptors for that process. I havn't thought about how to process the list.

    I'm not really a human, but I play one on earth. flash japh
Re: Close all open file descriptors
by mifflin (Curate) on Jul 28, 2004 at 14:45 UTC
    The module Proc::Daemon closes all file handles before it forks. Here's the code snippet from its Init function...
    ## Close open file descriptors foreach $i (0 .. OpenMax) { POSIX::close($i); }
      Ewww! Okay so it works, and I have to admit I thought of that general idea too, but iterating over all possible descriptors? That's just inelegant. And POSIX is still so like, heavy, man.

      --
      I'm not belgian but I play one on TV.

Re: Close all open file descriptors
by BrowserUk (Pope) on Jul 28, 2004 at 14:55 UTC

    How about

    use POSIX qw[ close ]; POSIX::close( $_ ) for 3 .. 1024; ## Arbitrary upper bound

    This seems to work ok on win32 which isn't the most posix-complient beast in the world.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

      Then again you can use POSIX::sysconf( &POSIX::_POSIX_OPEN_MAX ) instead of an arbitrary bound. :)

      Update: Ooh, missed the Win32 there. Yeah, All hope abandon, ye who program here.

        I said that Win32 was the most posix compliant beast in the world :)

        print POSIX::sysconf( &POSIX::_POSIX_OPEN_MAX );; POSIX::sysconf not implemented on this architecture at ...

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://378033]
Approved by ysth
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (13)
As of 2014-09-22 17:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (198 votes), past polls