--- name: setservent signature: 'setservent STAYOPEN' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: setservent; Perl built-in ``` *[Network info](../perlfunc-by-category)* # setservent Rewind the services database and optionally keep it open across lookups. `setservent` is the services-database counterpart of the C library's `setservent(3)`. It resets the internal cursor used by [`getservent`](getservent) so the next call starts again at the first entry of `/etc/services` (or whatever source the system resolver is configured to use), and it controls whether the underlying file stays open between by-name and by-port lookups. ## Synopsis ```perl setservent STAYOPEN setservent 0 # close file between lookups (default) setservent 1 # keep file open across lookups ``` ## What you get back The return value is whatever the underlying C `setservent(3)` returns — on most systems that's nothing useful, and scripts do not check it. Treat `setservent` as called for its side effect on the iterator, not for a value. ## Global state it touches - The per-process services-database cursor shared with [`getservent`](getservent), [`getservbyname`](getservbyname), [`getservbyport`](getservbyport) and [`endservent`](endservent). All four read and mutate the same state; iteration is not thread-safe and not reentrant. - The open/closed status of the services database file. `STAYOPEN` true leaves the file open until [`endservent`](endservent) is called; `STAYOPEN` false (the default) causes each subsequent by-name or by-port lookup to open and close the file again. ## The STAYOPEN argument Pass a true value to hold the file open across a run of individual [`getservbyname`](getservbyname) or [`getservbyport`](getservbyport) lookups. This is an optimisation for batch resolution, not a semantic change: results are identical either way. ```perl setservent 1; for my $name (@service_names) { my @svc = getservbyname $name, "tcp"; # ... process @svc ... } endservent; ``` Pass a false value (or `0`) when you want each lookup to reopen the file. This is the default behaviour and the one most programs want. ## Examples Walk every entry in the services database and print name/port pairs: ```perl setservent 0; while (my ($name, undef, $port, $proto) = getservent) { print "$name $port/$proto\n"; } endservent; ``` Rewind mid-iteration to start over: ```perl setservent 0; my @first_pass; while (my @svc = getservent) { push @first_pass, $svc[0]; last if @first_pass == 10; } setservent 0; # cursor back to start my @second_pass = getservent; # first entry again endservent; ``` Batch-resolve with the file held open: ```perl my @wanted = qw(http https ssh smtp); setservent 1; my %port = map { $_ => scalar getservbyname($_, "tcp") } @wanted; endservent; ``` ## Edge cases - **`STAYOPEN` is required at the Perl level.** `setservent` is parsed with list-operator precedence and reads one argument; a bare `setservent;` with no argument is a compile-time error. Pass `0` when you want the default "close after each lookup" behaviour. - **Platform dependence.** The services database is whatever the system resolver uses — typically `/etc/services`, but NIS, LDAP, and other name-service backends can supply entries. `setservent` rewinds whichever source the C library selects; the Perl level has no say in it. - **Non-Unix platforms.** On systems without `setservent(3)` the call croaks with `The setservent function is unimplemented`. See `perlport` for the availability matrix. - **Threads.** Iterator state is per-process, not per-thread; two threads walking the services database concurrently will interleave and neither will see every record. See the shared note in `perlfunc` on `getpwnam`-family thread safety. - **Pairing with [`endservent`](endservent).** When `STAYOPEN` was true, call [`endservent`](endservent) to release the file descriptor; otherwise the handle leaks for the life of the process. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getservent`](getservent) — walk the services database one entry at a time; this is the iterator `setservent` rewinds - [`endservent`](endservent) — close the services database file opened by `setservent 1` - [`getservbyname`](getservbyname) — look up a single service by name; honours the open/closed state set here - [`getservbyport`](getservbyport) — look up a single service by port number; same open/closed semantics - [`setprotoent`](setprotoent) — same pattern for the protocols database when you are rewinding both together - `Net::servent` — object-oriented wrapper over the `getserv*` family for when positional return lists get unwieldy