Network info

endhostent#

Close the hosts database after iteration.

endhostent releases any resources held by the hosts database after a walk driven by gethostent. It pairs with sethostent, which opens or rewinds the database, and is a direct wrapper around the C library call of the same name. Calling it when no iteration is in progress is harmless.

Synopsis#

endhostent;
endhostent();

endhostent takes no arguments. Parentheses are optional.

What you get back#

No useful return value. The call is made for its side effect — tearing down whatever per-process state the platform’s gethostent(3) keeps between iterations (file descriptors on traditional /etc/hosts iteration, resolver sockets on NSS-backed systems).

Global state it touches#

  • The hosts-database iteration cursor shared by gethostent, sethostent, gethostbyname, and gethostbyaddr. After endhostent, the next gethostent call restarts from the beginning (typically after an implicit sethostent).

  • $? carries the C-library h_errno value on systems where host lookups surface it. Most implementations of endhostent itself do not touch h_errno, but a subsequent gethostent can.

This state is per-process, not per-thread. Two threads iterating hosts concurrently will interleave records and neither will see the full set — pair sethostent / gethostent / endhostent within one thread.

Examples#

Close the database after a full walk:

sethostent(1);                          # 1 = keep connection open
while (my @h = gethostent()) {
    print "$h[0]\n";                    # canonical hostname
}
endhostent();

Always pair endhostent with sethostent in a subroutine so the iteration state does not leak to the caller:

sub list_hosts {
    sethostent(0);
    my @names;
    while (my ($name) = gethostent()) {
        push @names, $name;
    }
    endhostent();
    return @names;
}

Defensive cleanup — endhostent is safe even when no iteration is in progress, so it is fine to call unconditionally on an error path:

eval {
    sethostent(1);
    process_hosts();
    1;
} or do {
    my $err = $@;
    endhostent();
    die $err;
};
endhostent();

Using the by-name accessor object interface from Net::hostent does not change the rule — the underlying iterator is the same one endhostent closes:

use Net::hostent;
sethostent(1);
while (my $h = gethostent()) {
    print $h->name, "\n";
}
endhostent();

Edge cases#

  • No-op when nothing is open: calling endhostent without a prior sethostent or gethostent is defined and does nothing observable.

  • Interleaving with name / address lookups: a gethostbyname or gethostbyaddr call in the middle of an iteration may reset the cursor on some platforms (any implementation that internally calls sethostent(0) for single-shot lookups). Do not mix the two styles against the same database without re-calling sethostent afterwards.

  • Platforms without a hosts iterator: on systems whose resolver does not support enumeration (most modern NSS setups querying DNS only), gethostent returns the empty list immediately. endhostent is still callable and still a no-op.

  • Thread safety: the host iterator is process-global. In a multi-threaded program, guard the sethostent / gethostent / endhostent trio with your own mutex.

  • Prototype / parsing: endhostent has no arguments, so there is no parser-ambiguity trap. Writing endhostent LIST is a syntax error rather than being silently interpreted as a call with arguments.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • sethostent — open or rewind the hosts database; the opening half of the iteration pair

  • gethostent — read one record from the open database; returns the empty list when the iteration is exhausted

  • gethostbyname — single-shot lookup by name; does not require sethostent / endhostent

  • gethostbyaddr — single-shot lookup by address

  • endnetent — same pattern for the networks database

  • endservent — same pattern for the services database

  • $? — receives h_errno from failed host lookups on platforms where the C library exposes it