summaryrefslogtreecommitdiff
path: root/lib/libc/rpc
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
parent62b977cb51fdb569ebfa78e1ba60efa760bad6f8 (diff)
support descriptors > FD_SETSIZE and correct timeout handling
Diffstat (limited to 'lib/libc/rpc')
-rw-r--r--lib/libc/rpc/clnt_tcp.c54
-rw-r--r--lib/libc/rpc/clnt_udp.c114
-rw-r--r--lib/libc/rpc/pmap_rmt.c49
-rw-r--r--lib/libc/rpc/svc.c59
-rw-r--r--lib/libc/rpc/svc_run.c21
-rw-r--r--lib/libc/rpc/svc_tcp.c49
6 files changed, 233 insertions, 113 deletions
diff --git a/lib/libc/rpc/clnt_tcp.c b/lib/libc/rpc/clnt_tcp.c
index 1f9279fb0ad..daa893f3ed2 100644
--- a/lib/libc/rpc/clnt_tcp.c
+++ b/lib/libc/rpc/clnt_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clnt_tcp.c,v 1.4 1996/07/20 06:12:24 deraadt Exp $ */
+/* $OpenBSD: clnt_tcp.c,v 1.5 1996/08/15 07:27:47 deraadt Exp $ */
/* $NetBSD: clnt_tcp.c,v 1.4 1995/02/25 03:01:41 cgd Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: clnt_tcp.c,v 1.4 1996/07/20 06:12:24 deraadt Exp $";
+static char *rcsid = "$OpenBSD: clnt_tcp.c,v 1.5 1996/08/15 07:27:47 deraadt Exp $";
#endif
/*
@@ -404,39 +404,65 @@ readtcp(ct, buf, len)
caddr_t buf;
register int len;
{
- fd_set mask;
- fd_set readfds;
+ fd_set *fds, readfds;
+ struct timeval start, after, duration, delta, tmp;
+ int r, save_errno;
if (len == 0)
return (0);
- FD_ZERO(&mask);
- FD_SET(ct->ct_sock, &mask);
+
+ if (ct->ct_sock+1 > FD_SETSIZE) {
+ fds = (fd_set *)malloc(howmany(ct->ct_sock+1, NBBY));
+ if (fds == NULL)
+ return (-1);
+ memset(fds, '\0', howmany(ct->ct_sock+1, NBBY));
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ gettimeofday(&start, NULL);
+ delta = ct->ct_wait;
while (TRUE) {
- readfds = mask;
- switch (select(ct->ct_sock+1, &readfds, NULL, NULL,
- &(ct->ct_wait))) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(ct->ct_sock, fds);
+ r = select(ct->ct_sock+1, fds, NULL, NULL, &delta);
+ save_errno = errno;
+
+ gettimeofday(&after, NULL);
+ timersub(&start, &after, &duration);
+ timersub(&delta, &duration, &tmp);
+ delta = tmp;
+ if (delta.tv_sec < 0 || !timerisset(&delta))
+ r = 0;
+
+ switch (r) {
case 0:
ct->ct_error.re_status = RPC_TIMEDOUT;
+ if (fds != &readfds)
+ free(fds);
return (-1);
-
case -1:
- if (errno == EINTR)
+ if (errno == EINTR);
continue;
ct->ct_error.re_status = RPC_CANTRECV;
- ct->ct_error.re_errno = errno;
+ ct->ct_error.re_errno = save_errno;
+ if (fds != &readfds)
+ free(fds);
return (-1);
}
break;
}
- switch (len = read(ct->ct_sock, buf, len)) {
+ if (fds != &readfds)
+ free(fds);
+ switch (len = read(ct->ct_sock, buf, len)) {
case 0:
/* premature eof */
ct->ct_error.re_errno = ECONNRESET;
ct->ct_error.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
-
case -1:
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTRECV;
diff --git a/lib/libc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c
index d7fea262431..fadb7707d54 100644
--- a/lib/libc/rpc/clnt_udp.c
+++ b/lib/libc/rpc/clnt_udp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clnt_udp.c,v 1.4 1996/07/20 06:12:25 deraadt Exp $ */
+/* $OpenBSD: clnt_udp.c,v 1.5 1996/08/15 07:27:48 deraadt Exp $ */
/* $NetBSD: clnt_udp.c,v 1.4 1995/02/25 03:01:42 cgd Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: clnt_udp.c,v 1.4 1996/07/20 06:12:25 deraadt Exp $";
+static char *rcsid = "$OpenBSD: clnt_udp.c,v 1.5 1996/08/15 07:27:48 deraadt Exp $";
#endif
/*
@@ -224,24 +224,31 @@ clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
register int outlen;
register int inlen;
int fromlen;
- fd_set readfds;
- fd_set mask;
+ fd_set *fds, readfds;
struct sockaddr_in from;
struct rpc_msg reply_msg;
XDR reply_xdrs;
- struct timeval time_waited;
+ struct timeval time_waited, start, after, tmp1, tmp2;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
struct timeval timeout;
- if (cu->cu_total.tv_usec == -1) {
+ if (cu->cu_total.tv_usec == -1)
timeout = utimeout; /* use supplied timeout */
- } else {
+ else
timeout = cu->cu_total; /* use default timeout */
+
+ if (cu->cu_sock+1 > FD_SETSIZE) {
+ fds = (fd_set *)malloc(howmany(cu->cu_sock+1, NBBY));
+ if (fds == NULL)
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ memset(fds, '\0', howmany(cu->cu_sock+1, NBBY));
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
}
- time_waited.tv_sec = 0;
- time_waited.tv_usec = 0;
+ timerclear(&time_waited);
call_again:
xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_ENCODE;
@@ -250,26 +257,33 @@ call_again:
* the transaction is the first thing in the out buffer
*/
(*(u_short *)(cu->cu_outbuf))++;
- if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
- (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
- (! (*xargs)(xdrs, argsp)))
+ if (!XDR_PUTLONG(xdrs, (long *)&proc) ||
+ !AUTH_MARSHALL(cl->cl_auth, xdrs) ||
+ !(*xargs)(xdrs, argsp)) {
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+ }
outlen = (int)XDR_GETPOS(xdrs);
send_again:
if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
- (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
- != outlen) {
+ (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_CANTSEND);
}
/*
* Hack to provide rpc-based message passing
*/
- if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ if (!timerisset(&timeout)) {
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
+
/*
* sub-optimal code appears here because we have
* some clock time to spare while the packets are in flight.
@@ -278,46 +292,50 @@ send_again:
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
- FD_ZERO(&mask);
- FD_SET(cu->cu_sock, &mask);
- for (;;) {
- readfds = mask;
- switch (select(cu->cu_sock+1, &readfds, NULL,
- NULL, &(cu->cu_wait))) {
+ gettimeofday(&start, NULL);
+ for (;;) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(cu->cu_sock, fds);
+ switch (select(cu->cu_sock+1, fds, NULL, NULL, &cu->cu_wait)) {
case 0:
- time_waited.tv_sec += cu->cu_wait.tv_sec;
- time_waited.tv_usec += cu->cu_wait.tv_usec;
- while (time_waited.tv_usec >= 1000000) {
- time_waited.tv_sec++;
- time_waited.tv_usec -= 1000000;
- }
- if ((time_waited.tv_sec < timeout.tv_sec) ||
- ((time_waited.tv_sec == timeout.tv_sec) &&
- (time_waited.tv_usec < timeout.tv_usec)))
- goto send_again;
+ timeradd(&time_waited, &cu->cu_wait, &tmp1);
+ time_waited = tmp1;
+ if (timercmp(&time_waited, &timeout, <))
+ goto send_again;
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
-
- /*
- * buggy in other cases because time_waited is not being
- * updated.
- */
case -1:
- if (errno == EINTR)
- continue;
+ if (errno == EINTR) {
+ gettimeofday(&after, NULL);
+ timersub(&after, &start, &tmp1);
+ timeradd(&time_waited, &tmp1, &tmp2);
+ time_waited = tmp2;
+ if (timercmp(&time_waited, &timeout, <))
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
+
do {
fromlen = sizeof(struct sockaddr);
inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
- (int) cu->cu_recvsz, 0,
- (struct sockaddr *)&from, &fromlen);
+ (int) cu->cu_recvsz, 0,
+ (struct sockaddr *)&from, &fromlen);
} while (inlen < 0 && errno == EINTR);
if (inlen < 0) {
if (errno == EWOULDBLOCK)
- continue;
+ continue;
cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (inlen < sizeof(u_int32_t))
@@ -339,7 +357,7 @@ send_again:
_seterr_reply(&reply_msg, &(cu->cu_error));
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
- &reply_msg.acpted_rply.ar_verf)) {
+ &reply_msg.acpted_rply.ar_verf)) {
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
}
@@ -348,18 +366,18 @@ send_again:
(void)xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
}
- } /* end successful completion */
- else {
+ } else {
/* maybe our credentials need to be refreshed ... */
if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
nrefreshes--;
goto call_again;
}
- } /* end of unsuccessful completion */
- } /* end of valid reply message */
- else {
+ }
+ } else
cu->cu_error.re_status = RPC_CANTDECODERES;
- }
+
+ if (fds != &readfds)
+ free(fds);
return (cu->cu_error.re_status);
}
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);
}
diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c
index 86897f4e550..a9c1775476d 100644
--- a/lib/libc/rpc/svc.c
+++ b/lib/libc/rpc/svc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svc.c,v 1.4 1996/07/20 06:12:40 deraadt Exp $ */
+/* $OpenBSD: svc.c,v 1.5 1996/08/15 07:27:49 deraadt Exp $ */
/* $NetBSD: svc.c,v 1.9 1996/05/17 00:32:22 jtc Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: svc.c,v 1.4 1996/07/20 06:12:40 deraadt Exp $";
+static char *rcsid = "$OpenBSD: svc.c,v 1.5 1996/08/15 07:27:49 deraadt Exp $";
#endif
/*
@@ -75,6 +75,9 @@ static struct svc_callout {
static struct svc_callout *svc_find();
+int __svc_fdsetsize;
+fd_set *__svc_fdset;
+
/* *************** SVCXPRT related stuff **************** */
/*
@@ -87,15 +90,30 @@ xprt_register(xprt)
register int sock = xprt->xp_sock;
if (xports == NULL) {
- xports = (SVCXPRT **)
- mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
- memset(xports, 0, FD_SETSIZE * sizeof(SVCXPRT *));
+ xports = (SVCXPRT **)mem_alloc(FD_SETSIZE *
+ sizeof(SVCXPRT *));
+ memset(xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *));
}
- if (sock < FD_SETSIZE) {
- xports[sock] = xprt;
- FD_SET(sock, &svc_fdset);
- svc_maxfd = max(svc_maxfd, sock);
+
+ if (sock+1 > __svc_fdsetsize) {
+ fd_set *fds;
+
+ fds = (fd_set *)malloc(howmany(sock+1, NBBY));
+ memset(fds, '\0', howmany(sock+1, NBBY));
+ if (__svc_fdset) {
+ memcpy(fds, __svc_fdset,
+ howmany(__svc_fdsetsize, NBBY));
+ free(__svc_fdset);
+ }
+ __svc_fdset = fds;
+ __svc_fdsetsize = sock+1;
}
+
+ if (sock < FD_SETSIZE)
+ FD_SET(sock, &svc_fdset);
+ FD_SET(sock, __svc_fdset);
+ xports[sock] = xprt;
+ svc_maxfd = max(svc_maxfd, sock);
}
/*
@@ -107,14 +125,20 @@ xprt_unregister(xprt)
{
register int sock = xprt->xp_sock;
- if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) {
+ if (xports[sock] == xprt) {
xports[sock] = (SVCXPRT *)0;
- FD_CLR(sock, &svc_fdset);
+ if (sock < FD_SETSIZE)
+ FD_CLR(sock, &svc_fdset);
+ FD_CLR(sock, __svc_fdset);
if (sock == svc_maxfd) {
for (svc_maxfd--; svc_maxfd>=0; svc_maxfd--)
if (xports[svc_maxfd])
break;
}
+ /*
+ * XXX could use svc_maxfd as a hint to
+ * decrease the size of __svc_fdset
+ */
}
}
@@ -369,10 +393,20 @@ svc_getreq(rdfds)
svc_getreqset(&readfds);
}
+void svc_getreqset2 __P((fd_set *, int));
+
void
svc_getreqset(readfds)
fd_set *readfds;
{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
+svc_getreqset2(readfds, width)
+ fd_set *readfds;
+ int width;
+{
enum xprt_stat stat;
struct rpc_msg msg;
int prog_found;
@@ -388,9 +422,8 @@ svc_getreqset(readfds)
msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
-
maskp = readfds->fds_bits;
- for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
+ for (sock = 0; sock < width; sock += NFDBITS) {
for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
/* sock has input waiting */
xprt = xports[sock + bit - 1];
diff --git a/lib/libc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c
index 68edcaf2188..27b4c0e02fd 100644
--- a/lib/libc/rpc/svc_run.c
+++ b/lib/libc/rpc/svc_run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svc_run.c,v 1.3 1996/07/20 06:12:43 deraadt Exp $ */
+/* $OpenBSD: svc_run.c,v 1.4 1996/08/15 07:27:50 deraadt Exp $ */
/* $NetBSD: svc_run.c,v 1.6 1995/02/25 03:02:00 cgd Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: svc_run.c,v 1.3 1996/07/20 06:12:43 deraadt Exp $";
+static char *rcsid = "$OpenBSD: svc_run.c,v 1.4 1996/08/15 07:27:50 deraadt Exp $";
#endif
/*
@@ -44,25 +44,32 @@ static char *rcsid = "$OpenBSD: svc_run.c,v 1.3 1996/07/20 06:12:43 deraadt Exp
#include <sys/errno.h>
#include <unistd.h>
+extern int __svc_fdsetsize;
+extern fd_set *__svc_fdset;
+
void
svc_run()
{
- fd_set readfds;
+ fd_set *fds;
for (;;) {
- readfds = svc_fdset;
- switch (select(svc_maxfd+1, &readfds, 0, 0,
- (struct timeval *)0)) {
+ fds = (fd_set *)malloc(howmany(__svc_fdsetsize, NBBY));
+ memcpy(fds, __svc_fdset, howmany(__svc_fdsetsize, NBBY));
+ switch (select(svc_maxfd+1, fds, 0, 0, (struct timeval *)0)) {
case -1:
if (errno == EINTR) {
+ free(fds);
continue;
}
perror("svc_run: - select failed");
+ free(fds);
return;
case 0:
+ free(fds);
continue;
default:
- svc_getreqset(&readfds);
+ svc_getreqset2(fds, svc_maxfd+1);
+ free(fds);
}
}
}
diff --git a/lib/libc/rpc/svc_tcp.c b/lib/libc/rpc/svc_tcp.c
index c03659b4520..cb35f3330d5 100644
--- a/lib/libc/rpc/svc_tcp.c
+++ b/lib/libc/rpc/svc_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svc_tcp.c,v 1.4 1996/08/05 00:34:28 deraadt Exp $ */
+/* $OpenBSD: svc_tcp.c,v 1.5 1996/08/15 07:27:50 deraadt Exp $ */
/* $NetBSD: svc_tcp.c,v 1.6 1995/06/03 22:37:27 mycroft Exp $ */
/*
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$OpenBSD: svc_tcp.c,v 1.4 1996/08/05 00:34:28 deraadt Exp $";
+static char *rcsid = "$OpenBSD: svc_tcp.c,v 1.5 1996/08/15 07:27:50 deraadt Exp $";
#endif
/*
@@ -307,26 +307,49 @@ readtcp(xprt, buf, len)
register int len;
{
register int sock = xprt->xp_sock;
- fd_set mask;
- fd_set readfds;
+ struct timeval start, delta;
+ struct timeval tmp1, tmp2;
+ fd_set *fds, readfds;
- FD_ZERO(&mask);
- FD_SET(sock, &mask);
+ if (sock+1 > FD_SETSIZE) {
+ fds = (fd_set *)malloc(howmany(sock+1, NBBY));
+ if (fds == NULL)
+ goto fatal_err;
+ memset(fds, '\0', howmany(sock+1, NBBY));
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ delta = wait_per_try;
+ gettimeofday(&start, NULL);
do {
- readfds = mask;
- if (select(sock+1, &readfds, NULL, NULL,
- &wait_per_try) <= 0) {
- if (errno == EINTR) {
- continue;
- }
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ switch (select(sock+1, fds, NULL, NULL, &delta)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&delta, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
goto fatal_err;
}
- } while (!FD_ISSET(sock, &readfds));
+ } while (!FD_ISSET(sock, fds));
if ((len = read(sock, buf, len)) > 0) {
+ if (fds != &readfds)
+ free(fds);
return (len);
}
fatal_err:
((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != &readfds)
+ free(fds);
return (-1);
}