close#
Close a filehandle, flush its buffers, and release the underlying file descriptor.
close finishes whatever I/O was pending on FILEHANDLE, tears down
the PerlIO layer stack, and asks the kernel to close the descriptor.
The return value distinguishes a clean shutdown from one where either
a buffered write failed on the way out, a PerlIO layer reported an
error, or — for pipes — the child process exited non-zero. Without an
argument, close operates on the currently selected filehandle (see
select).
Synopsis#
close FILEHANDLE
close EXPR
close
What you get back#
Truthy (1) on a clean shutdown; false otherwise. A false return
means one of the following went wrong:
A pending buffered write could not be flushed (disk full, broken pipe, closed socket).
A PerlIO layer (e.g.
:encoding(...),:gzipfrom a CPAN layer) reported an error.A pre-existing sticky error was already recorded on the handle.
The handle came from a piped
openand the child exited non-zero (or another syscall involved in tearing the pipe down failed).
When close returns false, $! holds the error from
the failing operation and is safe to read. For pipe handles, if the
only problem was a non-zero child exit, $! is set to 0 and the
child’s status shows up in $? (see below).
Always check the return value on writable handles: the final buffered
block is flushed inside close, so print returning true earlier
does not guarantee the data reached disk.
close $fh
or die "close $path failed: $!";
Global state it touches#
$!— set to the failingerrnowhenclosereturns false, including the flush error on the final buffered write. Cleared to0on a pipe close where the only problem was a non-zero child exit.$?— for handles from a pipedopen, set to the wait status of the child process: low 8 bits are the signal, high 8 bits are the exit code (same encoding assystem).${^CHILD_ERROR_NATIVE}— for pipe handles, set to the raw OS-native status value (before Perl’s portable encoding).$.— an explicitcloseon an input handle resets the current line number. An implicit close via reopening the same handle does not.Currently selected filehandle (via
select) —closewith no argument closes it.
Examples#
Close a regular file and check for a flush failure:
open my $fh, ">", "out.txt" or die $!;
print {$fh} @records;
close $fh or die "flush to out.txt failed: $!";
Close a pipe opened for writing and inspect the child’s exit status.
close waits for the child, then populates $?:
open(my $sort, "|-", "sort", ">", "foo")
or die "can't start sort: $!";
# ... print records to $sort ...
close $sort
or warn $! ? "error closing sort pipe: $!"
: "sort exited with status " . ($? >> 8);
Close a pipe opened for reading, then collect the command’s exit
status. Exit code is the top 8 bits of $?:
open(my $who, "-|", "who") or die $!;
my @lines = <$who>;
close $who;
my $exit = $? >> 8;
Bare close closes whatever handle select most recently made
current, then restores STDOUT as the selected handle:
open my $log, ">>", "app.log" or die $!;
my $old = select $log;
print "entry\n";
close; # closes $log (the selected handle)
select $old;
Closing the read end of a pipe early makes the writer receive
SIGPIPE. If the writer has no handler, it will be killed — drain
the pipe first if you need the writer to exit cleanly:
open my $gen, "-|", "some-producer" or die $!;
while (<$gen>) { last if /^END/ }
1 while <$gen>; # drain so the child finishes cleanly
close $gen or warn "producer failed: $!";
Edge cases#
Bare
close— with no argument, closes the currently selected filehandle. In a freshly started program that isSTDOUT; after aselect($fh)it is$fh. Rarely what you want outside tightly scoped code.Reopening closes for you —
open my $fh, ...on a handle that is already open will close the old descriptor first. The implicit close does not reset$.; an explicitclosedoes. Use an explicitclosewhen line-number state matters.Scope exit closes lexical handles — when the last reference to a lexical filehandle goes out of scope, Perl closes it. If that implicit close fails (flush error, child exit non-zero), Perl emits a
Warning: unable to close filehandle %s properlywarning. Callcloseexplicitly at a point where you can check the return value and silence that warning.Indirect handles —
FILEHANDLEmay be any expression producing a usable filehandle: a bareword (close STDERR), a scalar (close $fh), a glob ref (close \*FH), or an autovivified handle fromopen my $fh, ....Pipe close waits — closing a pipe handle blocks until the child exits, so
$?is populated by the timeclosereturns. Under threads, if the same pipe handle is still open in another thread,closereturns true immediately without reaping the child.Pipe close with non-zero exit —
closereturns false and sets$!to0so that$! ? "$!" : "exit $?"discriminates between an OS-level failure and an ordinary non-zero exit.Closed or invalid handle — closing a handle that is not open sets
$!to"Bad file descriptor"and returns false. Underuse warnings, aclose() on unopened filehandlewarning is emitted.STDIN / STDOUT / STDERR — can be closed like any other handle. The descriptor is freed and will be reused by the next
openon the standard handle, which is how the classicopen STDOUT, ">", "log"redirect works.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
open— counterpart; anopenon an already-open handle does an implicitclosefirst (but does not reset$.)print— final bufferedprintis flushed insideclose, so the write’s real success is only known afterclosefileno— descriptor number of a handle; becomes invalid onceclosesucceedsbinmode— layer stack set bybinmodeis torn down duringclose, and its teardown can itself fail$?— child exit status populated bycloseon a pipe handle$!— error from the failing close operation