--- name: gethostent signature: 'gethostent' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: gethostent; Perl built-in ``` *[Network info](../perlfunc-by-category)* # gethostent Fetch the next entry from the host database. `gethostent` walks the host database — on traditional Unix systems the `/etc/hosts` file, on modern systems whatever NSS source is configured — returning one record per call until the database is exhausted. Use it when you want to enumerate every known host, not when you want to resolve a single name: [`gethostbyname`](gethostbyname) is the right tool for a targeted lookup. The iteration cursor is shared with [`sethostent`](sethostent) (which rewinds it) and [`endhostent`](endhostent) (which closes it). Between those two calls `gethostent` yields each record in order, then returns the empty list (or [`undef`](undef) in scalar context) once the end of the database is reached. ## Synopsis ```perl my ($name, $aliases, $addrtype, $length, @addrs) = gethostent; my $name = gethostent; ``` ## What you get back **List context** — a five-element list mirroring the C `struct hostent`: - `$name` — the canonical hostname for this entry. - `$aliases` — a space-separated string of alternate names. - `$addrtype` — the address family, typically `AF_INET` (`2`) or `AF_INET6` (`10`). - `$length` — the length in bytes of each address (`4` for IPv4, `16` for IPv6). - `@addrs` — every address recorded for this host, each a packed binary string of `$length` bytes. At end-of-database the return is the empty list. A distinction worth keeping in mind: the upstream perlfunc note that a missing entry may return *"a single meaningless true value"* applies to the by-name and by-address lookups, not to `gethostent` — iteration past the end is a clean empty list. **Scalar context** — the canonical `$name` only, or [`undef`](undef) at end-of-database. Use list context whenever you need anything beyond the name; reconstructing the other fields is not possible after the fact. Convert a packed address from `@addrs` with `Socket::inet_ntoa` for IPv4 or [`unpack`](unpack) directly: ```perl use Socket; print inet_ntoa($addrs[0]), "\n"; ``` ## Global state it touches - The **host database cursor**, shared with [`sethostent`](sethostent), [`endhostent`](endhostent), [`gethostbyname`](gethostbyname), and [`gethostbyaddr`](gethostbyaddr). A by-name or by-address lookup may reset or invalidate a cursor left mid-iteration by `gethostent`; don't interleave the two styles without a fresh [`sethostent`](sethostent) between them. - [`$?`](../perlvar) — set to the C `h_errno` value on failure, where the platform exposes it. A plain end-of-database is not a failure and leaves [`$?`](../perlvar) alone. - [`$!`](../perlvar) — `gethostent` is a database iterator, not a syscall wrapper in the [`open`](open)/[`read`](read) sense. DNS and NSS errors surface through `h_errno` (via [`$?`](../perlvar)), not through [`$!`](../perlvar). ## Examples Enumerate every host in the database: ```perl use Socket; sethostent(1); while (my ($name, $aliases, $type, $len, @addrs) = gethostent) { my @dotted = map { inet_ntoa($_) } @addrs; print "$name @dotted\n"; } endhostent; ``` Scalar context — list just the canonical names: ```perl sethostent(0); while (defined(my $name = gethostent)) { print "$name\n"; } endhostent; ``` Build a name-to-address hash in one pass, then look up entries locally without further DNS calls: ```perl use Socket; my %ip_of; sethostent(1); while (my ($name, $aliases, undef, undef, @addrs) = gethostent) { next unless @addrs; $ip_of{$name} = inet_ntoa($addrs[0]); $ip_of{$_} = inet_ntoa($addrs[0]) for split ' ', $aliases; } endhostent; print $ip_of{"localhost"} // "not in hosts DB", "\n"; ``` By-record interface via the `Net::hostent` override — accessor methods instead of positional unpacking: ```perl use Net::hostent; while (my $h = gethostent) { printf "%-30s %s\n", $h->name, join(",", @{$h->aliases}); } ``` ## Edge cases - **No implicit rewind.** `gethostent` does not open or rewind the database on its own. First call after program start works because the C library lazily opens the database, but once the end is reached further calls keep returning end-of-database until a [`sethostent`](sethostent) rewinds the cursor. Always pair enumeration with an explicit `sethostent` / `endhostent`. - **`STAYOPEN` argument to [`sethostent`](sethostent).** Passing a true value asks the library to keep the database file open across lookups, which matters for NSS sources that otherwise reconnect on every call. Passing `0` permits the library to close and reopen between calls. - **End-of-database is the empty list, not [`undef`](undef).** In list context the loop condition `while (my @r = gethostent)` works because the empty list is false. In scalar context use `while (defined(my $name = gethostent))` — a hostname of `"0"` is theoretically valid and would falsely terminate a truthiness-based loop. - **`@addrs` may be empty** even for a returned record on some NSS backends. Guard the address-unpacking step: ```perl next unless @addrs; ``` - **Aliases are one scalar, not a list.** `$aliases` is a single space-separated string. Split on whitespace if you want a list. - **NSS source mix.** On glibc-based systems the hosts database may draw from `/etc/hosts`, DNS, mDNS, and other NSS modules depending on `nsswitch.conf`. DNS-backed NSS modules typically do **not** enumerate — `gethostent` against a DNS-only hosts database returns the empty list immediately. On most real deployments only the `files` source contributes entries to iteration. - **Interleaving with by-name / by-address lookups.** A call to [`gethostbyname`](gethostbyname) or [`gethostbyaddr`](gethostbyaddr) can reset the shared cursor. Finish the iteration first, or restart it with [`sethostent`](sethostent) after the lookup. - **Thread safety.** The underlying C routine keeps per-process static state for the iteration cursor. Concurrent calls from multiple threads interleave results unpredictably. Confine enumeration to a single thread. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`sethostent`](sethostent) — rewind the iterator and control whether the database stays open across calls - [`endhostent`](endhostent) — close the iterator and release the database handle - [`gethostbyname`](gethostbyname) — targeted lookup by name instead of full enumeration - [`gethostbyaddr`](gethostbyaddr) — targeted reverse lookup by packed address - [`getnetent`](getnetent) — same iteration pattern for the networks database - [`Socket::inet_ntoa`](../../Socket/inet_ntoa) — turn a packed address from `@addrs` into a dotted-quad string