]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man3/getservent_r.3
bbeb129e8aae3889fdd6923321dc227b13ac9c35
[thirdparty/man-pages.git] / man3 / getservent_r.3
1 .\" Copyright 2008, Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH GETSERVENT_R 3 2021-03-22 "Linux man-pages (unreleased)" "Linux Programmer's Manual"
7 .SH NAME
8 getservent_r, getservbyname_r, getservbyport_r \- get
9 service entry (reentrant)
10 .SH LIBRARY
11 Standard C library
12 .RI ( libc ", " \-lc )
13 .SH SYNOPSIS
14 .nf
15 .B #include <netdb.h>
16 .PP
17 .BI "int getservent_r(struct servent *restrict " result_buf ,
18 .BI " char *restrict " buf ", size_t " buflen ,
19 .BI " struct servent **restrict " result );
20 .BI "int getservbyname_r(const char *restrict " name ,
21 .BI " const char *restrict " proto ,
22 .BI " struct servent *restrict " result_buf ,
23 .BI " char *restrict " buf ", size_t " buflen ,
24 .BI " struct servent **restrict " result );
25 .BI "int getservbyport_r(int " port ,
26 .BI " const char *restrict " proto ,
27 .BI " struct servent *restrict " result_buf ,
28 .BI " char *restrict " buf ", size_t " buflen ,
29 .BI " struct servent **restrict " result );
30 .PP
31 .fi
32 .RS -4
33 Feature Test Macro Requirements for glibc (see
34 .BR feature_test_macros (7)):
35 .RE
36 .PP
37 .BR getservent_r (),
38 .BR getservbyname_r (),
39 .BR getservbyport_r ():
40 .nf
41 Since glibc 2.19:
42 _DEFAULT_SOURCE
43 Glibc 2.19 and earlier:
44 _BSD_SOURCE || _SVID_SOURCE
45 .fi
46 .SH DESCRIPTION
47 The
48 .BR getservent_r (),
49 .BR getservbyname_r (),
50 and
51 .BR getservbyport_r ()
52 functions are the reentrant equivalents of, respectively,
53 .BR getservent (3),
54 .BR getservbyname (3),
55 and
56 .BR getservbyport (3).
57 They differ in the way that the
58 .I servent
59 structure is returned,
60 and in the function calling signature and return value.
61 This manual page describes just the differences from
62 the nonreentrant functions.
63 .PP
64 Instead of returning a pointer to a statically allocated
65 .I servent
66 structure as the function result,
67 these functions copy the structure into the location pointed to by
68 .IR result_buf .
69 .PP
70 The
71 .I buf
72 array is used to store the string fields pointed to by the returned
73 .I servent
74 structure.
75 (The nonreentrant functions allocate these strings in static storage.)
76 The size of this array is specified in
77 .IR buflen .
78 If
79 .I buf
80 is too small, the call fails with the error
81 .BR ERANGE ,
82 and the caller must try again with a larger buffer.
83 (A buffer of length 1024 bytes should be sufficient for most applications.)
84 .\" I can find no information on the required/recommended buffer size;
85 .\" the nonreentrant functions use a 1024 byte buffer -- mtk.
86 .PP
87 If the function call successfully obtains a service record, then
88 .I *result
89 is set pointing to
90 .IR result_buf ;
91 otherwise,
92 .I *result
93 is set to NULL.
94 .SH RETURN VALUE
95 On success, these functions return 0.
96 On error, they return one of the positive error numbers listed in errors.
97 .PP
98 On error, record not found
99 .RB ( getservbyname_r (),
100 .BR getservbyport_r ()),
101 or end of input
102 .RB ( getservent_r ())
103 .I result
104 is set to NULL.
105 .SH ERRORS
106 .TP
107 .B ENOENT
108 .RB ( getservent_r ())
109 No more records in database.
110 .TP
111 .B ERANGE
112 .I buf
113 is too small.
114 Try again with a larger buffer
115 (and increased
116 .IR buflen ).
117 .SH ATTRIBUTES
118 For an explanation of the terms used in this section, see
119 .BR attributes (7).
120 .ad l
121 .nh
122 .TS
123 allbox;
124 lbx lb lb
125 l l l.
126 Interface Attribute Value
127 T{
128 .BR getservent_r (),
129 .BR getservbyname_r (),
130 .BR getservbyport_r ()
131 T} Thread safety MT-Safe locale
132 .TE
133 .hy
134 .ad
135 .sp 1
136 .SH STANDARDS
137 These functions are GNU extensions.
138 Functions with similar names exist on some other systems,
139 though typically with different calling signatures.
140 .SH EXAMPLES
141 The program below uses
142 .BR getservbyport_r ()
143 to retrieve the service record for the port and protocol named
144 in its first command-line argument.
145 If a third (integer) command-line argument is supplied,
146 it is used as the initial value for
147 .IR buflen ;
148 if
149 .BR getservbyport_r ()
150 fails with the error
151 .BR ERANGE ,
152 the program retries with larger buffer sizes.
153 The following shell session shows a couple of sample runs:
154 .PP
155 .in +4n
156 .EX
157 .RB "$" " ./a.out 7 tcp 1"
158 ERANGE! Retrying with larger buffer
159 getservbyport_r() returned: 0 (success) (buflen=87)
160 s_name=echo; s_proto=tcp; s_port=7; aliases=
161 .RB "$" " ./a.out 77777 tcp"
162 getservbyport_r() returned: 0 (success) (buflen=1024)
163 Call failed/record not found
164 .EE
165 .in
166 .SS Program source
167 \&
168 .EX
169 #define _GNU_SOURCE
170 #include <ctype.h>
171 #include <netdb.h>
172 #include <stdlib.h>
173 #include <stdio.h>
174 #include <errno.h>
175 #include <string.h>
176
177 #define MAX_BUF 10000
178
179 int
180 main(int argc, char *argv[])
181 {
182 int buflen, erange_cnt, port, s;
183 struct servent result_buf;
184 struct servent *result;
185 char buf[MAX_BUF];
186 char *protop;
187
188 if (argc < 3) {
189 printf("Usage: %s port\-num proto\-name [buflen]\en", argv[0]);
190 exit(EXIT_FAILURE);
191 }
192
193 port = htons(atoi(argv[1]));
194 protop = (strcmp(argv[2], "null") == 0 ||
195 strcmp(argv[2], "NULL") == 0) ? NULL : argv[2];
196
197 buflen = 1024;
198 if (argc > 3)
199 buflen = atoi(argv[3]);
200
201 if (buflen > MAX_BUF) {
202 printf("Exceeded buffer limit (%d)\en", MAX_BUF);
203 exit(EXIT_FAILURE);
204 }
205
206 erange_cnt = 0;
207 do {
208 s = getservbyport_r(port, protop, &result_buf,
209 buf, buflen, &result);
210 if (s == ERANGE) {
211 if (erange_cnt == 0)
212 printf("ERANGE! Retrying with larger buffer\en");
213 erange_cnt++;
214
215 /* Increment a byte at a time so we can see exactly
216 what size buffer was required. */
217
218 buflen++;
219
220 if (buflen > MAX_BUF) {
221 printf("Exceeded buffer limit (%d)\en", MAX_BUF);
222 exit(EXIT_FAILURE);
223 }
224 }
225 } while (s == ERANGE);
226
227 printf("getservbyport_r() returned: %s (buflen=%d)\en",
228 (s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
229 strerror(s), buflen);
230
231 if (s != 0 || result == NULL) {
232 printf("Call failed/record not found\en");
233 exit(EXIT_FAILURE);
234 }
235
236 printf("s_name=%s; s_proto=%s; s_port=%d; aliases=",
237 result_buf.s_name, result_buf.s_proto,
238 ntohs(result_buf.s_port));
239 for (char **p = result_buf.s_aliases; *p != NULL; p++)
240 printf("%s ", *p);
241 printf("\en");
242
243 exit(EXIT_SUCCESS);
244 }
245 .EE
246 .SH SEE ALSO
247 .BR getservent (3),
248 .BR services (5)