diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-08-15 07:27:51 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-08-15 07:27:51 +0000 |
commit | d3abcba59b122d2f03164f75f7b8fe4cecd0068b (patch) | |
tree | 857f5b6a5d829ba53162db58c6abb98a7fb8a9e2 /lib/libc/rpc/pmap_rmt.c | |
parent | 62b977cb51fdb569ebfa78e1ba60efa760bad6f8 (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.c | 49 |
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); } |