check for errors and recover instead of core-dumping.diff -r1.35 -r1.36 src/lib/libc/rpc/svc.c
(christos)
--- src/lib/libc/rpc/svc.c 2015/11/06 19:34:13 1.35
+++ src/lib/libc/rpc/svc.c 2015/11/07 17:34:33 1.36
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $ */ | 1 | /* $NetBSD: svc.c,v 1.36 2015/11/07 17:34:33 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010, Oracle America, Inc. | 4 | * Copyright (c) 2010, Oracle America, Inc. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are | 7 | * modification, are permitted provided that the following conditions are | |
8 | * met: | 8 | * met: | |
9 | * | 9 | * | |
10 | * * Redistributions of source code must retain the above copyright | 10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above | 12 | * * Redistributions in binary form must reproduce the above | |
13 | * copyright notice, this list of conditions and the following | 13 | * copyright notice, this list of conditions and the following | |
14 | * disclaimer in the documentation and/or other materials | 14 | * disclaimer in the documentation and/or other materials | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | #if defined(LIBC_SCCS) && !defined(lint) | 35 | #if defined(LIBC_SCCS) && !defined(lint) | |
36 | #if 0 | 36 | #if 0 | |
37 | static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; | 37 | static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; | |
38 | static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; | 38 | static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $"); | 40 | __RCSID("$NetBSD: svc.c,v 1.36 2015/11/07 17:34:33 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | /* | 44 | /* | |
45 | * svc.c, Server-side remote procedure call interface. | 45 | * svc.c, Server-side remote procedure call interface. | |
46 | * | 46 | * | |
47 | * There are two sets of procedures here. The xprt routines are | 47 | * There are two sets of procedures here. The xprt routines are | |
48 | * for handling transport handles. The svc routines handle the | 48 | * for handling transport handles. The svc routines handle the | |
49 | * list of service routines. | 49 | * list of service routines. | |
50 | * | 50 | * | |
51 | * Copyright (C) 1984, Sun Microsystems, Inc. | 51 | * Copyright (C) 1984, Sun Microsystems, Inc. | |
52 | */ | 52 | */ | |
53 | 53 | |||
@@ -169,27 +169,28 @@ xprt_register(SVCXPRT *xprt) | @@ -169,27 +169,28 @@ xprt_register(SVCXPRT *xprt) | |||
169 | { | 169 | { | |
170 | int sock; | 170 | int sock; | |
171 | 171 | |||
172 | _DIAGASSERT(xprt != NULL); | 172 | _DIAGASSERT(xprt != NULL); | |
173 | 173 | |||
174 | rwlock_wrlock(&svc_fd_lock); | 174 | rwlock_wrlock(&svc_fd_lock); | |
175 | sock = xprt->xp_fd; | 175 | sock = xprt->xp_fd; | |
176 | 176 | |||
177 | if (!xprt_alloc(sock)) | 177 | if (!xprt_alloc(sock)) | |
178 | goto out; | 178 | goto out; | |
179 | 179 | |||
180 | __svc_xports[sock] = xprt; | 180 | __svc_xports[sock] = xprt; | |
181 | if (sock != -1) { | 181 | if (sock != -1) { | |
182 | svc_fdset_set(sock); | 182 | if (svc_fdset_set(sock) == -1) | |
183 | return FALSE; | |||
183 | } | 184 | } | |
184 | rwlock_unlock(&svc_fd_lock); | 185 | rwlock_unlock(&svc_fd_lock); | |
185 | return (TRUE); | 186 | return (TRUE); | |
186 | 187 | |||
187 | out: | 188 | out: | |
188 | rwlock_unlock(&svc_fd_lock); | 189 | rwlock_unlock(&svc_fd_lock); | |
189 | return (FALSE); | 190 | return (FALSE); | |
190 | } | 191 | } | |
191 | 192 | |||
192 | void | 193 | void | |
193 | xprt_unregister(SVCXPRT *xprt) | 194 | xprt_unregister(SVCXPRT *xprt) | |
194 | { | 195 | { | |
195 | __xprt_do_unregister(xprt, TRUE); | 196 | __xprt_do_unregister(xprt, TRUE); | |
@@ -212,27 +213,27 @@ __xprt_do_unregister(SVCXPRT *xprt, bool | @@ -212,27 +213,27 @@ __xprt_do_unregister(SVCXPRT *xprt, bool | |||
212 | _DIAGASSERT(xprt != NULL); | 213 | _DIAGASSERT(xprt != NULL); | |
213 | 214 | |||
214 | if (dolock) | 215 | if (dolock) | |
215 | rwlock_wrlock(&svc_fd_lock); | 216 | rwlock_wrlock(&svc_fd_lock); | |
216 | 217 | |||
217 | sock = xprt->xp_fd; | 218 | sock = xprt->xp_fd; | |
218 | if (sock >= __svc_maxxports || __svc_xports[sock] != xprt) | 219 | if (sock >= __svc_maxxports || __svc_xports[sock] != xprt) | |
219 | goto out; | 220 | goto out; | |
220 | 221 | |||
221 | __svc_xports[sock] = NULL; | 222 | __svc_xports[sock] = NULL; | |
222 | if (sock == -1) | 223 | if (sock == -1) | |
223 | goto out; | 224 | goto out; | |
224 | fdmax = svc_fdset_getmax(); | 225 | fdmax = svc_fdset_getmax(); | |
225 | if (sock < *fdmax) | 226 | if (fdmax == NULL || sock < *fdmax) | |
226 | goto clr; | 227 | goto clr; | |
227 | 228 | |||
228 | for ((*fdmax)--; *fdmax >= 0; (*fdmax)--) | 229 | for ((*fdmax)--; *fdmax >= 0; (*fdmax)--) | |
229 | if (__svc_xports[*fdmax]) | 230 | if (__svc_xports[*fdmax]) | |
230 | break; | 231 | break; | |
231 | clr: | 232 | clr: | |
232 | svc_fdset_clr(sock); | 233 | svc_fdset_clr(sock); | |
233 | out: | 234 | out: | |
234 | if (dolock) | 235 | if (dolock) | |
235 | rwlock_unlock(&svc_fd_lock); | 236 | rwlock_unlock(&svc_fd_lock); | |
236 | } | 237 | } | |
237 | 238 | |||
238 | /* | 239 | /* | |
@@ -624,26 +625,28 @@ svcerr_progvers(SVCXPRT *xprt, rpcvers_t | @@ -624,26 +625,28 @@ svcerr_progvers(SVCXPRT *xprt, rpcvers_t | |||
624 | * However, this function does not know the structure of the cooked | 625 | * However, this function does not know the structure of the cooked | |
625 | * credentials, so it make the following assumptions: | 626 | * credentials, so it make the following assumptions: | |
626 | * a) the structure is contiguous (no pointers), and | 627 | * a) the structure is contiguous (no pointers), and | |
627 | * b) the cred structure size does not exceed RQCRED_SIZE bytes. | 628 | * b) the cred structure size does not exceed RQCRED_SIZE bytes. | |
628 | * In all events, all three parameters are freed upon exit from this routine. | 629 | * In all events, all three parameters are freed upon exit from this routine. | |
629 | * The storage is trivially management on the call stack in user land, but | 630 | * The storage is trivially management on the call stack in user land, but | |
630 | * is mallocated in kernel land. | 631 | * is mallocated in kernel land. | |
631 | */ | 632 | */ | |
632 | 633 | |||
633 | void | 634 | void | |
634 | svc_getreq(int rdfds) | 635 | svc_getreq(int rdfds) | |
635 | { | 636 | { | |
636 | fd_set *readfds = svc_fdset_copy(NULL); | 637 | fd_set *readfds = svc_fdset_copy(NULL); | |
638 | if (readfds == NULL) | |||
639 | return; | |||
637 | 640 | |||
638 | readfds->fds_bits[0] = (unsigned int)rdfds; | 641 | readfds->fds_bits[0] = (unsigned int)rdfds; | |
639 | svc_getreqset(readfds); | 642 | svc_getreqset(readfds); | |
640 | free(readfds); | 643 | free(readfds); | |
641 | } | 644 | } | |
642 | 645 | |||
643 | void | 646 | void | |
644 | svc_getreqset2(fd_set *readfds, int maxsize) | 647 | svc_getreqset2(fd_set *readfds, int maxsize) | |
645 | { | 648 | { | |
646 | uint32_t mask, *maskp; | 649 | uint32_t mask, *maskp; | |
647 | int sock, bit, fd; | 650 | int sock, bit, fd; | |
648 | 651 | |||
649 | _DIAGASSERT(readfds != NULL); | 652 | _DIAGASSERT(readfds != NULL); | |
@@ -761,27 +764,27 @@ svc_getreq_poll(struct pollfd *pfdp, int | @@ -761,27 +764,27 @@ svc_getreq_poll(struct pollfd *pfdp, int | |||
761 | _DIAGASSERT(pfdp != NULL); | 764 | _DIAGASSERT(pfdp != NULL); | |
762 | 765 | |||
763 | for (i = fds_found = 0; fds_found < pollretval; i++) { | 766 | for (i = fds_found = 0; fds_found < pollretval; i++) { | |
764 | struct pollfd *p = &pfdp[i]; | 767 | struct pollfd *p = &pfdp[i]; | |
765 | 768 | |||
766 | if (p->revents) { | 769 | if (p->revents) { | |
767 | /* fd has input waiting */ | 770 | /* fd has input waiting */ | |
768 | fds_found++; | 771 | fds_found++; | |
769 | /* | 772 | /* | |
770 | * We assume that this function is only called | 773 | * We assume that this function is only called | |
771 | * via someone select()ing from svc_fdset or | 774 | * via someone select()ing from svc_fdset or | |
772 | * pollts()ing from svc_pollset[]. Thus it's safe | 775 | * pollts()ing from svc_pollset[]. Thus it's safe | |
773 | * to handle the POLLNVAL event by simply turning | 776 | * to handle the POLLNVAL event by simply turning | |
774 | * the corresponding bit off in svc_fdset. The | 777 | * the corresponding bit off in the fdset. The | |
775 | * svc_pollset[] array is derived from svc_fdset | 778 | * svc_pollset[] array is derived from svc_fdset | |
776 | * and so will also be updated eventually. | 779 | * and so will also be updated eventually. | |
777 | * | 780 | * | |
778 | * XXX Should we do an xprt_unregister() instead? | 781 | * XXX Should we do an xprt_unregister() instead? | |
779 | */ | 782 | */ | |
780 | if (p->revents & POLLNVAL) { | 783 | if (p->revents & POLLNVAL) { | |
781 | rwlock_wrlock(&svc_fd_lock); | 784 | rwlock_wrlock(&svc_fd_lock); | |
782 | svc_fdset_clr(p->fd); | 785 | svc_fdset_clr(p->fd); | |
783 | rwlock_unlock(&svc_fd_lock); | 786 | rwlock_unlock(&svc_fd_lock); | |
784 | } else | 787 | } else | |
785 | svc_getreq_common(p->fd); | 788 | svc_getreq_common(p->fd); | |
786 | } | 789 | } | |
787 | } | 790 | } |
--- src/lib/libc/rpc/svc_run.c 2015/11/06 19:34:13 1.23
+++ src/lib/libc/rpc/svc_run.c 2015/11/07 17:34:33 1.24
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 christos Exp $ */ | 1 | /* $NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010, Oracle America, Inc. | 4 | * Copyright (c) 2010, Oracle America, Inc. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are | 7 | * modification, are permitted provided that the following conditions are | |
8 | * met: | 8 | * met: | |
9 | * | 9 | * | |
10 | * * Redistributions of source code must retain the above copyright | 10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above | 12 | * * Redistributions in binary form must reproduce the above | |
13 | * copyright notice, this list of conditions and the following | 13 | * copyright notice, this list of conditions and the following | |
14 | * disclaimer in the documentation and/or other materials | 14 | * disclaimer in the documentation and/or other materials | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | #if defined(LIBC_SCCS) && !defined(lint) | 35 | #if defined(LIBC_SCCS) && !defined(lint) | |
36 | #if 0 | 36 | #if 0 | |
37 | static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; | 37 | static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; | |
38 | static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC"; | 38 | static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 christos Exp $"); | 40 | __RCSID("$NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | /* | 44 | /* | |
45 | * This is the rpc server side idle loop | 45 | * This is the rpc server side idle loop | |
46 | * Wait for input, call server program. | 46 | * Wait for input, call server program. | |
47 | */ | 47 | */ | |
48 | #include "namespace.h" | 48 | #include "namespace.h" | |
49 | #include "reentrant.h" | 49 | #include "reentrant.h" | |
50 | #include <err.h> | 50 | #include <err.h> | |
51 | #include <errno.h> | 51 | #include <errno.h> | |
52 | #include <stdio.h> | 52 | #include <stdio.h> | |
53 | #include <stdlib.h> | 53 | #include <stdlib.h> | |
@@ -59,69 +59,75 @@ __RCSID("$NetBSD: svc_run.c,v 1.23 2015/ | @@ -59,69 +59,75 @@ __RCSID("$NetBSD: svc_run.c,v 1.23 2015/ | |||
59 | #include "svc_fdset.h" | 59 | #include "svc_fdset.h" | |
60 | #include "rpc_internal.h" | 60 | #include "rpc_internal.h" | |
61 | 61 | |||
62 | #ifdef __weak_alias | 62 | #ifdef __weak_alias | |
63 | __weak_alias(svc_run,_svc_run) | 63 | __weak_alias(svc_run,_svc_run) | |
64 | __weak_alias(svc_exit,_svc_exit) | 64 | __weak_alias(svc_exit,_svc_exit) | |
65 | #endif | 65 | #endif | |
66 | 66 | |||
67 | void | 67 | void | |
68 | svc_run(void) | 68 | svc_run(void) | |
69 | { | 69 | { | |
70 | fd_set *readfds, *cleanfds; | 70 | fd_set *readfds, *cleanfds; | |
71 | struct timeval timeout; | 71 | struct timeval timeout; | |
72 | int maxfd, fdsize; | 72 | int *maxfd, fdsize; | |
73 | #ifndef RUMP_RPC | 73 | #ifndef RUMP_RPC | |
74 | int probs = 0; | 74 | int probs = 0; | |
75 | #endif | 75 | #endif | |
76 | #ifdef _REENTRANT | 76 | #ifdef _REENTRANT | |
77 | extern rwlock_t svc_fd_lock; | 77 | extern rwlock_t svc_fd_lock; | |
78 | #endif | 78 | #endif | |
79 | 79 | |||
80 | readfds = NULL; | 80 | readfds = NULL; | |
81 | cleanfds = NULL; | 81 | cleanfds = NULL; | |
82 | fdsize = 0; | 82 | fdsize = 0; | |
83 | timeout.tv_sec = 30; | 83 | timeout.tv_sec = 30; | |
84 | timeout.tv_usec = 0; | 84 | timeout.tv_usec = 0; | |
85 | 85 | |||
86 | for (;;) { | 86 | for (;;) { | |
87 | rwlock_rdlock(&svc_fd_lock); | 87 | rwlock_rdlock(&svc_fd_lock); | |
88 | if (fdsize != svc_fdset_getsize(0)) { | 88 | if (fdsize != svc_fdset_getsize(0)) { | |
89 | fdsize = svc_fdset_getsize(0); | 89 | fdsize = svc_fdset_getsize(0); | |
90 | free(readfds); | 90 | free(readfds); | |
91 | readfds = svc_fdset_copy(svc_fdset_get()); | 91 | readfds = svc_fdset_copy(svc_fdset_get()); | |
92 | free(cleanfds); | 92 | free(cleanfds); | |
93 | cleanfds = svc_fdset_copy(svc_fdset_get()); | 93 | cleanfds = svc_fdset_copy(svc_fdset_get()); | |
94 | } | 94 | } | |
95 | maxfd = *svc_fdset_getmax(); | 95 | maxfd = svc_fdset_getmax(); | |
96 | if (maxfd == NULL) { | |||
97 | warn("can't get maxfd"); | |||
98 | continue; | |||
99 | } | |||
96 | rwlock_unlock(&svc_fd_lock); | 100 | rwlock_unlock(&svc_fd_lock); | |
97 | switch (select(maxfd + 1, readfds, NULL, NULL, &timeout)) { | 101 | switch (select(*maxfd + 1, readfds, NULL, NULL, &timeout)) { | |
98 | case -1: | 102 | case -1: | |
99 | #ifndef RUMP_RPC | 103 | #ifndef RUMP_RPC | |
100 | if ((errno == EINTR || errno == EBADF) && probs < 100) { | 104 | if ((errno == EINTR || errno == EBADF) && probs < 100) { | |
101 | probs++; | 105 | probs++; | |
102 | continue; | 106 | continue; | |
103 | } | 107 | } | |
104 | #endif | 108 | #endif | |
105 | if (errno == EINTR) { | 109 | if (errno == EINTR) { | |
106 | continue; | 110 | continue; | |
107 | } | 111 | } | |
108 | warn("%s: select failed", __func__); | 112 | warn("%s: select failed", __func__); | |
109 | goto out; | 113 | goto out; | |
110 | case 0: | 114 | case 0: | |
111 | __svc_clean_idle(cleanfds, 30, FALSE); | 115 | if (cleanfds) | |
116 | __svc_clean_idle(cleanfds, 30, FALSE); | |||
112 | continue; | 117 | continue; | |
113 | default: | 118 | default: | |
114 | svc_getreqset2(readfds, fdsize); | 119 | if (readfds) | |
120 | svc_getreqset2(readfds, fdsize); | |||
115 | #ifndef RUMP_RPC | 121 | #ifndef RUMP_RPC | |
116 | probs = 0; | 122 | probs = 0; | |
117 | #endif | 123 | #endif | |
118 | } | 124 | } | |
119 | } | 125 | } | |
120 | out: | 126 | out: | |
121 | free(readfds); | 127 | free(readfds); | |
122 | free(cleanfds); | 128 | free(cleanfds); | |
123 | } | 129 | } | |
124 | 130 | |||
125 | /* | 131 | /* | |
126 | * This function causes svc_run() to exit by telling it that it has no | 132 | * This function causes svc_run() to exit by telling it that it has no | |
127 | * more work to do. | 133 | * more work to do. |
--- src/lib/libc/rpc/svc_vc.c 2015/11/06 19:34:13 1.31
+++ src/lib/libc/rpc/svc_vc.c 2015/11/07 17:34:33 1.32
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $ */ | 1 | /* $NetBSD: svc_vc.c,v 1.32 2015/11/07 17:34:33 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010, Oracle America, Inc. | 4 | * Copyright (c) 2010, Oracle America, Inc. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are | 7 | * modification, are permitted provided that the following conditions are | |
8 | * met: | 8 | * met: | |
9 | * | 9 | * | |
10 | * * Redistributions of source code must retain the above copyright | 10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above | 12 | * * Redistributions in binary form must reproduce the above | |
13 | * copyright notice, this list of conditions and the following | 13 | * copyright notice, this list of conditions and the following | |
14 | * disclaimer in the documentation and/or other materials | 14 | * disclaimer in the documentation and/or other materials | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | #if defined(LIBC_SCCS) && !defined(lint) | 35 | #if defined(LIBC_SCCS) && !defined(lint) | |
36 | #if 0 | 36 | #if 0 | |
37 | static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; | 37 | static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; | |
38 | static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; | 38 | static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $"); | 40 | __RCSID("$NetBSD: svc_vc.c,v 1.32 2015/11/07 17:34:33 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | /* | 44 | /* | |
45 | * svc_vc.c, Server side for Connection Oriented based RPC. | 45 | * svc_vc.c, Server side for Connection Oriented based RPC. | |
46 | * | 46 | * | |
47 | * Actually implements two flavors of transporter - | 47 | * Actually implements two flavors of transporter - | |
48 | * a tcp rendezvouser (a listner and connection establisher) | 48 | * a tcp rendezvouser (a listner and connection establisher) | |
49 | * and a record/tcp stream. | 49 | * and a record/tcp stream. | |
50 | */ | 50 | */ | |
51 | 51 | |||
52 | #include "namespace.h" | 52 | #include "namespace.h" | |
53 | #include "reentrant.h" | 53 | #include "reentrant.h" | |
@@ -319,27 +319,29 @@ rendezvous_request(SVCXPRT *xprt, struct | @@ -319,27 +319,29 @@ rendezvous_request(SVCXPRT *xprt, struct | |||
319 | r = (struct cf_rendezvous *)xprt->xp_p1; | 319 | r = (struct cf_rendezvous *)xprt->xp_p1; | |
320 | again: | 320 | again: | |
321 | len = sizeof addr; | 321 | len = sizeof addr; | |
322 | if ((sock = accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr, | 322 | if ((sock = accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr, | |
323 | &len)) < 0) { | 323 | &len)) < 0) { | |
324 | if (errno == EINTR) | 324 | if (errno == EINTR) | |
325 | goto again; | 325 | goto again; | |
326 | /* | 326 | /* | |
327 | * Clean out the most idle file descriptor when we're | 327 | * Clean out the most idle file descriptor when we're | |
328 | * running out. | 328 | * running out. | |
329 | */ | 329 | */ | |
330 | if (errno == EMFILE || errno == ENFILE) { | 330 | if (errno == EMFILE || errno == ENFILE) { | |
331 | fd_set *cleanfds = svc_fdset_copy(svc_fdset_get()); | 331 | fd_set *cleanfds = svc_fdset_copy(svc_fdset_get()); | |
332 | int rv = __svc_clean_idle(cleanfds, 0, FALSE); | 332 | int rv = 0; | |
333 | if (cleanfds) | |||
334 | rv = __svc_clean_idle(cleanfds, 0, FALSE); | |||
333 | free(cleanfds); | 335 | free(cleanfds); | |
334 | if (rv) | 336 | if (rv) | |
335 | goto again; | 337 | goto again; | |
336 | } | 338 | } | |
337 | return FALSE; | 339 | return FALSE; | |
338 | } | 340 | } | |
339 | /* | 341 | /* | |
340 | * make a new transporter (re-uses xprt) | 342 | * make a new transporter (re-uses xprt) | |
341 | */ | 343 | */ | |
342 | newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); | 344 | newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); | |
343 | if (newxprt == NULL) | 345 | if (newxprt == NULL) | |
344 | goto out; | 346 | goto out; | |
345 | newxprt->xp_rtaddr.buf = mem_alloc(len); | 347 | newxprt->xp_rtaddr.buf = mem_alloc(len); | |
@@ -751,39 +753,46 @@ svc_vc_rendezvous_ops(SVCXPRT *xprt) | @@ -751,39 +753,46 @@ svc_vc_rendezvous_ops(SVCXPRT *xprt) | |||
751 | xprt->xp_ops = &ops; | 753 | xprt->xp_ops = &ops; | |
752 | xprt->xp_ops2 = &ops2; | 754 | xprt->xp_ops2 = &ops2; | |
753 | mutex_unlock(&ops_lock); | 755 | mutex_unlock(&ops_lock); | |
754 | } | 756 | } | |
755 | 757 | |||
756 | /* | 758 | /* | |
757 | * Destroy xprts that have not have had any activity in 'timeout' seconds. | 759 | * Destroy xprts that have not have had any activity in 'timeout' seconds. | |
758 | * If 'cleanblock' is true, blocking connections (the default) are also | 760 | * If 'cleanblock' is true, blocking connections (the default) are also | |
759 | * cleaned. If timeout is 0, the least active connection is picked. | 761 | * cleaned. If timeout is 0, the least active connection is picked. | |
760 | */ | 762 | */ | |
761 | bool_t | 763 | bool_t | |
762 | __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) | 764 | __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) | |
763 | { | 765 | { | |
764 | int i, ncleaned, fdmax; | 766 | int i, ncleaned, *fdmax; | |
765 | SVCXPRT *xprt, *least_active; | 767 | SVCXPRT *xprt, *least_active; | |
766 | struct timeval tv, tdiff, tmax; | 768 | struct timeval tv, tdiff, tmax; | |
767 | struct cf_conn *cd; | 769 | struct cf_conn *cd; | |
768 | 770 | |||
769 | gettimeofday(&tv, NULL); | 771 | gettimeofday(&tv, NULL); | |
770 | tmax.tv_sec = tmax.tv_usec = 0; | 772 | tmax.tv_sec = tmax.tv_usec = 0; | |
771 | least_active = NULL; | 773 | least_active = NULL; | |
772 | rwlock_wrlock(&svc_fd_lock); | 774 | rwlock_wrlock(&svc_fd_lock); | |
773 | fdmax = *svc_fdset_getmax(); | 775 | fdmax = svc_fdset_getmax(); | |
774 | for (i = ncleaned = 0; i <= fdmax; i++) { | 776 | if (fdmax == NULL) | |
775 | if (!svc_fdset_isset(i)) | 777 | return FALSE; | |
778 | for (i = ncleaned = 0; i <= *fdmax; i++) { | |||
779 | switch (svc_fdset_isset(i)) { | |||
780 | case 0: | |||
781 | case -1: | |||
776 | continue; | 782 | continue; | |
783 | default: | |||
784 | break; | |||
785 | } | |||
777 | 786 | |||
778 | xprt = __svc_xports[i]; | 787 | xprt = __svc_xports[i]; | |
779 | if (xprt == NULL || xprt->xp_ops == NULL || | 788 | if (xprt == NULL || xprt->xp_ops == NULL || | |
780 | xprt->xp_ops->xp_recv != svc_vc_recv) | 789 | xprt->xp_ops->xp_recv != svc_vc_recv) | |
781 | continue; | 790 | continue; | |
782 | 791 | |||
783 | cd = (struct cf_conn *)xprt->xp_p1; | 792 | cd = (struct cf_conn *)xprt->xp_p1; | |
784 | if (!cleanblock && !cd->nonblock) | 793 | if (!cleanblock && !cd->nonblock) | |
785 | continue; | 794 | continue; | |
786 | 795 | |||
787 | if (timeout == 0) { | 796 | if (timeout == 0) { | |
788 | timersub(&tv, &cd->last_recv_time, &tdiff); | 797 | timersub(&tv, &cd->last_recv_time, &tdiff); | |
789 | if (timercmp(&tdiff, &tmax, >)) { | 798 | if (timercmp(&tdiff, &tmax, >)) { |