If you don't mind to use the object oriented IO::File instead of plain
file handles, you could do it this way:

-----------------------------------------------------------------------
#!/bin/perl -w
use strict;
use IO::File;

# Open a whole bunch of files ('test1'..'test7') and
# store the handles in a hash table.
my $files = {
     map { ($_ => IO::File->new($_) || die "$_: $!\n") }
         qw( test1 test2 test3 test4 test5 test6 test7 )
   };

# Do whatever you like with the files, e.g. print
# the name and the first line of each file...
print "$_: ", $files->{$_}->getline for sort keys %$files;

# Close 'em all!
undef $files;

# Do anything else
# ...
-----------------------------------------------------------------------

If all references to an IO::File object are lost, Perl will call its
destructor and this will close the file. Since all references are stored
in a hash table referenced only by $files, the destructors for all
IO::File objects will be called if you undef $files.

If my 'map'ping looks like line noise to you, here's another example
with only two files that looks less noisy:

-----------------------------------------------------------------------
#!/bin/perl -w
use strict;
use IO::File;

my $files;

# Open two files
$files->{file1} = new IO::File 'test1'
                  or die "can't open `test1': $!\n";
$files->{file2} = new IO::File 'test2'
                  or die "can't open `test2': $!\n";

# Print their contents
print $files->{file1}->getlines;
print $files->{file2}->getlines;

# And close them
undef $files;
-----------------------------------------------------------------------

If you're only using the files within a subroutine and make $files
local to that subroutine using 'my', you don't even need to explicitly
undef $files, because it automatically vanishes if the sub is left.

In case you don't want to use IO::File, and don't mind some real
ugly (or cool, whatever you like ;-) code, have a look at this:

-----------------------------------------------------------------------
close $_ for map { /^(?:ARGV|std(?:err|out|in)|STD(?:ERR|OUT|IN))$/
                   ? () : *{$::{$_}}{IO} || () } keys %::;
-----------------------------------------------------------------------

This will close all existing file handles except for the 'standard'
ones being ARGV, STDIN, STDOUT, STDERR, stdin, stdout and stderr.
It simply searches the symbol table for file handles and, if they
aren't the standard file handles, closes them.

Hope this helps,

-- Marcus


| -----Original Message-----
| From: Gupta, Ashish [mailto:[EMAIL PROTECTED]]
| Sent: Friday, August 24, 2001 2:21 AM
| To: '[EMAIL PROTECTED]'
| Subject: How to close ALL open file descriptors
| 
| 
| I open lots of file descriptors in a script.
| At one point,  I want to close all the opened file 
| descriptors (except for
| stdin, stdout, stderr).
| Is there a way to close all the opened file descriptors 
| without having a
| list of the handles ?
| 
| 
| 
| 
| **************************************************************
| ********* 
| This communication is confidential and is intended only for 
| the person 
| to whom it is addressed.  If you are not that person, you are not 
| permitted to make use of the information and you are requested to 
| notify administrator [EMAIL PROTECTED] immediately that 
| you have received it and then destroy/erase the copy/e-mail in your 
| possession. 
| **************************************************************
| ********* 
| 
| 
| 
| -- 
| To unsubscribe, e-mail: [EMAIL PROTECTED]
| For additional commands, e-mail: [EMAIL PROTECTED]
| 

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to