--- name: opendir signature: 'opendir DIRHANDLE,EXPR' since: 5.0 status: documented categories: ["Filehandles, files, directories"] --- ```{index} single: opendir; Perl built-in ``` *[Filehandles, files, directories](../perlfunc-by-category)* # opendir Open a directory for reading. `opendir` attaches `DIRHANDLE` to the directory named by `EXPR` so the directory's entries can be read with [`readdir`](readdir) and the position manipulated with [`telldir`](telldir), [`seekdir`](seekdir), and [`rewinddir`](rewinddir). When you're done, [`closedir`](closedir) releases the handle. `DIRHANDLE` lives in a namespace distinct from file handles — a bareword you have already used with [`open`](open) is free to reuse here, and vice versa. ## Synopsis ```perl opendir DIRHANDLE, EXPR opendir my $dh, EXPR ``` ## What you get back `1` on success, `0` on failure. On failure [`$!`](../perlvar) holds the reason — the directory does not exist, is not a directory, is not readable, or the process has hit its open-file limit. Always check the return; a silent failure here turns into a mysteriously empty [`readdir`](readdir) later. ```perl opendir my $dh, $path or die "opendir $path: $!"; ``` ## Global state it touches - [`$!`](../perlvar) — set to the system error string on failure, left untouched on success. Capture it before any other system call disturbs it. ## Handle semantics Three forms of `DIRHANDLE` are accepted, and the choice matters: - **Bareword** — `opendir DIR, $path` creates a package-global dirhandle named `DIR` in the current package. It stays open until you [`closedir`](closedir) it explicitly or the program exits. Avoid in new code; the global namespace is shared across the whole package. - **Undefined scalar** — `opendir my $dh, $path` autovivifies `$dh` into a reference to a fresh anonymous dirhandle. When `$dh` goes out of scope and its refcount drops to zero, the handle is closed automatically. This is the form to use. - **Expression** — any expression whose value is usable as an indirect dirhandle (typically a real dirhandle name held in a variable). The handle identity comes from the expression's value, not its syntactic form. Dirhandles and filehandles share the same underlying I/O object: a given object can be open as one or the other at a time, never both. Passing a dirhandle to [`read`](read) or a filehandle to [`readdir`](readdir) is a usage error, not a silent read of zero bytes. ## Examples The canonical `opendir` / [`readdir`](readdir) / [`closedir`](closedir) idiom: ```perl opendir my $dh, $dir or die "opendir $dir: $!"; while (my $entry = readdir $dh) { next if $entry eq '.' or $entry eq '..'; print "$dir/$entry\n"; } closedir $dh; ``` Read every entry into a list in one go. [`readdir`](readdir) in list context returns all remaining entries: ```perl opendir my $dh, '.' or die "opendir .: $!"; my @entries = grep { !/^\.\.?\z/ } readdir $dh; closedir $dh; ``` Rely on lexical scope for cleanup — no explicit [`closedir`](closedir) needed: ```perl sub list_dir { my ($path) = @_; opendir my $dh, $path or return; return grep { !/^\.\.?\z/ } readdir $dh; # $dh goes out of scope here, handle is closed } ``` Handle a missing-or-unreadable directory without dying: ```perl if (opendir my $dh, $path) { while (defined(my $e = readdir $dh)) { ... } closedir $dh; } else { warn "skipping $path: $!"; } ``` Revisit the start of a directory with [`rewinddir`](rewinddir) rather than reopening: ```perl opendir my $dh, $dir or die $!; my @first_pass = readdir $dh; rewinddir $dh; my @second_pass = readdir $dh; closedir $dh; ``` ## Edge cases - **Failure sets `$!`, not `$@`**. `opendir` reports through [`$!`](../perlvar) like the rest of the I/O family; [`$@`](../perlvar) is untouched. - **Reusing an open dirhandle**. `opendir` on a handle that is already open silently closes the old directory before opening the new one. Prefer explicit [`closedir`](closedir) when the code is meant to be readable. - **Relative paths**. `EXPR` is resolved against the current working directory at the moment of the call. If you [`chdir`](chdir) later, a relative path you captured earlier may no longer mean the same thing — the already-opened dirhandle keeps pointing at the right inode regardless. - **Symlinks**. `opendir` follows symlinks by default: opening a link to a directory opens the target. The entries returned by [`readdir`](readdir) are the target's entries, not the link. - **Bareword vs lexical lifetime**. A bareword dirhandle is global and outlives the enclosing block; a lexical `my $dh` is cleaned up when the scope ends. Mixing the two by accident (`opendir DH, $path` inside a sub) leaks dirhandles on repeated calls. - **File vs dir handle mix-up**. You cannot [`print`](print) to a dirhandle nor [`readdir`](readdir) from a filehandle. The error surfaces at the later call, not at `opendir`. - **`glob` vs `opendir`**. [`glob`](glob) expands shell-style patterns and returns paths; `opendir` enumerates raw directory entries (including `.` and `..`) without interpretation. Use [`glob`](glob) when you want pattern matching; use `opendir` when you want every entry exactly as the filesystem stores it. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`readdir`](readdir) — read the next entry (or all remaining entries) from a dirhandle opened with `opendir` - [`closedir`](closedir) — release a dirhandle; implicit when a lexical `$dh` goes out of scope - [`rewinddir`](rewinddir) — reset the read position to the start without reopening - [`seekdir`](seekdir) — reposition the dirhandle to a token previously returned by [`telldir`](telldir) - [`telldir`](telldir) — current read position as an opaque token suitable for [`seekdir`](seekdir) - [`glob`](glob) — pattern-based alternative when you want shell-style filename expansion instead of raw directory enumeration