--- name: setprotoent signature: 'setprotoent STAYOPEN' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: setprotoent; Perl built-in ``` *[Network info](../perlfunc-by-category)* # setprotoent Open the protocols database and prepare it for sequential reads. `setprotoent` rewinds (or opens) the system protocols database — on most Unix-like systems that's `/etc/protocols` — so that a subsequent sequence of [`getprotoent`](getprotoent) calls starts at the first entry. It is the first leg of the [`setprotoent`](setprotoent) / [`getprotoent`](getprotoent) / [`endprotoent`](endprotoent) iteration triad. The single `STAYOPEN` argument is a hint to the C library about whether the file handle backing the iteration should stay open between calls: a true value asks the library to keep it open (faster for long walks), a false value lets it close and reopen per call. Calling [`getprotobyname`](getprotobyname) or [`getprotobynumber`](getprotobynumber) anywhere mid-iteration may reset the walk position on some platforms; see *Edge cases*. ## Synopsis ```perl setprotoent STAYOPEN setprotoent(1) ``` ## What you get back No meaningful return value. Like its `endprotoent` and `sethostent` siblings, `setprotoent` is called for its side effect: rewinding the iteration and, depending on `STAYOPEN`, pinning the descriptor open. There is nothing worth checking in its return value. ## Global state it touches `setprotoent` manipulates a **per-process**, C-library-owned cursor into the protocols database. That state is shared across every subsequent [`getprotoent`](getprotoent) call in the same process — including calls from other modules you did not write. Code that walks the database must either fully drain it with [`endprotoent`](endprotoent) or accept that a later caller may see an iteration already in progress. No Perl-level special variables are read or written. ## Examples Open the database and iterate every entry, keeping the underlying descriptor alive for the full walk: ```perl setprotoent(1); # 1 = keep file open between calls while (my @p = getprotoent()) { my ($name, $aliases, $proto) = @p; print "$proto\t$name\n"; } endprotoent(); ``` Restart an in-progress iteration from the beginning: ```perl setprotoent(1); my @first = getprotoent(); my @second = getprotoent(); setprotoent(1); # rewind my @again = getprotoent(); # same as @first endprotoent(); ``` Let the C library close and reopen `/etc/protocols` on every `getprotoent` — cheaper in memory, more expensive in syscalls, useful only when you read a handful of entries: ```perl setprotoent(0); my @tcp = getprotoent(); endprotoent(); ``` Pair with a one-shot lookup — `getprotobyname` and `getprotobynumber` do not participate in the iteration and do not need `setprotoent`: ```perl my @tcp = getprotobyname('tcp'); # no setprotoent needed ``` ## Edge cases - **`STAYOPEN` is a hint, not a contract**: many C libraries ignore it entirely and behave as if the descriptor were always kept open. Do not rely on the argument to control resource usage at a fine grain. - **Mixing with single-shot lookups**: calling [`getprotobyname`](getprotobyname) or [`getprotobynumber`](getprotobynumber) during a walk may reset the iteration cursor on some platforms. Portable code drains the walk first, or re-calls `setprotoent` afterwards to restart from the top. - **Not reentrant**: the protocols database cursor is a single global resource inside the C library. Two concurrent iterations in the same process (threads, signal handlers, anything) corrupt each other. Use one walk at a time. - **Argument is mandatory at the language level**: `setprotoent` without an argument is a syntax error — the built-in has arity one. Pass `0` if you have no preference. - **Platforms without a protocols database**: on systems where the C library has no `/etc/protocols` equivalent, the call is a no-op rather than an error. See `perlport` for the full list of network-database quirks. - **Untainted result of the iteration**: the records returned by [`getprotoent`](getprotoent) after `setprotoent` come from a file the kernel reads on your behalf and are not marked tainted. Treat them as untrusted anyway if the database can be user-edited. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getprotoent`](getprotoent) — read the next entry; the body of the loop that `setprotoent` sets up - [`endprotoent`](endprotoent) — close the database after iteration; the terminator for the triad `setprotoent` starts - [`getprotobyname`](getprotobyname) — single-shot lookup by name; does not participate in the iteration - [`getprotobynumber`](getprotobynumber) — single-shot lookup by protocol number; likewise independent - [`sethostent`](sethostent) — analogous opener for the hosts database; same idiom, different table - [`setservent`](setservent) — analogous opener for the services database