From cdb3c81f36283df4b53f24a374d78c695e9d8b06 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 17 Jun 2002 21:12:16 +0000 Subject: Re-backport all the rpc stuff from glibc 2.2.5. This allows us to make this junk (and I do mean that ;-) thread safe without undue pain. Adds 12k worth to the code size I'm afraid, but since I never use NFS and therefore never include this stuff, I guess thats acceptable. I still need to enable the multi-threaded bits... -Erik --- libc/inet/rpc/clnt_simple.c | 191 ++++++++++++++++++++++++++++---------------- 1 file changed, 120 insertions(+), 71 deletions(-) (limited to 'libc/inet/rpc/clnt_simple.c') diff --git a/libc/inet/rpc/clnt_simple.c b/libc/inet/rpc/clnt_simple.c index 3ec4aedfe..fe65d4e23 100644 --- a/libc/inet/rpc/clnt_simple.c +++ b/libc/inet/rpc/clnt_simple.c @@ -6,110 +6,159 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ -#define __FORCE_GLIBC -#include +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; +#endif -/* +/* * clnt_simple.c * Simplified front end to rpc. * * Copyright (C) 1984, Sun Microsystems, Inc. */ +#define __FORCE_GLIBC +#include + +#include +#include #include #include #include #include #include -#include +#include -static struct callrpc_private { - CLIENT *client; - int socket; - int oldprognum, oldversnum, valid; - char *oldhost; -} *callrpc_private; +struct callrpc_private_s + { + CLIENT *client; + int socket; + u_long oldprognum, oldversnum, valid; + char *oldhost; + }; +#ifdef _RPC_THREAD_SAFE_ +#define callrpc_private ((struct callrpc_private_s *)RPC_THREAD_VARIABLE(callrpc_private_s)) +#else +static struct callrpc_private_s *callrpc_private; +#endif -int callrpc (const char *host, const u_long prognum, - const u_long versnum, const u_long procnum, - const xdrproc_t inproc, const char *in, - const xdrproc_t outproc, char *out) +int +callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, + xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out) { - register struct callrpc_private *crp = callrpc_private; - struct sockaddr_in server_addr; - enum clnt_stat clnt_stat; - struct hostent *hp; - struct timeval timeout, tottimeout; + struct callrpc_private_s *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent hostbuf, *hp; + struct timeval timeout, tottimeout; - if (crp == 0) { - crp = (struct callrpc_private *) calloc(1, sizeof(*crp)); - if (crp == 0) - return (0); - callrpc_private = crp; - } - if (crp->oldhost == NULL) { - crp->oldhost = malloc(256); - crp->oldhost[0] = 0; - crp->socket = RPC_ANYSOCK; + if (crp == 0) + { + crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp)); + if (crp == 0) + return 0; + callrpc_private = crp; + } + if (crp->oldhost == NULL) + { + crp->oldhost = malloc (256); + crp->oldhost[0] = 0; + crp->socket = RPC_ANYSOCK; + } + if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum + && strcmp (crp->oldhost, host) == 0) + { + /* reuse old client */ + } + else + { + size_t buflen; + char *buffer; + int herr; + + crp->valid = 0; + if (crp->socket != RPC_ANYSOCK) + { + (void) close (crp->socket); + crp->socket = RPC_ANYSOCK; } - if (crp->valid && crp->oldprognum == prognum - && crp->oldversnum == versnum && - strcmp(crp->oldhost, host) == 0) + if (crp->client) { - /* reuse old client */ - } else { - crp->valid = 0; - (void) close(crp->socket); - crp->socket = RPC_ANYSOCK; - if (crp->client) { - clnt_destroy(crp->client); - crp->client = NULL; - } - if ((hp = gethostbyname(host)) == NULL) - return ((int) RPC_UNKNOWNHOST); - timeout.tv_usec = 0; - timeout.tv_sec = 5; - bcopy(hp->h_addr, (char *) &server_addr.sin_addr, hp->h_length); - server_addr.sin_family = AF_INET; - server_addr.sin_port = 0; - if ((crp->client = clntudp_create(&server_addr, - (u_long) prognum, (u_long) versnum, - timeout, &crp->socket)) == NULL) - return ((int) rpc_createerr.cf_stat); - crp->valid = 1; - crp->oldprognum = prognum; - crp->oldversnum = versnum; - (void) strcpy(crp->oldhost, host); + clnt_destroy (crp->client); + crp->client = NULL; + } + + buflen = 1024; + buffer = alloca (buflen); + while (gethostbyname_r (host, &hostbuf, buffer, buflen, + &hp, &herr) != 0 + || hp == NULL) + if (herr != NETDB_INTERNAL || errno != ERANGE) + return (int) RPC_UNKNOWNHOST; + else + { + /* Enlarge the buffer. */ + buflen *= 2; + buffer = alloca (buflen); + } + + timeout.tv_usec = 0; + timeout.tv_sec = 5; + memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((crp->client = clntudp_create (&server_addr, (u_long) prognum, + (u_long) versnum, timeout, &crp->socket)) == NULL) + return (int) get_rpc_createerr().cf_stat; + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strncpy (crp->oldhost, host, 255); + crp->oldhost[255] = '\0'; + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return (int) clnt_stat; +} + +#ifdef _RPC_THREAD_SAFE_ +void +__rpc_thread_clnt_cleanup (void) +{ + struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s); + + if (rcp) { + if (rcp->client) + CLNT_DESTROY (rcp->client); + free (rcp); } - tottimeout.tv_sec = 25; - tottimeout.tv_usec = 0; - clnt_stat = clnt_call(crp->client, procnum, inproc, (char*)in, - outproc, out, tottimeout); - /* - * if call failed, empty cache - */ - if (clnt_stat != RPC_SUCCESS) - crp->valid = 0; - return ((int) clnt_stat); } +#endif /* _RPC_THREAD_SAFE_ */ -- cgit v1.2.3