summaryrefslogtreecommitdiff
path: root/lib/libc/rpc/pmap_rmt.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-08-15 07:27:51 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-08-15 07:27:51 +0000
commitd3abcba59b122d2f03164f75f7b8fe4cecd0068b (patch)
tree857f5b6a5d829ba53162db58c6abb98a7fb8a9e2 /lib/libc/rpc/pmap_rmt.c
parent62b977cb51fdb569ebfa78e1ba60efa760bad6f8 (diff)
support descriptors > FD_SETSIZE and correct timeout handling
Diffstat (limited to 'lib/libc/rpc/pmap_rmt.c')
-rw-r--r--lib/libc/rpc/pmap_rmt.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c
index 1ed82e39b84..a4e9b0b57aa 100644
--- a/lib/libc/rpc/pmap_rmt.c
+++ b/lib/libc/rpc/pmap_rmt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap_rmt.c,v 1.5 1996/08/10 05:12:09 deraadt Exp $ */
+/* $OpenBSD: pmap_rmt.c,v 1.6 1996/08/15 07:27:49 deraadt Exp $ */
/* $NetBSD: pmap_rmt.c,v 1.6 1995/06/03 22:37:25 mycroft Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: pmap_rmt.c,v 1.5 1996/08/10 05:12:09 deraadt Exp $";
+static char *rcsid = "$OpenBSD: pmap_rmt.c,v 1.6 1996/08/15 07:27:49 deraadt Exp $";
#endif
/*
@@ -186,7 +186,7 @@ getbroadcastnets(addrs, sock, buf)
#define size(p) max((p).sa_len, sizeof(p))
cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
for (cp = buf; cp < cplim;
- cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
+ cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
ifr = (struct ifreq *)cp;
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
@@ -198,7 +198,6 @@ getbroadcastnets(addrs, sock, buf)
if ((ifreq.ifr_flags & IFF_BROADCAST) &&
(ifreq.ifr_flags & IFF_UP)) {
sin = (struct sockaddr_in *)&ifr->ifr_addr;
-#ifdef SIOCGIFBRDADDR /* 4.3BSD */
if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
addrs[i++] =
inet_makeaddr(inet_netof(sin->sin_addr),
@@ -207,10 +206,6 @@ getbroadcastnets(addrs, sock, buf)
addrs[i++] = ((struct sockaddr_in*)
&ifreq.ifr_addr)->sin_addr;
}
-#else /* 4.2 BSD */
- addrs[i++] = inet_makeaddr(inet_netof(sin->sin_addr),
- INADDR_ANY);
-#endif
}
}
return (i);
@@ -236,8 +231,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
int outlen, inlen, fromlen, nets;
register int sock;
int on = 1;
- fd_set mask;
- fd_set readfds;
+ fd_set *fds, readfds;
register int i;
bool_t done = FALSE;
register u_long xid;
@@ -266,8 +260,19 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
goto done_broad;
}
#endif /* def SO_BROADCAST */
- FD_ZERO(&mask);
- FD_SET(sock, &mask);
+
+ if (sock+1 > FD_SETSIZE) {
+ fds = (fd_set *)malloc(howmany(sock+1, NBBY));
+ if (fds == NULL) {
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ memset(fds, '\0', howmany(sock+1, NBBY));
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
nets = getbroadcastnets(addrs, sock, inbuf);
memset(&baddr, 0, sizeof (baddr));
baddr.sin_len = sizeof(struct sockaddr_in);
@@ -303,6 +308,12 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
/*
* Basic loop: broadcast a packet and wait a while for response(s).
* The response timeout grows larger per iteration.
+ *
+ * XXX This will loop about 5 times the stop. If there are
+ * lots of signals being received by the process it will quit
+ * send them all in one quick burst, not paying attention to
+ * the intended function of sending them slowly over half a
+ * minute or so
*/
for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
for (i = 0; i < nets; i++) {
@@ -323,21 +334,20 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where = (caddr_t)&r;
msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
- readfds = mask;
- switch (select(sock+1, &readfds, NULL, NULL, &t)) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ switch (select(sock+1, fds, NULL, NULL, &t)) {
case 0: /* timed out */
stat = RPC_TIMEDOUT;
continue;
-
case -1: /* some kind of error */
if (errno == EINTR)
goto recv_again;
perror("Broadcast select problem");
stat = RPC_CANTRECV;
goto done_broad;
-
- } /* end of select results switch */
+ }
try_again:
fromlen = sizeof(struct sockaddr);
inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
@@ -378,7 +388,10 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
}
}
done_broad:
- (void)close(sock);
+ if (fds != &readfds)
+ free(fds);
+ if (sock >= 0)
+ (void)close(sock);
AUTH_DESTROY(unix_auth);
return (stat);
}