What are the consequences of not closing a directory descriptor in Perl?

I recently inherited some code written by someone else.

I found that everywhere in the code that was open for reading the directory, it never closed because the original developer had a syntax problem - he used the close function to try to close the directory descriptor instead of closedir .

The code was something like this:

 opendir( DIR, $dir ) or die "Cannot open $dir: $!\n"; @files = readdir( DIR ); close( DIR ); 

(This is another good point that Perl Best Practices (pages 208, 278) made about checking the return of the close function. If the close return was checked in this case, it will fail with a "Bad file number.")

Since then I changed it to closedir , but it made me start to wonder: since the directory descriptor has never been closed, what are the negative consequences for keeping the directory descriptor for a long time?

This program is larger (3500 lines of code), it takes some time (5-10 minutes), and several instances of this program work simultaneously. In the case of this directory in the above example, $dir is the same value for all instances. If 10 instances of this program were started at the same time, they all kept the open directory descriptor in the same directory for 5 minutes or longer. I'm sure Perl automatically closes the directory descriptor when the program ends, but it is best to close it as soon as possible.

It's more obvious to me that leaving open file descriptors can cause problems (especially for file descriptors that are open for writing), but what can happen if you don't close the directory descriptor?

The reason I ask is because there was a strange circumstance when this program tried to create a file (in the directory defined by the $ dir parameter above). The PID was embedded in the file name, so the likelihood that the file already exists is less, but Perl could not open the file for writing because it said that it already exists. When we looked in the directory, this file was not. I am wondering if such a problem may occur when working with the public directory of a directory in this directory?

I'm not sure if the OS matters, but this program works on AIX.

Thanks in advance, and happy Friday!

+6
perl syntax-error
source share
3 answers

You wasted a directory descriptor, which is probably considered a file descriptor. In the end, it would hurt if your program opened enough directories to run out of file descriptors. Otherwise, it is quite harmless, although not perfect. This forces the system (and Perl) to maintain resources over which it might otherwise be released.

If the directory descriptor was a local variable and not a simple DIR type name, you could clear Perl after you. See opendir , which says:

Opens a directory named EXPR for processing with readdir, telldir, seekdir, rewinddir, and closedir. Returns true if successful. DIRHANDLE can be an expression whose value can be used as an indirect dirhandle, usually the name of a real dirhandle. If DIRHANDLE is an undefined scalar variable (either an array or a hash element), the variable is assigned a reference to a new anonymous dirhandle. DIRHANDLE have their own namespace, separate from FILEHANDLE.

+11
source share

There will be no serious consequences. There will be a very small increase in memory usage, from the kernel itself, which the iterator that it uses cannot free up to cycle through the list of entries in the directory and possibly also from perl.

Attributively, if any descriptor in the directory is still open, the data cannot actually be deleted from the file system. If any other external process deletes the directory in which the descriptor is located, it will stop appearing in future directories, but the data should still be stored on disk and will still be accessible by the process using an open descriptor. This can lead to odd numbers when using a disk, for example.

Also note that you do not have to close all handles manually. When using lexical file descriptors, closing is automatic as soon as the last descriptor link disappears:

  { # new scope opendir(my $handle, ...) or ...; ... } # implicit closedir happens here 
+7
source share

This is a lesson that is always used to process lexical files (and directory-) - lexical descriptors automatically close when they go out of scope.

This way, you will only spend descriptors (as Jonathan describes) if 1. you used the glob handle of the old style or 2. all the code is in a flat script without any routines or other areas. Use good programming methods, and there will be less unintentional errors :)

+6
source share

All Articles