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 is the right
tool for a targeted lookup.
The iteration cursor is shared with sethostent (which
rewinds it) and endhostent (which closes it). Between
those two calls gethostent yields each record in order, then returns
the empty list (or undef in scalar context) once the end of
the database is reached.
Synopsis#
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, typicallyAF_INET(2) orAF_INET6(10).$length— the length in bytes of each address (4for IPv4,16for IPv6).@addrs— every address recorded for this host, each a packed binary string of$lengthbytes.
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 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 directly:
use Socket;
print inet_ntoa($addrs[0]), "\n";
Global state it touches#
The host database cursor, shared with
sethostent,endhostent,gethostbyname, andgethostbyaddr. A by-name or by-address lookup may reset or invalidate a cursor left mid-iteration bygethostent; don’t interleave the two styles without a freshsethostentbetween them.$?— set to the Ch_errnovalue on failure, where the platform exposes it. A plain end-of-database is not a failure and leaves$?alone.$!—gethostentis a database iterator, not a syscall wrapper in theopen/readsense. DNS and NSS errors surface throughh_errno(via$?), not through$!.
Examples#
Enumerate every host in the database:
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:
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:
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:
use Net::hostent;
while (my $h = gethostent) {
printf "%-30s %s\n", $h->name, join(",", @{$h->aliases});
}
Edge cases#
No implicit rewind.
gethostentdoes 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 asethostentrewinds the cursor. Always pair enumeration with an explicitsethostent/endhostent.STAYOPENargument tosethostent. 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. Passing0permits the library to close and reopen between calls.End-of-database is the empty list, not
undef. In list context the loop conditionwhile (my @r = gethostent)works because the empty list is false. In scalar context usewhile (defined(my $name = gethostent))— a hostname of"0"is theoretically valid and would falsely terminate a truthiness-based loop.@addrsmay be empty even for a returned record on some NSS backends. Guard the address-unpacking step:next unless @addrs;
Aliases are one scalar, not a list.
$aliasesis 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 onnsswitch.conf. DNS-backed NSS modules typically do not enumerate —gethostentagainst a DNS-only hosts database returns the empty list immediately. On most real deployments only thefilessource contributes entries to iteration.Interleaving with by-name / by-address lookups. A call to
gethostbynameorgethostbyaddrcan reset the shared cursor. Finish the iteration first, or restart it withsethostentafter 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— rewind the iterator and control whether the database stays open across callsendhostent— close the iterator and release the database handlegethostbyname— targeted lookup by name instead of full enumerationgethostbyaddr— targeted reverse lookup by packed addressgetnetent— same iteration pattern for the networks databaseSocket::inet_ntoa— turn a packed address from@addrsinto a dotted-quad string