--- name: setnetent signature: 'setnetent STAYOPEN' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: setnetent; Perl built-in ``` *[Network info](../perlfunc-by-category)* # setnetent Open or rewind the networks database for iteration. `setnetent` prepares the system networks database so that subsequent calls to [`getnetent`](getnetent) return entries starting from the first one. It is a direct wrapper around the C library's `setnetent(3)` and reads the same underlying source as the C call — typically `/etc/networks` on Linux, or whatever `nsswitch.conf` / NSS backends have been configured to provide. The `STAYOPEN` argument is a hint to the C library: a true value asks it to keep the database file open across related calls ([`getnetbyname`](getnetbyname), [`getnetbyaddr`](getnetbyaddr), [`getnetent`](getnetent)) so individual lookups do not each pay the cost of opening and closing the file. On modern glibc this flag is effectively ignored — the database is handled efficiently either way — but passing it costs nothing and keeps the code portable to systems where it still matters. ## Synopsis ```perl setnetent STAYOPEN setnetent 0 setnetent 1 ``` ## What you get back `setnetent` returns nothing meaningful. In list context it returns an empty list, in scalar context [`undef`](undef). Do not rely on the return value; the call's effect is the side effect of positioning the database iterator at the start. If the underlying C call fails (for example the database file is missing or unreadable) the error is silent from Perl's perspective — [`getnetent`](getnetent) will simply return an empty list on the first call. ## Global state it touches - The process-wide **networks-database cursor** maintained by the C library. Every call to [`getnetent`](getnetent) advances this cursor; `setnetent` rewinds it. [`endnetent`](endnetent) closes the database and releases any resources held by a `STAYOPEN` hint. - No Perl special variables are read or written. Because the cursor is per-process, not per-thread, interleaving networks-database iteration from multiple threads in the same interpreter will corrupt each iterator's position. Perform the iteration from a single thread, or serialise access. ## Examples Rewind the database and iterate from the first entry: ```perl setnetent(1); while (my ($name, $aliases, $addrtype, $net) = getnetent()) { printf "%-20s %d\n", $name, $net; } endnetent(); ``` Re-run the iteration from the top without closing in between. The second `setnetent` rewinds, so the second loop sees every entry again: ```perl setnetent(1); my @first_pass = collect_nets(); setnetent(1); my @second_pass = collect_nets(); endnetent(); sub collect_nets { my @out; while (my @ent = getnetent()) { push @out, $ent[0] } return @out; } ``` Pairing with `Net::netent` for a named-field interface over the same data source — `setnetent` still controls the cursor: ```perl use Net::netent; setnetent(1); while (my $n = getnetent()) { printf "%s -> %s\n", $n->name, $n->net; } endnetent(); ``` ## Edge cases - **`STAYOPEN` is a hint, not a guarantee**. On systems where the C library ignores it, passing `1` and passing `0` produce identical observable behaviour. - **No implicit `setnetent` before `getnetent`**. A fresh process that calls [`getnetent`](getnetent) without first calling `setnetent` still starts from the first entry on most systems, but this is a libc convention rather than a guarantee. Call `setnetent` explicitly when you want to be sure. - **Calling `setnetent` mid-iteration rewinds the cursor**. Any in-progress `while (getnetent)` loop restarts from the top — useful for a deliberate second pass, a bug if it happens by accident from a helper sub that also iterates. - **Interaction with [`getnetbyname`](getnetbyname) / [`getnetbyaddr`](getnetbyaddr)**. On systems where the C library honours `STAYOPEN`, a by-name or by-address lookup during iteration will *not* disturb the iterator. On systems that ignore the hint, each lookup may reset the cursor. Do not mix by-name lookups with `getnetent` iteration if you need stable positioning. - **Permissions**. The networks database is typically world-readable, but NSS backends (LDAP, `sssd`) may impose their own authorisation. A lookup that worked as `root` can yield nothing as a normal user without Perl seeing an error. - **Empty or missing `/etc/networks`**. On most Linux systems this file is empty or absent by default. `setnetent` still succeeds; the following [`getnetent`](getnetent) returns an empty list on the first call. This is not an error condition. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getnetent`](getnetent) — the iterator primed by `setnetent`; reaches for the next row on each call - [`endnetent`](endnetent) — close the database and release any resources held open by `STAYOPEN`; call it when iteration is done - [`getnetbyname`](getnetbyname) — lookup a single entry by name without running the iterator - [`getnetbyaddr`](getnetbyaddr) — lookup a single entry by packed address without running the iterator - [`sethostent`](sethostent) — the same idiom for the hosts database - [`setservent`](setservent) — the same idiom for the services database - `Net::netent` — object-oriented wrapper returning named fields instead of a positional list