summaryrefslogtreecommitdiffstats
path: root/man3/getservent_r.3
diff options
context:
space:
mode:
Diffstat (limited to 'man3/getservent_r.3')
-rw-r--r--man3/getservent_r.3250
1 files changed, 250 insertions, 0 deletions
diff --git a/man3/getservent_r.3 b/man3/getservent_r.3
new file mode 100644
index 0000000..04397ee
--- /dev/null
+++ b/man3/getservent_r.3
@@ -0,0 +1,250 @@
+'\" t
+.\" Copyright 2008, Linux Foundation, written by Michael Kerrisk
+.\" <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH getservent_r 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+getservent_r, getservbyname_r, getservbyport_r \- get
+service entry (reentrant)
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <netdb.h>
+.PP
+.BI "int getservent_r(struct servent *restrict " result_buf ,
+.BI " char " buf "[restrict ." buflen "], size_t " buflen ,
+.BI " struct servent **restrict " result );
+.BI "int getservbyname_r(const char *restrict " name ,
+.BI " const char *restrict " proto ,
+.BI " struct servent *restrict " result_buf ,
+.BI " char " buf "[restrict ." buflen "], size_t " buflen ,
+.BI " struct servent **restrict " result );
+.BI "int getservbyport_r(int " port ,
+.BI " const char *restrict " proto ,
+.BI " struct servent *restrict " result_buf ,
+.BI " char " buf "[restrict ." buflen "], size_t " buflen ,
+.BI " struct servent **restrict " result );
+.PP
+.fi
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.PP
+.BR getservent_r (),
+.BR getservbyname_r (),
+.BR getservbyport_r ():
+.nf
+ Since glibc 2.19:
+ _DEFAULT_SOURCE
+ glibc 2.19 and earlier:
+ _BSD_SOURCE || _SVID_SOURCE
+.fi
+.SH DESCRIPTION
+The
+.BR getservent_r (),
+.BR getservbyname_r (),
+and
+.BR getservbyport_r ()
+functions are the reentrant equivalents of, respectively,
+.BR getservent (3),
+.BR getservbyname (3),
+and
+.BR getservbyport (3).
+They differ in the way that the
+.I servent
+structure is returned,
+and in the function calling signature and return value.
+This manual page describes just the differences from
+the nonreentrant functions.
+.PP
+Instead of returning a pointer to a statically allocated
+.I servent
+structure as the function result,
+these functions copy the structure into the location pointed to by
+.IR result_buf .
+.PP
+The
+.I buf
+array is used to store the string fields pointed to by the returned
+.I servent
+structure.
+(The nonreentrant functions allocate these strings in static storage.)
+The size of this array is specified in
+.IR buflen .
+If
+.I buf
+is too small, the call fails with the error
+.BR ERANGE ,
+and the caller must try again with a larger buffer.
+(A buffer of length 1024 bytes should be sufficient for most applications.)
+.\" I can find no information on the required/recommended buffer size;
+.\" the nonreentrant functions use a 1024 byte buffer -- mtk.
+.PP
+If the function call successfully obtains a service record, then
+.I *result
+is set pointing to
+.IR result_buf ;
+otherwise,
+.I *result
+is set to NULL.
+.SH RETURN VALUE
+On success, these functions return 0.
+On error, they return one of the positive error numbers listed in errors.
+.PP
+On error, record not found
+.RB ( getservbyname_r (),
+.BR getservbyport_r ()),
+or end of input
+.RB ( getservent_r ())
+.I result
+is set to NULL.
+.SH ERRORS
+.TP
+.B ENOENT
+.RB ( getservent_r ())
+No more records in database.
+.TP
+.B ERANGE
+.I buf
+is too small.
+Try again with a larger buffer
+(and increased
+.IR buflen ).
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR getservent_r (),
+.BR getservbyname_r (),
+.BR getservbyport_r ()
+T} Thread safety MT-Safe locale
+.TE
+.sp 1
+.SH VERSIONS
+Functions with similar names exist on some other systems,
+though typically with different calling signatures.
+.SH STANDARDS
+GNU.
+.SH EXAMPLES
+The program below uses
+.BR getservbyport_r ()
+to retrieve the service record for the port and protocol named
+in its first command-line argument.
+If a third (integer) command-line argument is supplied,
+it is used as the initial value for
+.IR buflen ;
+if
+.BR getservbyport_r ()
+fails with the error
+.BR ERANGE ,
+the program retries with larger buffer sizes.
+The following shell session shows a couple of sample runs:
+.PP
+.in +4n
+.EX
+.RB "$" " ./a.out 7 tcp 1"
+ERANGE! Retrying with larger buffer
+getservbyport_r() returned: 0 (success) (buflen=87)
+s_name=echo; s_proto=tcp; s_port=7; aliases=
+.RB "$" " ./a.out 77777 tcp"
+getservbyport_r() returned: 0 (success) (buflen=1024)
+Call failed/record not found
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (getservent_r.c)
+.EX
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+\&
+#define MAX_BUF 10000
+\&
+int
+main(int argc, char *argv[])
+{
+ int buflen, erange_cnt, port, s;
+ struct servent result_buf;
+ struct servent *result;
+ char buf[MAX_BUF];
+ char *protop;
+\&
+ if (argc < 3) {
+ printf("Usage: %s port\-num proto\-name [buflen]\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ port = htons(atoi(argv[1]));
+ protop = (strcmp(argv[2], "null") == 0 ||
+ strcmp(argv[2], "NULL") == 0) ? NULL : argv[2];
+\&
+ buflen = 1024;
+ if (argc > 3)
+ buflen = atoi(argv[3]);
+\&
+ if (buflen > MAX_BUF) {
+ printf("Exceeded buffer limit (%d)\en", MAX_BUF);
+ exit(EXIT_FAILURE);
+ }
+\&
+ erange_cnt = 0;
+ do {
+ s = getservbyport_r(port, protop, &result_buf,
+ buf, buflen, &result);
+ if (s == ERANGE) {
+ if (erange_cnt == 0)
+ printf("ERANGE! Retrying with larger buffer\en");
+ erange_cnt++;
+\&
+ /* Increment a byte at a time so we can see exactly
+ what size buffer was required. */
+\&
+ buflen++;
+\&
+ if (buflen > MAX_BUF) {
+ printf("Exceeded buffer limit (%d)\en", MAX_BUF);
+ exit(EXIT_FAILURE);
+ }
+ }
+ } while (s == ERANGE);
+\&
+ printf("getservbyport_r() returned: %s (buflen=%d)\en",
+ (s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
+ strerror(s), buflen);
+\&
+ if (s != 0 || result == NULL) {
+ printf("Call failed/record not found\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ printf("s_name=%s; s_proto=%s; s_port=%d; aliases=",
+ result_buf.s_name, result_buf.s_proto,
+ ntohs(result_buf.s_port));
+ for (char **p = result_buf.s_aliases; *p != NULL; p++)
+ printf("%s ", *p);
+ printf("\en");
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR getservent (3),
+.BR services (5)