Network info

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#

  • 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 or 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 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 — read the next entry; the body of the loop that setprotoent sets up

  • endprotoent — close the database after iteration; the terminator for the triad setprotoent starts

  • getprotobyname — single-shot lookup by name; does not participate in the iteration

  • getprotobynumber — single-shot lookup by protocol number; likewise independent

  • sethostent — analogous opener for the hosts database; same idiom, different table

  • setservent — analogous opener for the services database