diff options
Diffstat (limited to 'libc/inet')
-rw-r--r-- | libc/inet/rpc/clnt_generic.c | 29 |
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) |