summaryrefslogtreecommitdiff
path: root/libc/inet
diff options
context:
space:
mode:
Diffstat (limited to 'libc/inet')
-rw-r--r--libc/inet/rpc/clnt_generic.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/libc/inet/rpc/clnt_generic.c b/libc/inet/rpc/clnt_generic.c
index 349c0f62d..c8fe545c3 100644
--- a/libc/inet/rpc/clnt_generic.c
+++ b/libc/inet/rpc/clnt_generic.c
@@ -53,7 +53,9 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
struct hostent hostbuf, *h;
size_t hstbuflen;
char *hsttmpbuf;
- struct protoent *p;
+ struct protoent protobuf, *p;
+ size_t prtbuflen;
+ char *prttmpbuf;
struct sockaddr_in sin;
struct sockaddr_un sun;
int sock;
@@ -113,14 +115,23 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
memset (sin.sin_zero, 0, sizeof (sin.sin_zero));
memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);
-#warning getprotobyname is not reentrant... Add getprotobyname_r
- p = getprotobyname(proto);
- if (p == NULL) {
- struct rpc_createerr *ce = &get_rpc_createerr ();
- ce->cf_stat = RPC_UNKNOWNPROTO;
- ce->cf_error.re_errno = EPFNOSUPPORT;
- return NULL;
- }
+ prtbuflen = 1024;
+ prttmpbuf = alloca (prtbuflen);
+ while (getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
+ || p == NULL)
+ if (errno != ERANGE)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_UNKNOWNPROTO;
+ ce->cf_error.re_errno = EPFNOSUPPORT;
+ return NULL;
+ }
+ else
+ {
+ /* Enlarge the buffer. */
+ prtbuflen *= 2;
+ prttmpbuf = alloca (prtbuflen);
+ }
sock = RPC_ANYSOCK;
switch (p->p_proto)