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 calls starts at the first entry. It is the first leg of the setprotoent / getprotoent / 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 or getprotobynumber anywhere mid-iteration may reset the walk position on some platforms; see Edge cases.
Synopsis#
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 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 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:
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:
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:
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:
my @tcp = getprotobyname('tcp'); # no setprotoent needed
Edge cases#
STAYOPENis 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
getprotobynameorgetprotobynumberduring a walk may reset the iteration cursor on some platforms. Portable code drains the walk first, or re-callssetprotoentafterwards 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:
setprotoentwithout an argument is a syntax error — the built-in has arity one. Pass0if you have no preference.Platforms without a protocols database: on systems where the C library has no
/etc/protocolsequivalent, the call is a no-op rather than an error. Seeperlportfor the full list of network-database quirks.Untainted result of the iteration: the records returned by
getprotoentaftersetprotoentcome 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— read the next entry; the body of the loop thatsetprotoentsets upendprotoent— close the database after iteration; the terminator for the triadsetprotoentstartsgetprotobyname— single-shot lookup by name; does not participate in the iterationgetprotobynumber— single-shot lookup by protocol number; likewise independentsethostent— analogous opener for the hosts database; same idiom, different tablesetservent— analogous opener for the services database