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