--- name: endprotoent signature: 'endprotoent' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: endprotoent; Perl built-in ``` *[Network info](../perlfunc-by-category)* # endprotoent Close the protocols database after iteration. `endprotoent` is the terminator for the `getprotoent` / `setprotoent` / `endprotoent` iteration triad that walks the system protocols database (typically `/etc/protocols`). It releases whatever handle or state the system C library kept open for the iteration. You call it once the sequential walk is done; `getprotobyname` and `getprotobynumber` do not need it — they open and close the database on each call. Takes no arguments, returns nothing useful. This is a thin wrapper over the system `endprotoent(3)` call. ## Synopsis ```perl endprotoent ``` ## What you get back No meaningful return value. Calling it in list or scalar context yields the empty list / undef-equivalent; nothing you'd want to check. Its value is the side effect of closing the protocols database. ## Examples Walk every protocol, then close the database: ```perl setprotoent(1); # 1 = keep the file open between calls while (my @p = getprotoent()) { my ($name, $aliases, $proto) = @p; print "$proto\t$name\n"; } endprotoent(); ``` Short-circuit mid-walk — `endprotoent` still closes cleanly: ```perl setprotoent(0); while (my @p = getprotoent()) { last if $p[0] eq 'tcp'; } endprotoent(); ``` Paired with a direct lookup, `endprotoent` is unnecessary — name and number lookups manage their own state: ```perl my @tcp = getprotobyname('tcp'); # no endprotoent needed ``` ## Edge cases - **Calling without a prior `setprotoent` / `getprotoent`**: harmless. The system call is idempotent; closing an already-closed database is a no-op on every supported platform. - **No arguments accepted**: `endprotoent $x` is a syntax error — the built-in has arity zero. - **Not reentrant**: the protocols database is a single global resource inside the C library. Two concurrent iterations in the same process step on each other's state. Use per-thread or per-subprocess walks if you need parallelism. - **Platform quirks**: behaviour is whatever the host system's `endprotoent(3)` does. See `perlport` for the list of platforms where the network-database routines diverge or are absent entirely. - **Stubbed on platforms without `/etc/protocols`**: on systems where the C library has no protocols database, the call is a no-op rather than an error. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`setprotoent`](setprotoent) — open the protocols database and optionally keep it open across `getprotoent` calls; pair with `endprotoent` to bracket a walk - [`getprotoent`](getprotoent) — read the next entry during an iteration; drives the loop that `endprotoent` terminates - [`getprotobyname`](getprotobyname) — single-shot lookup by protocol name; self-contained, no `endprotoent` needed - [`getprotobynumber`](getprotobynumber) — single-shot lookup by protocol number; same independence from the iteration triad - [`endservent`](endservent) — the analogous terminator for the services database; same idiom, different table - [`endhostent`](endhostent) — the analogous terminator for the hosts database