Filehandles, files, directories
fcntl#
Perform a fcntl(2) file-control operation on a filehandle.
fcntl is the direct Perl binding for the POSIX fcntl(2) system
call. It reads or changes per-descriptor state — non-blocking mode,
close-on-exec, advisory record locks, descriptor flags — by invoking
FUNCTION against FILEHANDLE, with SCALAR acting as either the
input argument, the output buffer, or both, depending on which
FUNCTION you pass.
The FUNCTION codes are not Perl-level literals; they are C
preprocessor macros exposed by the Fcntl module.
Load it first, or FUNCTION will be an undefined bareword:
use Fcntl;
Synopsis#
use Fcntl;
fcntl FILEHANDLE, FUNCTION, SCALAR
my $flags = fcntl($fh, F_GETFL, 0);
fcntl($fh, F_SETFL, $flags | O_NONBLOCK);
What you get back#
On success, the integer the kernel returned. When that integer is
0, Perl substitutes the dual-valued string "0 but true" — true
in boolean context, numeric 0 in numeric context, and exempt from
the Argument "..." isn't numeric warning. This lets you test the
result with or die even for operations whose success value is
literally zero:
fcntl($fh, F_SETFD, FD_CLOEXEC)
or die "F_SETFD: $!";
On failure, fcntl returns undef and sets $!
to the relevant errno. You do not need to wrap the return in
defined — the "0 but true" convention makes a plain
truth test sufficient.
For FUNCTION codes that write back through SCALAR (such as
F_GETLK), the updated bytes land in the scalar you passed; the
return value still follows the rule above.
How SCALAR is used#
SCALAR plays three different roles depending on FUNCTION:
Input integer. For flag-setting calls like
F_SETFDorF_SETFL,SCALARis the integer bitmask to install.Ignored placeholder. For flag-getting calls like
F_GETFDorF_GETFL,SCALARis unused by the kernel; pass0by convention.In/out struct buffer. For record-locking calls like
F_GETLK,F_SETLK, andF_SETLKW,SCALARmust hold a packedstruct flock— build it withpackbefore the call, and forF_GETLKdecode the returned bytes withunpackafterward.
When SCALAR is used as an output buffer, pre-size it to at least
the length of the struct the kernel will write; an undersized
scalar is grown automatically, but pre-sizing makes the intent
obvious.
Global state it touches#
$!— set on failure to theerrnofromfcntl(2).Descriptor-level flags on
FILEHANDLE(e.g.O_NONBLOCK,FD_CLOEXEC) persist for the lifetime of the descriptor, survivedupandforkaccording to POSIX rules, and are not Perl-visible through any other variable. The only way to read them back is anotherfcntlcall withF_GETFL/F_GETFD.
Examples#
Make a socket non-blocking — the canonical use:
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
my $flags = fcntl($remote, F_GETFL, 0)
or die "F_GETFL: $!";
fcntl($remote, F_SETFL, $flags | O_NONBLOCK)
or die "F_SETFL: $!";
Set close-on-exec so the descriptor is not inherited by child
processes across exec:
use Fcntl qw(F_SETFD FD_CLOEXEC);
fcntl($fh, F_SETFD, FD_CLOEXEC)
or die "F_SETFD: $!";
Read the current descriptor flags and test a bit:
use Fcntl qw(F_GETFD FD_CLOEXEC);
my $fd_flags = fcntl($fh, F_GETFD, 0);
defined $fd_flags or die "F_GETFD: $!";
if ($fd_flags & FD_CLOEXEC) {
# descriptor will close on exec
}
Place an advisory write lock on the whole file. The struct flock
layout is platform-specific; on Linux s s l l i covers
l_type l_whence l_start l_len l_pid:
use Fcntl qw(F_SETLK F_WRLCK SEEK_SET);
my $lock = pack('s s l l i', F_WRLCK, SEEK_SET, 0, 0, 0);
fcntl($fh, F_SETLK, $lock)
or die "lock refused: $!";
Toggling off a single flag — mask out O_NONBLOCK to return a
handle to blocking mode:
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
my $flags = fcntl($fh, F_GETFL, 0);
fcntl($fh, F_SETFL, $flags & ~O_NONBLOCK)
or die "F_SETFL: $!";
Edge cases#
Forgot
use Fcntl:F_GETFLand friends parse as barewords and evaluate to a warning-level nuisance underuse strict/use warnings, or to the string"F_GETFL"otherwise — either way the call fails withEINVAL. Always loadFcntlfirst."0 but true"return: do not compare the return with== 0as a failure test. Use a plain boolean (or die) ordefined— the former is the idiom.F_SETLKvsF_SETLKW:F_SETLKreturnsundefand sets$!toEAGAIN/EACCESwhen another process holds a conflicting lock.F_SETLKWblocks until the lock is granted. Pick deliberately; mixing them up is the usual source of hangs.F_GETLKoutput: on success thestruct flockbytes inSCALARare overwritten with information about the conflicting lock (orl_type == F_UNLCKif the region is free).unpackback with the same template you packed with.Not every system implements every FUNCTION:
fcntlraises an exception on a machine that does not implementfcntl(2)at all. On systems that do, unsupportedFUNCTIONcodes fail withEINVALvia$!. TheFcntlmodule only exports constants the current platform actually defines.fcntlvsioctl: both share the argument-processing and return-value convention, but they target different kernel interfaces. Usefcntlfor descriptor flags and advisory locks; useioctlfor device-specific control codes.fcntlvsflock:flockuses whole-file BSD-styleflock(2)locks, which on Linux interoperate withfcntlPOSIX locks only in limited ways. If you need byte-range locking or POSIX semantics (lock released on anycloseof the file by the owning process), usefcntlwithF_SETLK; otherwiseflockis simpler.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
Fcntl— the module that exports theF_*/O_*/FD_*/SEEK_*constantsfcntlexpects; alwaysuseit firstioctl— same calling and return-value convention asfcntl, but for device control codes rather than file-control flagsflock— simpler whole-file advisory locks; reach for it when you don’t need byte-range or POSIX semanticsopen— opens the filehandle in the first place; some flagsfcntladjusts (e.g.O_NONBLOCK,O_APPEND) are also settable at open timesysopen— low-level open that takes the sameO_*flags fromFcntl; use it when you want the flags applied atomically rather than via a follow-upfcntl(F_SETFL)pack/unpack— required for building and decoding thestruct flockbuffer used byF_GETLK/F_SETLK