getsockopt#
Read one socket option out of the kernel as an opaque packed string.
getsockopt asks the kernel for the current value of the option named
OPTNAME at protocol level LEVEL on SOCKET. The kernel does not
return a typed value — it returns a raw byte buffer whose layout is
determined by the (LEVEL, OPTNAME) pair. You decode that buffer with
unpack, usually with the "i" or "I" template, because
most options are plain integers.
Synopsis#
getsockopt SOCKET, LEVEL, OPTNAME
What you get back#
A packed string holding the kernel’s reply on success, or
undef on failure with $! set to the system
error. The string’s contents are opaque bytes — its length and
layout depend entirely on (LEVEL, OPTNAME):
Boolean and integer options (
SO_KEEPALIVE,SO_REUSEADDR,TCP_NODELAY, …) come back as a packedint. Decode withunpackusing"i"or"I".Timeouts (
SO_RCVTIMEO,SO_SNDTIMEO) come back as a packedstruct timeval— twolongs on most platforms.Address-bound options (
SO_PEERCRED,IP_MULTICAST_IF, linger structs, …) have their own layouts; consultgetsockopt(2)and the relevant protocol man pages for the exact struct.
Always check the return value before decoding — calling
unpack on undef yields an empty result and hides
the real error recorded in $!.
Global state it touches#
Examples#
Check whether Nagle’s algorithm is currently disabled (TCP_NODELAY
set) on a TCP socket:
use Socket qw(IPPROTO_TCP TCP_NODELAY);
my $packed = getsockopt($sock, IPPROTO_TCP, TCP_NODELAY)
or die "getsockopt TCP_NODELAY: $!";
my $nodelay = unpack("I", $packed);
print "Nagle is ", $nodelay ? "off" : "on", "\n";
Same idea, but obtaining the TCP protocol number at runtime from the
system’s protocol database rather than a Socket constant:
use Socket qw(TCP_NODELAY);
defined(my $tcp = getprotobyname("tcp"))
or die "no protocol entry for tcp";
my $packed = getsockopt($sock, $tcp, TCP_NODELAY)
or die "getsockopt: $!";
Read SO_ERROR to drain and clear a pending asynchronous error on a
non-blocking socket after connect or after select flags it
writable:
use Socket qw(SOL_SOCKET SO_ERROR);
my $packed = getsockopt($sock, SOL_SOCKET, SO_ERROR)
or die "getsockopt SO_ERROR: $!";
my $err = unpack("i", $packed);
if ($err) {
$! = $err;
die "asynchronous socket error: $!";
}
Read the socket type (SOCK_STREAM, SOCK_DGRAM, …) of an already
opened handle:
use Socket qw(SOL_SOCKET SO_TYPE SOCK_STREAM);
my $packed = getsockopt($sock, SOL_SOCKET, SO_TYPE)
or die "getsockopt SO_TYPE: $!";
my $type = unpack("i", $packed);
print "stream socket\n" if $type == SOCK_STREAM;
Read a struct timeval option. SO_RCVTIMEO returns two native
longs — seconds and microseconds:
use Socket qw(SOL_SOCKET SO_RCVTIMEO);
my $packed = getsockopt($sock, SOL_SOCKET, SO_RCVTIMEO)
or die "getsockopt SO_RCVTIMEO: $!";
my ($sec, $usec) = unpack("l!l!", $packed);
printf "receive timeout: %d.%06d s\n", $sec, $usec;
Edge cases#
SOCKETis not an open socket: the call fails, returnsundef, and sets$!toENOTSOCK("Socket operation on non-socket") orEBADF("Bad file descriptor") for a closed handle.Unknown
LEVEL/OPTNAME: the kernel rejects the request withENOPROTOOPT("Protocol not available"). There is no way to tell this apart from the success case except by checking the return value.Truthy-return idiom: the common
getsockopt(...) or dieworks because a successful call returns a non-empty packed string. A zero-length reply would make the idiom misfire, but no kernel option returns a zero-length buffer in practice — every defined option has at least one byte of payload.Integer decode width: use
"i"or"I"forint-sized options (SO_KEEPALIVE,TCP_NODELAY,SO_ERROR, …); use"l!"or"L!"only when the option’s documented layout genuinely uses a nativelong. Getting the width wrong silently returns the wrong number on LP64 platforms.Do not hand-pack the reply:
getsockoptreturns whatever the kernel wrote, including any padding. Re-pack only on round-trips viasetsockopt, and then pass the buffer back verbatim rather than reconstructing it.No constants without
Socket:SOL_SOCKET,IPPROTO_TCP,TCP_NODELAY,SO_ERROR, and friends are not built-in names. Import them fromSocketwithuse Socket qw(...)oruse Socket qw(:all).
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
setsockopt— the write half; sets the option whose valuegetsockoptreads backSocket— source of theSOL_*,IPPROTO_*,SO_*,TCP_*,IP_*constants you pass asLEVELandOPTNAMEunpack— required to decode the packed byte string the kernel hands backgetprotobyname— run-time way to obtain theLEVELprotocol number when you do not want to pull in theIPPROTO_*constants fromSocketgetsockname— sibling introspection call; returns the local address bound toSOCKETrather than a single optionsocket— creates the socket thatgetsockoptthen queries