--- name: getsockopt signature: 'getsockopt SOCKET, LEVEL, OPTNAME' since: 5.0 status: documented categories: ["Sockets"] --- ```{index} single: getsockopt; Perl built-in ``` *[Sockets](../perlfunc-by-category)* # 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`](unpack), usually with the `"i"` or `"I"` template, because most options are plain integers. ## Synopsis ```perl getsockopt SOCKET, LEVEL, OPTNAME ``` ## What you get back A packed string holding the kernel's reply on success, or [`undef`](undef) on failure with [`$!`](../perlvar) 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 packed `int`. Decode with [`unpack`](unpack) using `"i"` or `"I"`. - Timeouts (`SO_RCVTIMEO`, `SO_SNDTIMEO`) come back as a packed `struct timeval` — two `long`s on most platforms. - Address-bound options (`SO_PEERCRED`, `IP_MULTICAST_IF`, linger structs, …) have their own layouts; consult `getsockopt(2)` and the relevant protocol man pages for the exact struct. Always check the return value before decoding — calling [`unpack`](unpack) on [`undef`](undef) yields an empty result and hides the real error recorded in [`$!`](../perlvar). ## Global state it touches - [`$!`](../perlvar) is set on failure to the `errno` value from the underlying `getsockopt(2)` call. It is not cleared on success, so check the return value, not [`$!`](../perlvar) directly. ## Examples Check whether Nagle's algorithm is currently disabled (`TCP_NODELAY` set) on a TCP socket: ```perl 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: ```perl 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: ```perl 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: ```perl 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 `long`s — seconds and microseconds: ```perl 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 - **`SOCKET` is not an open socket**: the call fails, returns [`undef`](undef), and sets [`$!`](../perlvar) to `ENOTSOCK` (`"Socket operation on non-socket"`) or `EBADF` (`"Bad file descriptor"`) for a closed handle. - **Unknown `LEVEL` / `OPTNAME`**: the kernel rejects the request with `ENOPROTOOPT` (`"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 die` works 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"` for `int`-sized options (`SO_KEEPALIVE`, `TCP_NODELAY`, `SO_ERROR`, …); use `"l!"` or `"L!"` only when the option's documented layout genuinely uses a native `long`. Getting the width wrong silently returns the wrong number on LP64 platforms. - **Do not hand-pack the reply**: `getsockopt` returns whatever the kernel wrote, including any padding. Re-pack only on round-trips via [`setsockopt`](setsockopt), and then pass the buffer back verbatim rather than reconstructing it. - **No constants without [`Socket`](../../Socket)**: `SOL_SOCKET`, `IPPROTO_TCP`, `TCP_NODELAY`, `SO_ERROR`, and friends are not built-in names. Import them from [`Socket`](../../Socket) with `use Socket qw(...)` or `use Socket qw(:all)`. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`setsockopt`](setsockopt) — the write half; sets the option whose value `getsockopt` reads back - [`Socket`](../../Socket) — source of the `SOL_*`, `IPPROTO_*`, `SO_*`, `TCP_*`, `IP_*` constants you pass as `LEVEL` and `OPTNAME` - [`unpack`](unpack) — required to decode the packed byte string the kernel hands back - [`getprotobyname`](getprotobyname) — run-time way to obtain the `LEVEL` protocol number when you do not want to pull in the `IPPROTO_*` constants from [`Socket`](../../Socket) - [`getsockname`](getsockname) — sibling introspection call; returns the local address bound to `SOCKET` rather than a single option - [`socket`](socket) — creates the socket that `getsockopt` then queries