Sat Nov 7 16:58:24 2015 UTC ()
Put back NULL tests for allocation failures.


(christos)
diff -r1.27 -r1.28 src/include/rpc/svc.h
diff -r1.6 -r1.7 src/lib/libc/rpc/svc_fdset.c

cvs diff -r1.27 -r1.28 src/include/rpc/svc.h (switch to unified diff)

--- src/include/rpc/svc.h 2015/11/06 19:42:57 1.27
+++ src/include/rpc/svc.h 2015/11/07 16:58:24 1.28
@@ -1,437 +1,437 @@ @@ -1,437 +1,437 @@
1/* $NetBSD: svc.h,v 1.27 2015/11/06 19:42:57 christos Exp $ */ 1/* $NetBSD: svc.h,v 1.28 2015/11/07 16:58:24 christos Exp $ */
2 2
3/* 3/*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape 5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users 6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized 7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or 8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user. 9 * program developed by the user.
10 * 10 *
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * 14 *
15 * Sun RPC is provided with no support and without any obligation on the 15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement. 17 * modification or enhancement.
18 * 18 *
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF. 21 * OR ANY PART THEREOF.
22 * 22 *
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if 24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages. 25 * Sun has been advised of the possibility of such damages.
26 * 26 *
27 * Sun Microsystems, Inc. 27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue 28 * 2550 Garcia Avenue
29 * Mountain View, California 94043 29 * Mountain View, California 94043
30 * 30 *
31 * from: @(#)svc.h 1.35 88/12/17 SMI 31 * from: @(#)svc.h 1.35 88/12/17 SMI
32 * @(#)svc.h 1.27 94/04/25 SMI 32 * @(#)svc.h 1.27 94/04/25 SMI
33 */ 33 */
34 34
35/* 35/*
36 * svc.h, Server-side remote procedure call interface. 36 * svc.h, Server-side remote procedure call interface.
37 * 37 *
38 * Copyright (C) 1986-1993 by Sun Microsystems, Inc. 38 * Copyright (C) 1986-1993 by Sun Microsystems, Inc.
39 */ 39 */
40 40
41#ifndef _RPC_SVC_H_ 41#ifndef _RPC_SVC_H_
42#define _RPC_SVC_H_ 42#define _RPC_SVC_H_
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44 44
45#include <rpc/rpc_com.h> 45#include <rpc/rpc_com.h>
46 46
47/* 47/*
48 * This interface must manage two items concerning remote procedure calling: 48 * This interface must manage two items concerning remote procedure calling:
49 * 49 *
50 * 1) An arbitrary number of transport connections upon which rpc requests 50 * 1) An arbitrary number of transport connections upon which rpc requests
51 * are received. The two most notable transports are TCP and UDP; they are 51 * are received. The two most notable transports are TCP and UDP; they are
52 * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 52 * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
53 * they in turn call xprt_register and xprt_unregister. 53 * they in turn call xprt_register and xprt_unregister.
54 * 54 *
55 * 2) An arbitrary number of locally registered services. Services are 55 * 2) An arbitrary number of locally registered services. Services are
56 * described by the following four data: program number, version number, 56 * described by the following four data: program number, version number,
57 * "service dispatch" function, a transport handle, and a boolean that 57 * "service dispatch" function, a transport handle, and a boolean that
58 * indicates whether or not the exported program should be registered with a 58 * indicates whether or not the exported program should be registered with a
59 * local binder service; if true the program's number and version and the 59 * local binder service; if true the program's number and version and the
60 * port number from the transport handle are registered with the binder. 60 * port number from the transport handle are registered with the binder.
61 * These data are registered with the rpc svc system via svc_register. 61 * These data are registered with the rpc svc system via svc_register.
62 * 62 *
63 * A service's dispatch function is called whenever an rpc request comes in 63 * A service's dispatch function is called whenever an rpc request comes in
64 * on a transport. The request's program and version numbers must match 64 * on a transport. The request's program and version numbers must match
65 * those of the registered service. The dispatch function is passed two 65 * those of the registered service. The dispatch function is passed two
66 * parameters, struct svc_req * and SVCXPRT *, defined below. 66 * parameters, struct svc_req * and SVCXPRT *, defined below.
67 */ 67 */
68 68
69/* 69/*
70 * Service control requests 70 * Service control requests
71 */ 71 */
72#define SVCGET_VERSQUIET 1 72#define SVCGET_VERSQUIET 1
73#define SVCSET_VERSQUIET 2 73#define SVCSET_VERSQUIET 2
74#define SVCGET_CONNMAXREC 3 74#define SVCGET_CONNMAXREC 3
75#define SVCSET_CONNMAXREC 4 75#define SVCSET_CONNMAXREC 4
76 76
77 77
78enum xprt_stat { 78enum xprt_stat {
79 XPRT_DIED, 79 XPRT_DIED,
80 XPRT_MOREREQS, 80 XPRT_MOREREQS,
81 XPRT_IDLE 81 XPRT_IDLE
82}; 82};
83 83
84/* 84/*
85 * Server side transport handle 85 * Server side transport handle
86 */ 86 */
87typedef struct __rpc_svcxprt { 87typedef struct __rpc_svcxprt {
88 int xp_fd; 88 int xp_fd;
89 u_short xp_port; /* associated port number */ 89 u_short xp_port; /* associated port number */
90 const struct xp_ops { 90 const struct xp_ops {
91 /* receive incomming requests */ 91 /* receive incomming requests */
92 bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); 92 bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *);
93 /* get transport status */ 93 /* get transport status */
94 enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 94 enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *);
95 /* get arguments */ 95 /* get arguments */
96 bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, 96 bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t,
97 caddr_t); 97 caddr_t);
98 /* send reply */ 98 /* send reply */
99 bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); 99 bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *);
100 /* free mem allocated for args */ 100 /* free mem allocated for args */
101 bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, 101 bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t,
102 caddr_t); 102 caddr_t);
103 /* destroy this struct */ 103 /* destroy this struct */
104 void (*xp_destroy)(struct __rpc_svcxprt *); 104 void (*xp_destroy)(struct __rpc_svcxprt *);
105 } *xp_ops; 105 } *xp_ops;
106 int xp_addrlen; /* length of remote address */ 106 int xp_addrlen; /* length of remote address */
107 struct sockaddr_in xp_raddr; /* rem. addr. (backward ABI compat) */ 107 struct sockaddr_in xp_raddr; /* rem. addr. (backward ABI compat) */
108 /* XXX - fvdl stick this here for ABI backward compat reasons */ 108 /* XXX - fvdl stick this here for ABI backward compat reasons */
109 const struct xp_ops2 { 109 const struct xp_ops2 {
110 /* catch-all function */ 110 /* catch-all function */
111 bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, 111 bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int,
112 void *); 112 void *);
113 } *xp_ops2; 113 } *xp_ops2;
114 char *xp_tp; /* transport provider device name */ 114 char *xp_tp; /* transport provider device name */
115 char *xp_netid; /* network token */ 115 char *xp_netid; /* network token */
116 struct netbuf xp_ltaddr; /* local transport address */ 116 struct netbuf xp_ltaddr; /* local transport address */
117 struct netbuf xp_rtaddr; /* remote transport address */ 117 struct netbuf xp_rtaddr; /* remote transport address */
118 struct opaque_auth xp_verf; /* raw response verifier */ 118 struct opaque_auth xp_verf; /* raw response verifier */
119 void *xp_p1; /* private: for use by svc ops */ 119 void *xp_p1; /* private: for use by svc ops */
120 void *xp_p2; /* private: for use by svc ops */ 120 void *xp_p2; /* private: for use by svc ops */
121 void *xp_p3; /* private: for use by svc lib */ 121 void *xp_p3; /* private: for use by svc lib */
122 int xp_type; /* transport type */ 122 int xp_type; /* transport type */
123} SVCXPRT; 123} SVCXPRT;
124 124
125/* 125/*
126 * Service request 126 * Service request
127 */ 127 */
128struct svc_req { 128struct svc_req {
129 uint32_t rq_prog; /* service program number */ 129 uint32_t rq_prog; /* service program number */
130 uint32_t rq_vers; /* service protocol version */ 130 uint32_t rq_vers; /* service protocol version */
131 uint32_t rq_proc; /* the desired procedure */ 131 uint32_t rq_proc; /* the desired procedure */
132 struct opaque_auth rq_cred; /* raw creds from the wire */ 132 struct opaque_auth rq_cred; /* raw creds from the wire */
133 void *rq_clntcred; /* read only cooked cred */ 133 void *rq_clntcred; /* read only cooked cred */
134 SVCXPRT *rq_xprt; /* associated transport */ 134 SVCXPRT *rq_xprt; /* associated transport */
135}; 135};
136 136
137/* 137/*
138 * Approved way of getting address of caller 138 * Approved way of getting address of caller
139 */ 139 */
140#define svc_getrpccaller(x) (&(x)->xp_rtaddr) 140#define svc_getrpccaller(x) (&(x)->xp_rtaddr)
141 141
142/* 142/*
143 * NetBSD-only definition to get the creds of the caller (AF_LOCAL). 143 * NetBSD-only definition to get the creds of the caller (AF_LOCAL).
144 */ 144 */
145#define __svc_getcallercreds(x) ((struct sockcred *)(x)->xp_p2) 145#define __svc_getcallercreds(x) ((struct sockcred *)(x)->xp_p2)
146 146
147/* 147/*
148 * Operations defined on an SVCXPRT handle 148 * Operations defined on an SVCXPRT handle
149 * 149 *
150 * SVCXPRT *xprt; 150 * SVCXPRT *xprt;
151 * struct rpc_msg *msg; 151 * struct rpc_msg *msg;
152 * xdrproc_t xargs; 152 * xdrproc_t xargs;
153 * caddr_t argsp; 153 * caddr_t argsp;
154 */ 154 */
155#define SVC_RECV(xprt, msg) \ 155#define SVC_RECV(xprt, msg) \
156 (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 156 (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
157#define svc_recv(xprt, msg) \ 157#define svc_recv(xprt, msg) \
158 (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 158 (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
159 159
160#define SVC_STAT(xprt) \ 160#define SVC_STAT(xprt) \
161 (*(xprt)->xp_ops->xp_stat)(xprt) 161 (*(xprt)->xp_ops->xp_stat)(xprt)
162#define svc_stat(xprt) \ 162#define svc_stat(xprt) \
163 (*(xprt)->xp_ops->xp_stat)(xprt) 163 (*(xprt)->xp_ops->xp_stat)(xprt)
164 164
165#define SVC_GETARGS(xprt, xargs, argsp) \ 165#define SVC_GETARGS(xprt, xargs, argsp) \
166 (*(xprt)->xp_ops->xp_getargs)((xprt), ((xdrproc_t)(xargs)), (argsp)) 166 (*(xprt)->xp_ops->xp_getargs)((xprt), ((xdrproc_t)(xargs)), (argsp))
167#define svc_getargs(xprt, xargs, argsp) \ 167#define svc_getargs(xprt, xargs, argsp) \
168 (*(xprt)->xp_ops->xp_getargs)((xprt), ((xdrproc_t)(xargs)), (argsp)) 168 (*(xprt)->xp_ops->xp_getargs)((xprt), ((xdrproc_t)(xargs)), (argsp))
169 169
170#define SVC_REPLY(xprt, msg) \ 170#define SVC_REPLY(xprt, msg) \
171 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 171 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
172#define svc_reply(xprt, msg) \ 172#define svc_reply(xprt, msg) \
173 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 173 (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
174 174
175#define SVC_FREEARGS(xprt, xargs, argsp) \ 175#define SVC_FREEARGS(xprt, xargs, argsp) \
176 (*(xprt)->xp_ops->xp_freeargs)((xprt), ((xdrproc_t)(xargs)), (argsp)) 176 (*(xprt)->xp_ops->xp_freeargs)((xprt), ((xdrproc_t)(xargs)), (argsp))
177#define svc_freeargs(xprt, xargs, argsp) \ 177#define svc_freeargs(xprt, xargs, argsp) \
178 (*(xprt)->xp_ops->xp_freeargs)((xprt), ((xdrproc_t)(xargs)), (argsp)) 178 (*(xprt)->xp_ops->xp_freeargs)((xprt), ((xdrproc_t)(xargs)), (argsp))
179 179
180#define SVC_DESTROY(xprt) \ 180#define SVC_DESTROY(xprt) \
181 (*(xprt)->xp_ops->xp_destroy)(xprt) 181 (*(xprt)->xp_ops->xp_destroy)(xprt)
182#define svc_destroy(xprt) \ 182#define svc_destroy(xprt) \
183 (*(xprt)->xp_ops->xp_destroy)(xprt) 183 (*(xprt)->xp_ops->xp_destroy)(xprt)
184 184
185#define SVC_CONTROL(xprt, rq, in) \ 185#define SVC_CONTROL(xprt, rq, in) \
186 (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) 186 (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in))
187 187
188/* 188/*
189 * Service registration 189 * Service registration
190 * 190 *
191 * svc_reg(xprt, prog, vers, dispatch, nconf) 191 * svc_reg(xprt, prog, vers, dispatch, nconf)
192 * const SVCXPRT *xprt; 192 * const SVCXPRT *xprt;
193 * const rpcprog_t prog; 193 * const rpcprog_t prog;
194 * const rpcvers_t vers; 194 * const rpcvers_t vers;
195 * const void (*dispatch)(...); 195 * const void (*dispatch)(...);
196 * const struct netconfig *nconf; 196 * const struct netconfig *nconf;
197 */ 197 */
198 198
199__BEGIN_DECLS 199__BEGIN_DECLS
200extern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, 200extern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t,
201 void (*)(struct svc_req *, SVCXPRT *), 201 void (*)(struct svc_req *, SVCXPRT *),
202 const struct netconfig *); 202 const struct netconfig *);
203__END_DECLS 203__END_DECLS
204 204
205/* 205/*
206 * Service un-registration 206 * Service un-registration
207 * 207 *
208 * svc_unreg(prog, vers) 208 * svc_unreg(prog, vers)
209 * const rpcprog_t prog; 209 * const rpcprog_t prog;
210 * const rpcvers_t vers; 210 * const rpcvers_t vers;
211 */ 211 */
212 212
213__BEGIN_DECLS 213__BEGIN_DECLS
214extern void svc_unreg(const rpcprog_t, const rpcvers_t); 214extern void svc_unreg(const rpcprog_t, const rpcvers_t);
215__END_DECLS 215__END_DECLS
216 216
217/* 217/*
218 * Transport registration. 218 * Transport registration.
219 * 219 *
220 * xprt_register(xprt) 220 * xprt_register(xprt)
221 * SVCXPRT *xprt; 221 * SVCXPRT *xprt;
222 */ 222 */
223__BEGIN_DECLS 223__BEGIN_DECLS
224extern bool_t xprt_register (SVCXPRT *); 224extern bool_t xprt_register (SVCXPRT *);
225__END_DECLS 225__END_DECLS
226 226
227/* 227/*
228 * Transport un-register 228 * Transport un-register
229 * 229 *
230 * xprt_unregister(xprt) 230 * xprt_unregister(xprt)
231 * SVCXPRT *xprt; 231 * SVCXPRT *xprt;
232 */ 232 */
233__BEGIN_DECLS 233__BEGIN_DECLS
234extern void xprt_unregister (SVCXPRT *); 234extern void xprt_unregister (SVCXPRT *);
235__END_DECLS 235__END_DECLS
236 236
237 237
238/* 238/*
239 * When the service routine is called, it must first check to see if it 239 * When the service routine is called, it must first check to see if it
240 * knows about the procedure; if not, it should call svcerr_noproc 240 * knows about the procedure; if not, it should call svcerr_noproc
241 * and return. If so, it should deserialize its arguments via 241 * and return. If so, it should deserialize its arguments via
242 * SVC_GETARGS (defined above). If the deserialization does not work, 242 * SVC_GETARGS (defined above). If the deserialization does not work,
243 * svcerr_decode should be called followed by a return. Successful 243 * svcerr_decode should be called followed by a return. Successful
244 * decoding of the arguments should be followed the execution of the 244 * decoding of the arguments should be followed the execution of the
245 * procedure's code and a call to svc_sendreply. 245 * procedure's code and a call to svc_sendreply.
246 * 246 *
247 * Also, if the service refuses to execute the procedure due to too- 247 * Also, if the service refuses to execute the procedure due to too-
248 * weak authentication parameters, svcerr_weakauth should be called. 248 * weak authentication parameters, svcerr_weakauth should be called.
249 * Note: do not confuse access-control failure with weak authentication! 249 * Note: do not confuse access-control failure with weak authentication!
250 * 250 *
251 * NB: In pure implementations of rpc, the caller always waits for a reply 251 * NB: In pure implementations of rpc, the caller always waits for a reply
252 * msg. This message is sent when svc_sendreply is called. 252 * msg. This message is sent when svc_sendreply is called.
253 * Therefore pure service implementations should always call 253 * Therefore pure service implementations should always call
254 * svc_sendreply even if the function logically returns void; use 254 * svc_sendreply even if the function logically returns void; use
255 * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 255 * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows
256 * for the abuse of pure rpc via batched calling or pipelining. In the 256 * for the abuse of pure rpc via batched calling or pipelining. In the
257 * case of a batched call, svc_sendreply should NOT be called since 257 * case of a batched call, svc_sendreply should NOT be called since
258 * this would send a return message, which is what batching tries to avoid. 258 * this would send a return message, which is what batching tries to avoid.
259 * It is the service/protocol writer's responsibility to know which calls are 259 * It is the service/protocol writer's responsibility to know which calls are
260 * batched and which are not. Warning: responding to batch calls may 260 * batched and which are not. Warning: responding to batch calls may
261 * deadlock the caller and server processes! 261 * deadlock the caller and server processes!
262 */ 262 */
263 263
264__BEGIN_DECLS 264__BEGIN_DECLS
265extern bool_t svc_sendreply (SVCXPRT *, xdrproc_t, const char *); 265extern bool_t svc_sendreply (SVCXPRT *, xdrproc_t, const char *);
266extern void svcerr_decode (SVCXPRT *); 266extern void svcerr_decode (SVCXPRT *);
267extern void svcerr_weakauth (SVCXPRT *); 267extern void svcerr_weakauth (SVCXPRT *);
268extern void svcerr_noproc (SVCXPRT *); 268extern void svcerr_noproc (SVCXPRT *);
269extern void svcerr_progvers (SVCXPRT *, rpcvers_t, rpcvers_t); 269extern void svcerr_progvers (SVCXPRT *, rpcvers_t, rpcvers_t);
270extern void svcerr_auth (SVCXPRT *, enum auth_stat); 270extern void svcerr_auth (SVCXPRT *, enum auth_stat);
271extern void svcerr_noprog (SVCXPRT *); 271extern void svcerr_noprog (SVCXPRT *);
272extern void svcerr_systemerr(SVCXPRT *); 272extern void svcerr_systemerr(SVCXPRT *);
273extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, 273extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t,
274 char *(*)(char *), xdrproc_t, xdrproc_t, 274 char *(*)(char *), xdrproc_t, xdrproc_t,
275 char *); 275 char *);
276__END_DECLS 276__END_DECLS
277 277
278/* 278/*
279 * Lowest level dispatching -OR- who owns this process anyway. 279 * Lowest level dispatching -OR- who owns this process anyway.
280 * Somebody has to wait for incoming requests and then call the correct 280 * Somebody has to wait for incoming requests and then call the correct
281 * service routine. The routine svc_run does infinite waiting; i.e., 281 * service routine. The routine svc_run does infinite waiting; i.e.,
282 * svc_run never returns. 282 * svc_run never returns.
283 * Since another (co-existent) package may wish to selectively wait for 283 * Since another (co-existent) package may wish to selectively wait for
284 * incoming calls or other events outside of the rpc architecture, the 284 * incoming calls or other events outside of the rpc architecture, the
285 * routine svc_getreq is provided. It must be passed readfds, the 285 * routine svc_getreq is provided. It must be passed readfds, the
286 * "in-place" results of a select system call (see select, section 2). 286 * "in-place" results of a select system call (see select, section 2).
287 */ 287 */
288 288
289/* 289/*
290 * Global keeper of rpc service descriptors in use 290 * Global keeper of rpc service descriptors in use
291 * dynamic; must be inspected before each call to select 291 * dynamic; must be inspected before each call to select
292 */ 292 */
293#ifdef SVC_LEGACY 293#ifdef SVC_LEGACY
294extern int svc_maxfd; 294extern int svc_maxfd;
295extern fd_set svc_fdset; 295extern fd_set svc_fdset;
296#else 296#else
297#define svc_maxfd (*svc_fdset_getmax()) 297#define svc_maxfd (*svc_fdset_getmax())
298#define svc_fdset (*svc_fdset_get()) 298#define svc_fdset (*svc_fdset_get())
299#endif 299#endif
300 300
301#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 301#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
302 302
303/* 303/*
304 * a small program implemented by the svc_rpc implementation itself; 304 * a small program implemented by the svc_rpc implementation itself;
305 * also see clnt.h for protocol numbers. 305 * also see clnt.h for protocol numbers.
306 */ 306 */
307__BEGIN_DECLS 307__BEGIN_DECLS
308extern void rpctest_service(void); 308extern void rpctest_service(void);
309__END_DECLS 309__END_DECLS
310 310
311__BEGIN_DECLS 311__BEGIN_DECLS
312 312
313#define SVC_FDSET_MT 1 313#define SVC_FDSET_MT 1
314extern void svc_fdset_init(int); 314extern void svc_fdset_init(int);
315extern fd_set *svc_fdset_copy(const fd_set *); 315extern fd_set *svc_fdset_copy(const fd_set *);
316 316
317extern void svc_fdset_zero(void); 317extern void svc_fdset_zero(void);
318extern int svc_fdset_isset(int); 318extern int svc_fdset_isset(int);
319extern void svc_fdset_clr(int); 319extern int svc_fdset_clr(int);
320extern void svc_fdset_set(int); 320extern int svc_fdset_set(int);
321 321
322extern fd_set *svc_fdset_get(void); 322extern fd_set *svc_fdset_get(void);
323extern int svc_fdset_getsize(int); 323extern int svc_fdset_getsize(int);
324extern int *svc_fdset_getmax(void); 324extern int *svc_fdset_getmax(void);
325 325
326extern void svc_getreq (int); 326extern void svc_getreq (int);
327extern void svc_getreqset (fd_set *); 327extern void svc_getreqset (fd_set *);
328extern void svc_getreqset2 (fd_set *, int); 328extern void svc_getreqset2 (fd_set *, int);
329extern void svc_getreq_common (int); 329extern void svc_getreq_common (int);
330struct pollfd; 330struct pollfd;
331extern void svc_getreq_poll(struct pollfd *, int); 331extern void svc_getreq_poll(struct pollfd *, int);
332 332
333extern void svc_run (void); 333extern void svc_run (void);
334extern void svc_exit (void); 334extern void svc_exit (void);
335__END_DECLS 335__END_DECLS
336 336
337/* 337/*
338 * Socket to use on svcxxx_create call to get default socket 338 * Socket to use on svcxxx_create call to get default socket
339 */ 339 */
340#define RPC_ANYSOCK -1 340#define RPC_ANYSOCK -1
341#define RPC_ANYFD RPC_ANYSOCK 341#define RPC_ANYFD RPC_ANYSOCK
342 342
343/* 343/*
344 * These are the existing service side transport implementations 344 * These are the existing service side transport implementations
345 */ 345 */
346 346
347__BEGIN_DECLS 347__BEGIN_DECLS
348/* 348/*
349 * Transport independent svc_create routine. 349 * Transport independent svc_create routine.
350 */ 350 */
351extern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 351extern int svc_create(void (*)(struct svc_req *, SVCXPRT *),
352 const rpcprog_t, const rpcvers_t, const char *); 352 const rpcprog_t, const rpcvers_t, const char *);
353/* 353/*
354 * void (*dispatch)(...); -- dispatch routine 354 * void (*dispatch)(...); -- dispatch routine
355 * const rpcprog_t prognum; -- program number 355 * const rpcprog_t prognum; -- program number
356 * const rpcvers_t versnum; -- version number 356 * const rpcvers_t versnum; -- version number
357 * const char *nettype; -- network type 357 * const char *nettype; -- network type
358 */ 358 */
359 359
360 360
361/* 361/*
362 * Generic server creation routine. It takes a netconfig structure 362 * Generic server creation routine. It takes a netconfig structure
363 * instead of a nettype. 363 * instead of a nettype.
364 */ 364 */
365 365
366extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 366extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *),
367 const rpcprog_t, const rpcvers_t, 367 const rpcprog_t, const rpcvers_t,
368 const struct netconfig *); 368 const struct netconfig *);
369/* 369/*
370 * void (*dispatch)(...); -- dispatch routine 370 * void (*dispatch)(...); -- dispatch routine
371 * const rpcprog_t prognum; -- program number 371 * const rpcprog_t prognum; -- program number
372 * const rpcvers_t versnum; -- version number 372 * const rpcvers_t versnum; -- version number
373 * const struct netconfig *nconf; -- netconfig structure 373 * const struct netconfig *nconf; -- netconfig structure
374 */ 374 */
375 375
376 376
377/* 377/*
378 * Generic TLI create routine 378 * Generic TLI create routine
379 */ 379 */
380extern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 380extern SVCXPRT *svc_tli_create(const int, const struct netconfig *,
381 const struct t_bind *, const u_int, 381 const struct t_bind *, const u_int,
382 const u_int); 382 const u_int);
383/* 383/*
384 * const int fd; -- connection end point 384 * const int fd; -- connection end point
385 * const struct netconfig *nconf; -- netconfig structure for network 385 * const struct netconfig *nconf; -- netconfig structure for network
386 * const struct t_bind *bindaddr; -- local bind address 386 * const struct t_bind *bindaddr; -- local bind address
387 * const u_int sendsz; -- max sendsize 387 * const u_int sendsz; -- max sendsize
388 * const u_int recvsz; -- max recvsize 388 * const u_int recvsz; -- max recvsize
389 */ 389 */
390 390
391/* 391/*
392 * Connectionless and connectionful create routines 392 * Connectionless and connectionful create routines
393 */ 393 */
394 394
395extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); 395extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int);
396/* 396/*
397 * const int fd; -- open connection end point 397 * const int fd; -- open connection end point
398 * const u_int sendsize; -- max send size 398 * const u_int sendsize; -- max send size
399 * const u_int recvsize; -- max recv size 399 * const u_int recvsize; -- max recv size
400 */ 400 */
401 401
402extern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); 402extern SVCXPRT *svc_dg_create(const int, const u_int, const u_int);
403/* 403/*
404 * const int fd; -- open connection 404 * const int fd; -- open connection
405 * const u_int sendsize; -- max send size 405 * const u_int sendsize; -- max send size
406 * const u_int recvsize; -- max recv size 406 * const u_int recvsize; -- max recv size
407 */ 407 */
408 408
409 409
410/* 410/*
411 * the routine takes any *open* connection 411 * the routine takes any *open* connection
412 * descriptor as its first input and is used for open connections. 412 * descriptor as its first input and is used for open connections.
413 */ 413 */
414extern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); 414extern SVCXPRT *svc_fd_create(const int, const u_int, const u_int);
415/* 415/*
416 * const int fd; -- open connection end point 416 * const int fd; -- open connection end point
417 * const u_int sendsize; -- max send size 417 * const u_int sendsize; -- max send size
418 * const u_int recvsize; -- max recv size 418 * const u_int recvsize; -- max recv size
419 */ 419 */
420 420
421/* 421/*
422 * Memory based rpc (for speed check and testing) 422 * Memory based rpc (for speed check and testing)
423 */ 423 */
424extern SVCXPRT *svc_raw_create(void); 424extern SVCXPRT *svc_raw_create(void);
425 425
426/* 426/*
427 * svc_dg_enable_cache() enables the cache on dg transports. 427 * svc_dg_enable_cache() enables the cache on dg transports.
428 */ 428 */
429int svc_dg_enablecache(SVCXPRT *, const u_int); 429int svc_dg_enablecache(SVCXPRT *, const u_int);
430 430
431__END_DECLS 431__END_DECLS
432 432
433 433
434/* for backward compatibility */ 434/* for backward compatibility */
435#include <rpc/svc_soc.h> 435#include <rpc/svc_soc.h>
436 436
437#endif /* !_RPC_SVC_H_ */ 437#endif /* !_RPC_SVC_H_ */

cvs diff -r1.6 -r1.7 src/lib/libc/rpc/svc_fdset.c (switch to unified diff)

--- src/lib/libc/rpc/svc_fdset.c 2015/11/07 03:06:32 1.6
+++ src/lib/libc/rpc/svc_fdset.c 2015/11/07 16:58:24 1.7
@@ -1,296 +1,316 @@ @@ -1,296 +1,316 @@
1/* $NetBSD: svc_fdset.c,v 1.6 2015/11/07 03:06:32 christos Exp $ */ 1/* $NetBSD: svc_fdset.c,v 1.7 2015/11/07 16:58:24 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights resefdsed. 5 * All rights resefdsed.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: svc_fdset.c,v 1.6 2015/11/07 03:06:32 christos Exp $"); 33__RCSID("$NetBSD: svc_fdset.c,v 1.7 2015/11/07 16:58:24 christos Exp $");
34 34
35 35
36#include "reentrant.h" 36#include "reentrant.h"
37 37
38#include <sys/fd_set.h> 38#include <sys/fd_set.h>
39 39
40#include <rpc/rpc.h> 40#include <rpc/rpc.h>
41 41
42#ifdef FDSET_DEBUG 42#ifdef FDSET_DEBUG
43#include <stdio.h> 43#include <stdio.h>
44#include <stdarg.h> 44#include <stdarg.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <lwp.h> 46#include <lwp.h>
47#endif 47#endif
48#include <stdlib.h> 48#include <stdlib.h>
49#include <string.h> 49#include <string.h>
50 50
51#include "svc_fdset.h" 51#include "svc_fdset.h"
52 52
53#undef svc_fdset 53#undef svc_fdset
54#undef svc_maxfd 54#undef svc_maxfd
55extern __fd_set_256 svc_fdset; 55extern __fd_set_256 svc_fdset;
56extern int svc_maxfd; 56extern int svc_maxfd;
57 57
58struct svc_fdset { 58struct svc_fdset {
59 fd_set *fdset; 59 fd_set *fdset;
60 int fdmax; 60 int fdmax;
61 int fdsize; 61 int fdsize;
62}; 62};
63 63
64/* The single threaded, one global fd_set version */ 64/* The single threaded, one global fd_set version */
65static struct svc_fdset __svc_fdset; 65static struct svc_fdset __svc_fdset;
66 66
67static thread_key_t fdsetkey = -2; 67static thread_key_t fdsetkey = -2;
68 68
69#ifdef FDSET_DEBUG 69#ifdef FDSET_DEBUG
70 70
71static void __printflike(3, 0) 71static void __printflike(3, 0)
72svc_header(const char *func, size_t line, const char *fmt, va_list ap) 72svc_header(const char *func, size_t line, const char *fmt, va_list ap)
73{ 73{
74 fprintf(stderr, "%s[%d.%d]: %s, %zu: ", getprogname(), (int)getpid(), 74 fprintf(stderr, "%s[%d.%d]: %s, %zu: ", getprogname(), (int)getpid(),
75 (int)_lwp_self(), func, line); 75 (int)_lwp_self(), func, line);
76 vfprintf(stderr, fmt, ap); 76 vfprintf(stderr, fmt, ap);
77 va_end(ap); 77 va_end(ap);
78} 78}
79 79
80static void __printflike(4, 5) 80static void __printflike(4, 5)
81svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,  81svc_fdset_print(const char *func, size_t line, struct svc_fdset *fds,
82 const char *fmt, ...) 82 const char *fmt, ...)
83{ 83{
84 va_list ap; 84 va_list ap;
85 const char *did = ""; 85 const char *did = "";
86 86
87 va_start(ap, fmt); 87 va_start(ap, fmt);
88 svc_header(func, line, fmt, ap); 88 svc_header(func, line, fmt, ap);
89 va_end(ap); 89 va_end(ap);
90 90
91 fprintf(stderr, "%p[%d] <", fds->fdset, fds->fdmax); 91 fprintf(stderr, "%p[%d] <", fds->fdset, fds->fdmax);
92 for (int i = 0; i <= fds->fdmax; i++) { 92 for (int i = 0; i <= fds->fdmax; i++) {
93 if (!FD_ISSET(i, fds->fdset)) 93 if (!FD_ISSET(i, fds->fdset))
94 continue; 94 continue;
95 fprintf(stderr, "%s%d", did, i); 95 fprintf(stderr, "%s%d", did, i);
96 did = ", "; 96 did = ", ";
97 } 97 }
98 fprintf(stderr, ">\n"); 98 fprintf(stderr, ">\n");
99} 99}
100 100
101static void __printflike(3, 4) 101static void __printflike(3, 4)
102svc_print(const char *func, size_t line, const char *fmt, ...) 102svc_print(const char *func, size_t line, const char *fmt, ...)
103{ 103{
104 va_list ap; 104 va_list ap;
105 105
106 va_start(ap, fmt); 106 va_start(ap, fmt);
107 svc_header(func, line, fmt, ap); 107 svc_header(func, line, fmt, ap);
108 va_end(ap); 108 va_end(ap);
109 fprintf(stderr, "\n"); 109 fprintf(stderr, "\n");
110} 110}
111 111
112#define DPRINTF(...) svc_print(__func__, __LINE__, __VA_ARGS__) 112#define DPRINTF(...) svc_print(__func__, __LINE__, __VA_ARGS__)
113#define DPRINTF_FDSET(...) svc_fdset_print(__func__, __LINE__, __VA_ARGS__) 113#define DPRINTF_FDSET(...) svc_fdset_print(__func__, __LINE__, __VA_ARGS__)
114 114
115#else 115#else
116 116
117#define DPRINTF(...) 117#define DPRINTF(...)
118#define DPRINTF_FDSET(...) 118#define DPRINTF_FDSET(...)
119 119
120#endif 120#endif
121 121
122 122
123static inline void 123static inline void
124svc_fdset_sanitize(struct svc_fdset *fds) 124svc_fdset_sanitize(struct svc_fdset *fds)
125{ 125{
126 while (fds->fdmax >= 0 && !FD_ISSET(fds->fdmax, fds->fdset)) 126 while (fds->fdmax >= 0 && !FD_ISSET(fds->fdmax, fds->fdset))
127 fds->fdmax--; 127 fds->fdmax--;
128 /* Compat update */ 128 /* Compat update */
129 if (fds == &__svc_fdset) { 129 if (fds == &__svc_fdset) {
130 svc_fdset = *(__fd_set_256 *)__svc_fdset.fdset; 130 svc_fdset = *(__fd_set_256 *)__svc_fdset.fdset;
131 svc_maxfd = __svc_fdset.fdmax; 131 svc_maxfd = __svc_fdset.fdmax;
132 } 132 }
133} 133}
134 134
135static void 135static void
136svc_fdset_free(void *v) 136svc_fdset_free(void *v)
137{ 137{
138 struct svc_fdset *fds = v; 138 struct svc_fdset *fds = v;
139 DPRINTF_FDSET(fds, "free"); 139 DPRINTF_FDSET(fds, "free");
140 140
141 free(fds->fdset); 141 free(fds->fdset);
142 free(fds); 142 free(fds);
143} 143}
144 144
145static struct svc_fdset * 145static struct svc_fdset *
146svc_fdset_resize(int fd, struct svc_fdset *fds) 146svc_fdset_resize(int fd, struct svc_fdset *fds)
147{ 147{
148 if (fds->fdset && fd < fds->fdsize) { 148 if (fds->fdset && fd < fds->fdsize) {
149 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize); 149 DPRINTF_FDSET(fds, "keeping %d < %d", fd, fds->fdsize);
150 return fds; 150 return fds;
151 } 151 }
152 152
153 fd += FD_SETSIZE;  153 fd += FD_SETSIZE;
154 154
155 char *newfdset = realloc(fds->fdset, __NFD_BYTES(fd)); 155 char *newfdset = realloc(fds->fdset, __NFD_BYTES(fd));
156 if (newfdset == NULL) 156 if (newfdset == NULL)
157 return NULL; 157 return NULL;
158 158
159 memset(newfdset + __NFD_BYTES(fds->fdsize), 0, 159 memset(newfdset + __NFD_BYTES(fds->fdsize), 0,
160 __NFD_BYTES(fd) - __NFD_BYTES(fds->fdsize)); 160 __NFD_BYTES(fd) - __NFD_BYTES(fds->fdsize));
161 161
162 162
163 fds->fdset = (void *)newfdset; 163 fds->fdset = (void *)newfdset;
164 DPRINTF_FDSET(fds, "resize %d > %d", fd, fds->fdsize); 164 DPRINTF_FDSET(fds, "resize %d > %d", fd, fds->fdsize);
165 fds->fdsize = fd; 165 fds->fdsize = fd;
166 166
167 return fds; 167 return fds;
168} 168}
169 169
170static struct svc_fdset * 170static struct svc_fdset *
171svc_fdset_alloc(int fd) 171svc_fdset_alloc(int fd)
172{ 172{
173 struct svc_fdset *fds; 173 struct svc_fdset *fds;
174 174
175 if (!__isthreaded || fdsetkey == -2) 175 if (!__isthreaded || fdsetkey == -2)
176 return svc_fdset_resize(fd, &__svc_fdset); 176 return svc_fdset_resize(fd, &__svc_fdset);
177 177
178 if (fdsetkey == -1) 178 if (fdsetkey == -1)
179 thr_keycreate(&fdsetkey, svc_fdset_free); 179 thr_keycreate(&fdsetkey, svc_fdset_free);
180 180
181 if ((fds = thr_getspecific(fdsetkey)) == NULL) { 181 if ((fds = thr_getspecific(fdsetkey)) == NULL) {
182 182
183 fds = calloc(1, sizeof(*fds)); 183 fds = calloc(1, sizeof(*fds));
184 if (fds == NULL) 184 if (fds == NULL)
185 return NULL; 185 return NULL;
186 186
187 (void)thr_setspecific(fdsetkey, fds); 187 (void)thr_setspecific(fdsetkey, fds);
188 188
189 if (__svc_fdset.fdsize != 0) { 189 if (__svc_fdset.fdsize != 0) {
190 *fds = __svc_fdset; 190 *fds = __svc_fdset;
191 DPRINTF("switching to %p", fds->fdset); 191 DPRINTF("switching to %p", fds->fdset);
192 } else { 192 } else {
193 DPRINTF("first thread time %p", fds->fdset); 193 DPRINTF("first thread time %p", fds->fdset);
194 } 194 }
195 } else { 195 } else {
196 DPRINTF("again for %p", fds->fdset); 196 DPRINTF("again for %p", fds->fdset);
197 if (fd < fds->fdsize) 197 if (fd < fds->fdsize)
198 return fds; 198 return fds;
199 } 199 }
200 200
201 return svc_fdset_resize(fd, fds); 201 return svc_fdset_resize(fd, fds);
202} 202}
203 203
204/* allow each thread to have their own copy */ 204/* allow each thread to have their own copy */
205void 205void
206svc_fdset_init(int flags) 206svc_fdset_init(int flags)
207{ 207{
208 DPRINTF("%x", flags); 208 DPRINTF("%x", flags);
209 if ((flags & SVC_FDSET_MT) && fdsetkey == -2) 209 if ((flags & SVC_FDSET_MT) && fdsetkey == -2)
210 fdsetkey = -1; 210 fdsetkey = -1;
211} 211}
212 212
213void 213void
214svc_fdset_zero(void) 214svc_fdset_zero(void)
215{ 215{
216 DPRINTF("zero"); 216 DPRINTF("zero");
217 struct svc_fdset *fds = svc_fdset_alloc(0); 217 struct svc_fdset *fds = svc_fdset_alloc(0);
218 memset(fds->fdset, 0, fds->fdsize); 218 memset(fds->fdset, 0, fds->fdsize);
219 fds->fdmax = -1; 219 fds->fdmax = -1;
220} 220}
221 221
222void 222int
223svc_fdset_set(int fd) 223svc_fdset_set(int fd)
224{ 224{
225 struct svc_fdset *fds = svc_fdset_alloc(fd); 225 struct svc_fdset *fds = svc_fdset_alloc(fd);
226 226
 227 if (fds == NULL)
 228 return -1;
 229
227 FD_SET(fd, fds->fdset); 230 FD_SET(fd, fds->fdset);
228 if (fd > fds->fdmax) 231 if (fd > fds->fdmax)
229 fds->fdmax = fd; 232 fds->fdmax = fd;
230 233
231 DPRINTF_FDSET(fds, "%d", fd); 234 DPRINTF_FDSET(fds, "%d", fd);
232 235
233 svc_fdset_sanitize(fds); 236 svc_fdset_sanitize(fds);
 237 return 0;
234} 238}
235 239
236int 240int
237svc_fdset_isset(int fd) 241svc_fdset_isset(int fd)
238{ 242{
239 struct svc_fdset *fds = svc_fdset_alloc(fd); 243 struct svc_fdset *fds = svc_fdset_alloc(fd);
240 244
 245 if (fds == NULL)
 246 return -1;
 247
241 DPRINTF_FDSET(fds, "%d", fd); 248 DPRINTF_FDSET(fds, "%d", fd);
242 249
243 return FD_ISSET(fd, fds->fdset); 250 return FD_ISSET(fd, fds->fdset) != 0;
244} 251}
245 252
246void 253int
247svc_fdset_clr(int fd) 254svc_fdset_clr(int fd)
248{ 255{
249 struct svc_fdset *fds = svc_fdset_alloc(fd); 256 struct svc_fdset *fds = svc_fdset_alloc(fd);
250 257
 258 if (fds == NULL)
 259 return -1;
 260
251 FD_CLR(fd, fds->fdset); 261 FD_CLR(fd, fds->fdset);
252 DPRINTF_FDSET(fds, "%d", fd); 262 DPRINTF_FDSET(fds, "%d", fd);
253 263
254 svc_fdset_sanitize(fds); 264 svc_fdset_sanitize(fds);
 265 return 0;
255} 266}
256 267
257fd_set * 268fd_set *
258svc_fdset_copy(const fd_set *orig) 269svc_fdset_copy(const fd_set *orig)
259{ 270{
260 int size = svc_fdset_getsize(0); 271 int size = svc_fdset_getsize(0);
261 fd_set *copy = calloc(1, __NFD_BYTES(size)); 272 fd_set *copy = calloc(1, __NFD_BYTES(size));
262 if (copy == NULL) 273 if (copy == NULL)
263 return NULL; 274 return NULL;
264 if (orig) 275 if (orig)
265 memcpy(copy, orig, __NFD_BYTES(size)); 276 memcpy(copy, orig, __NFD_BYTES(size));
266 return copy; 277 return copy;
267} 278}
268 279
269fd_set * 280fd_set *
270svc_fdset_get(void) 281svc_fdset_get(void)
271{ 282{
272 struct svc_fdset *fds = svc_fdset_alloc(0); 283 struct svc_fdset *fds = svc_fdset_alloc(0);
273 284
 285 if (fds == NULL)
 286 return NULL;
 287
274 DPRINTF_FDSET(fds, "get"); 288 DPRINTF_FDSET(fds, "get");
275 svc_fdset_sanitize(fds); 289 svc_fdset_sanitize(fds);
276 return fds->fdset; 290 return fds->fdset;
277} 291}
278 292
279int * 293int *
280svc_fdset_getmax(void) 294svc_fdset_getmax(void)
281{ 295{
282 struct svc_fdset *fds = svc_fdset_alloc(0); 296 struct svc_fdset *fds = svc_fdset_alloc(0);
283 297
 298 if (fds == NULL)
 299 return NULL;
 300
284 DPRINTF_FDSET(fds, "getmax"); 301 DPRINTF_FDSET(fds, "getmax");
285 svc_fdset_sanitize(fds); 302 svc_fdset_sanitize(fds);
286 return &fds->fdmax; 303 return &fds->fdmax;
287} 304}
288 305
289int 306int
290svc_fdset_getsize(int fd) 307svc_fdset_getsize(int fd)
291{ 308{
292 struct svc_fdset *fds = svc_fdset_alloc(fd); 309 struct svc_fdset *fds = svc_fdset_alloc(fd);
293 310
 311 if (fds == NULL)
 312 return -1;
 313
294 DPRINTF_FDSET(fds, "getsize"); 314 DPRINTF_FDSET(fds, "getsize");
295 return fds->fdsize; 315 return fds->fdsize;
296} 316}