1getservent_r(3) Library Functions Manual getservent_r(3)
2
3
4
6 getservent_r, getservbyname_r, getservbyport_r - get service entry
7 (reentrant)
8
10 Standard C library (libc, -lc)
11
13 #include <netdb.h>
14
15 int getservent_r(struct servent *restrict result_buf,
16 char buf[restrict .buflen], size_t buflen,
17 struct servent **restrict result);
18 int getservbyname_r(const char *restrict name,
19 const char *restrict proto,
20 struct servent *restrict result_buf,
21 char buf[restrict .buflen], size_t buflen,
22 struct servent **restrict result);
23 int getservbyport_r(int port,
24 const char *restrict proto,
25 struct servent *restrict result_buf,
26 char buf[restrict .buflen], size_t buflen,
27 struct servent **restrict result);
28
29 Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
30
31 getservent_r(), getservbyname_r(), getservbyport_r():
32 Since glibc 2.19:
33 _DEFAULT_SOURCE
34 glibc 2.19 and earlier:
35 _BSD_SOURCE || _SVID_SOURCE
36
38 The getservent_r(), getservbyname_r(), and getservbyport_r() functions
39 are the reentrant equivalents of, respectively, getservent(3), get‐
40 servbyname(3), and getservbyport(3). They differ in the way that the
41 servent structure is returned, and in the function calling signature
42 and return value. This manual page describes just the differences from
43 the nonreentrant functions.
44
45 Instead of returning a pointer to a statically allocated servent struc‐
46 ture as the function result, these functions copy the structure into
47 the location pointed to by result_buf.
48
49 The buf array is used to store the string fields pointed to by the re‐
50 turned servent structure. (The nonreentrant functions allocate these
51 strings in static storage.) The size of this array is specified in bu‐
52 flen. If buf is too small, the call fails with the error ERANGE, and
53 the caller must try again with a larger buffer. (A buffer of length
54 1024 bytes should be sufficient for most applications.)
55
56 If the function call successfully obtains a service record, then *re‐
57 sult is set pointing to result_buf; otherwise, *result is set to NULL.
58
60 On success, these functions return 0. On error, they return one of the
61 positive error numbers listed in errors.
62
63 On error, record not found (getservbyname_r(), getservbyport_r()), or
64 end of input (getservent_r()) result is set to NULL.
65
67 ENOENT (getservent_r()) No more records in database.
68
69 ERANGE buf is too small. Try again with a larger buffer (and increased
70 buflen).
71
73 For an explanation of the terms used in this section, see at‐
74 tributes(7).
75
76 ┌─────────────────────────────────────┬───────────────┬────────────────┐
77 │Interface │ Attribute │ Value │
78 ├─────────────────────────────────────┼───────────────┼────────────────┤
79 │getservent_r(), getservbyname_r(), │ Thread safety │ MT-Safe locale │
80 │getservbyport_r() │ │ │
81 └─────────────────────────────────────┴───────────────┴────────────────┘
82
84 Functions with similar names exist on some other systems, though
85 typically with different calling signatures.
86
88 GNU.
89
91 The program below uses getservbyport_r() to retrieve the service record
92 for the port and protocol named in its first command-line argument. If
93 a third (integer) command-line argument is supplied, it is used as the
94 initial value for buflen; if getservbyport_r() fails with the error
95 ERANGE, the program retries with larger buffer sizes. The following
96 shell session shows a couple of sample runs:
97
98 $ ./a.out 7 tcp 1
99 ERANGE! Retrying with larger buffer
100 getservbyport_r() returned: 0 (success) (buflen=87)
101 s_name=echo; s_proto=tcp; s_port=7; aliases=
102 $ ./a.out 77777 tcp
103 getservbyport_r() returned: 0 (success) (buflen=1024)
104 Call failed/record not found
105
106 Program source
107
108 #define _GNU_SOURCE
109 #include <ctype.h>
110 #include <errno.h>
111 #include <netdb.h>
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <string.h>
115
116 #define MAX_BUF 10000
117
118 int
119 main(int argc, char *argv[])
120 {
121 int buflen, erange_cnt, port, s;
122 struct servent result_buf;
123 struct servent *result;
124 char buf[MAX_BUF];
125 char *protop;
126
127 if (argc < 3) {
128 printf("Usage: %s port-num proto-name [buflen]\n", argv[0]);
129 exit(EXIT_FAILURE);
130 }
131
132 port = htons(atoi(argv[1]));
133 protop = (strcmp(argv[2], "null") == 0 ||
134 strcmp(argv[2], "NULL") == 0) ? NULL : argv[2];
135
136 buflen = 1024;
137 if (argc > 3)
138 buflen = atoi(argv[3]);
139
140 if (buflen > MAX_BUF) {
141 printf("Exceeded buffer limit (%d)\n", MAX_BUF);
142 exit(EXIT_FAILURE);
143 }
144
145 erange_cnt = 0;
146 do {
147 s = getservbyport_r(port, protop, &result_buf,
148 buf, buflen, &result);
149 if (s == ERANGE) {
150 if (erange_cnt == 0)
151 printf("ERANGE! Retrying with larger buffer\n");
152 erange_cnt++;
153
154 /* Increment a byte at a time so we can see exactly
155 what size buffer was required. */
156
157 buflen++;
158
159 if (buflen > MAX_BUF) {
160 printf("Exceeded buffer limit (%d)\n", MAX_BUF);
161 exit(EXIT_FAILURE);
162 }
163 }
164 } while (s == ERANGE);
165
166 printf("getservbyport_r() returned: %s (buflen=%d)\n",
167 (s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
168 strerror(s), buflen);
169
170 if (s != 0 || result == NULL) {
171 printf("Call failed/record not found\n");
172 exit(EXIT_FAILURE);
173 }
174
175 printf("s_name=%s; s_proto=%s; s_port=%d; aliases=",
176 result_buf.s_name, result_buf.s_proto,
177 ntohs(result_buf.s_port));
178 for (char **p = result_buf.s_aliases; *p != NULL; p++)
179 printf("%s ", *p);
180 printf("\n");
181
182 exit(EXIT_SUCCESS);
183 }
184
186 getservent(3), services(5)
187
188
189
190Linux man-pages 6.05 2023-07-20 getservent_r(3)