diff options
Diffstat (limited to 'sunrpc')
-rw-r--r-- | sunrpc/Makefile | 3 | ||||
-rw-r--r-- | sunrpc/Versions | 3 | ||||
-rw-r--r-- | sunrpc/auth_none.c | 29 | ||||
-rw-r--r-- | sunrpc/clnt_perr.c | 21 | ||||
-rw-r--r-- | sunrpc/clnt_raw.c | 18 | ||||
-rw-r--r-- | sunrpc/clnt_simp.c | 28 | ||||
-rw-r--r-- | sunrpc/key_call.c | 18 | ||||
-rw-r--r-- | sunrpc/rpc_common.c | 8 | ||||
-rw-r--r-- | sunrpc/rpc_thread.c | 55 | ||||
-rw-r--r-- | sunrpc/svc.c | 26 | ||||
-rw-r--r-- | sunrpc/svc_raw.c | 22 | ||||
-rw-r--r-- | sunrpc/svc_simple.c | 37 | ||||
-rw-r--r-- | sunrpc/svcauth_des.c | 11 |
13 files changed, 219 insertions, 60 deletions
diff --git a/sunrpc/Makefile b/sunrpc/Makefile index 7f81218b3d..f3f29bc2cb 100644 --- a/sunrpc/Makefile +++ b/sunrpc/Makefile @@ -60,7 +60,7 @@ routines := auth_none auth_unix authuxprot bindrsvprt \ clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \ clnt_udp rpc_dtable get_myaddr getrpcport \ pmap_clnt pm_getmaps pm_getport pmap_prot \ - pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \ + pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg rpc_thread \ svc svc_auth svc_authux svc_raw svc_run svc_simple \ svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \ xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \ @@ -116,6 +116,7 @@ CFLAGS-xkey_prot.c = -Wno-unused ifeq (yes,$(have_doors)) CPPFLAGS-key_call.c += -DHAVE_DOORS=1 endif +CPPFLAGS += -D_RPC_THREAD_SAFE_ include ../Rules diff --git a/sunrpc/Versions b/sunrpc/Versions index 6efdaac4c4..a1ab66e460 100644 --- a/sunrpc/Versions +++ b/sunrpc/Versions @@ -109,4 +109,7 @@ libc { GLIBC_2.2 { svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd; } + GLIBC_2.2.3 { + __rpc_thread_destroy; + } } diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c index b2f9273530..10e9b2f65a 100644 --- a/sunrpc/auth_none.c +++ b/sunrpc/auth_none.c @@ -35,8 +35,7 @@ * credentials and verifiers to remote systems. */ -#include <rpc/types.h> -#include <rpc/auth.h> +#include <rpc/rpc.h> #define MAX_MARSHEL_SIZE 20 @@ -57,24 +56,29 @@ static struct auth_ops ops = { authnone_destroy }; -static struct authnone_private -{ +struct authnone_private_s { AUTH no_client; char marshalled_client[MAX_MARSHEL_SIZE]; u_int mcnt; -} *authnone_private; +}; +#ifdef _RPC_THREAD_SAFE_ +#define authnone_private ((struct authnone_private_ *)RPC_THREAD_VARIABLE(authnone_private_s)) +#else +static struct authnone_private_s *authnone_private; +#endif AUTH * authnone_create (void) { - struct authnone_private *ap = authnone_private; + struct authnone_private_s *ap; XDR xdr_stream; XDR *xdrs; - if (ap == 0) + ap = (struct authnone_private_s *) authnone_private; + if (ap == NULL) { - ap = (struct authnone_private *) calloc (1, sizeof (*ap)); - if (ap == 0) + ap = (struct authnone_private_s *) calloc (1, sizeof (*ap)); + if (ap == NULL) return NULL; authnone_private = ap; } @@ -97,10 +101,11 @@ authnone_create (void) static bool_t authnone_marshal (AUTH *client, XDR *xdrs) { - struct authnone_private *ap = authnone_private; + struct authnone_private_s *ap; - if (ap == 0) - return 0; + ap = (struct authnone_private_s *) authnone_private; + if (ap == NULL) + return FALSE; return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt); } diff --git a/sunrpc/clnt_perr.c b/sunrpc/clnt_perr.c index 6c33c32d2f..24b15c04c6 100644 --- a/sunrpc/clnt_perr.c +++ b/sunrpc/clnt_perr.c @@ -40,9 +40,7 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; #include <stdio.h> #include <string.h> #include <libintl.h> -#include <rpc/types.h> -#include <rpc/auth.h> -#include <rpc/clnt.h> +#include <rpc/rpc.h> #ifdef USE_IN_LIBIO # include <libio/iolibio.h> @@ -51,7 +49,16 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; static char *auth_errmsg (enum auth_stat stat) internal_function; +#ifdef _RPC_THREAD_SAFE_ +/* + * Making buf a preprocessor macro requires renaming the local + * buf variable in a few functions. Overriding a global variable + * with a local variable of the same name is a bad idea, anyway. + */ +#define buf ((char *)RPC_THREAD_VARIABLE(clnt_perr_buf_s)) +#else static char *buf; +#endif static char * _buf (void) @@ -67,7 +74,7 @@ _buf (void) char * clnt_sperror (CLIENT * rpch, const char *msg) { - char buf[1024]; + char chrbuf[1024]; struct rpc_err e; char *err; char *str = _buf (); @@ -103,7 +110,7 @@ clnt_sperror (CLIENT * rpch, const char *msg) case RPC_CANTSEND: case RPC_CANTRECV: len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno, - buf, sizeof buf)); + chrbuf, sizeof chrbuf)); str += len; break; @@ -281,7 +288,7 @@ clnt_perrno (enum clnt_stat num) char * clnt_spcreateerror (const char *msg) { - char buf[1024]; + char chrbuf[1024]; char *str = _buf (); char *cp; int len; @@ -301,7 +308,7 @@ clnt_spcreateerror (const char *msg) case RPC_SYSTEMERROR: cp = stpcpy (stpcpy (cp, " - "), __strerror_r (rpc_createerr.cf_error.re_errno, - buf, sizeof buf)); + chrbuf, sizeof chrbuf)); break; default: break; diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c index 8ed589c93d..ee70e9568b 100644 --- a/sunrpc/clnt_raw.c +++ b/sunrpc/clnt_raw.c @@ -52,15 +52,19 @@ static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; /* * This is the "network" we will be moving stuff over. */ -static struct clntraw_private +struct clntraw_private_s { CLIENT client_object; XDR xdr_stream; char _raw_buf[UDPMSGSIZE]; char mashl_callmsg[MCALL_MSG_SIZE]; u_int mcnt; - } - *clntraw_private; + }; +#ifdef _RPC_THREAD_SAFE_ +#define clntraw_private ((struct clntraw_private_s *)RPC_THREAD_VARIABLE(clntraw_private_s)) +#else +static struct clntraw_private_s *clntraw_private; +#endif static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval); @@ -86,14 +90,14 @@ static struct clnt_ops client_ops = CLIENT * clntraw_create (u_long prog, u_long vers) { - struct clntraw_private *clp = clntraw_private; + struct clntraw_private_s *clp = clntraw_private; struct rpc_msg call_msg; XDR *xdrs = &clp->xdr_stream; CLIENT *client = &clp->client_object; if (clp == 0) { - clp = (struct clntraw_private *) calloc (1, sizeof (*clp)); + clp = (struct clntraw_private_s *) calloc (1, sizeof (*clp)); if (clp == 0) return (0); clntraw_private = clp; @@ -136,7 +140,7 @@ clntraw_call (h, proc, xargs, argsp, xresults, resultsp, timeout) caddr_t resultsp; struct timeval timeout; { - struct clntraw_private *clp = clntraw_private; + struct clntraw_private_s *clp = clntraw_private; XDR *xdrs = &clp->xdr_stream; struct rpc_msg msg; enum clnt_stat status; @@ -220,7 +224,7 @@ clntraw_freeres (cl, xdr_res, res_ptr) xdrproc_t xdr_res; caddr_t res_ptr; { - struct clntraw_private *clp = clntraw_private; + struct clntraw_private_s *clp = clntraw_private; XDR *xdrs = &clp->xdr_stream; bool_t rval; diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c index 19c03b0ba7..03b65cdbc0 100644 --- a/sunrpc/clnt_simp.c +++ b/sunrpc/clnt_simp.c @@ -47,20 +47,24 @@ static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; #include <netdb.h> #include <string.h> -static struct callrpc_private +struct callrpc_private_s { CLIENT *client; int socket; u_long oldprognum, oldversnum, valid; char *oldhost; - } - *callrpc_private; + }; +#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, u_long prognum, u_long versnum, u_long procnum, xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out) { - struct callrpc_private *crp = callrpc_private; + struct callrpc_private_s *crp = callrpc_private; struct sockaddr_in server_addr; enum clnt_stat clnt_stat; struct hostent hostbuf, *hp; @@ -68,7 +72,7 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, if (crp == 0) { - crp = (struct callrpc_private *) calloc (1, sizeof (*crp)); + crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp)); if (crp == 0) return 0; callrpc_private = crp; @@ -141,3 +145,17 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, 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); + } +} +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c index 6e9d4a3cb4..5df8f6fd57 100644 --- a/sunrpc/key_call.c +++ b/sunrpc/key_call.c @@ -359,7 +359,11 @@ struct key_call_private { pid_t pid; /* process-id at moment of creation */ uid_t uid; /* user-id at last authorization */ }; +#ifdef _RPC_THREAD_SAFE_ +#define key_call_private_main ((struct key_call_private *)RPC_THREAD_VARIABLE(key_call_private_s)) +#else static struct key_call_private *key_call_private_main; +#endif __libc_lock_define_initialized (static, keycall_lock) /* @@ -610,3 +614,17 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg, return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt); #endif } + +#ifdef _RPC_THREAD_SAFE_ +void +__rpc_thread_key_cleanup (void) +{ + struct key_call_private *kcp = RPC_THREAD_VARIABLE(key_call_private_s); + + if (kcp) { + if (kcp->client) + clnt_destroy(kcp->client); + free (kcp); + } +} +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/sunrpc/rpc_common.c b/sunrpc/rpc_common.c index 57e14351ea..6b22b3f66b 100644 --- a/sunrpc/rpc_common.c +++ b/sunrpc/rpc_common.c @@ -27,6 +27,14 @@ * Mountain View, California 94043 */ #include <rpc/rpc.h> + +#ifdef _RPC_THREAD_SAFE_ +#undef svc_fdset +#undef rpc_createerr +#undef svc_pollfd +#undef svc_max_pollfd +#endif /* _RPC_THREAD_SAFE_ */ + /* * This file should only contain common data (global data) that is exported * by public interfaces diff --git a/sunrpc/rpc_thread.c b/sunrpc/rpc_thread.c new file mode 100644 index 0000000000..0b004c403f --- /dev/null +++ b/sunrpc/rpc_thread.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <bits/libc-lock.h> +#include <rpc/rpc.h> +#include <assert.h> + +#include <bits/libc-lock.h> +#include <bits/libc-tsd.h> + +#ifdef _RPC_THREAD_SAFE_ + + +/* Variable used in non-threaded applications. */ +static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem; +static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data = + &__libc_tsd_RPC_VARS_mem; + +/* + * Task-variable destructor + */ +void +__rpc_thread_destroy (void) +{ + struct rpc_thread_variables *tvp = __rpc_thread_variables(); + + if (tvp != NULL) { + __rpc_thread_svc_cleanup (); + __rpc_thread_clnt_cleanup (); + __rpc_thread_key_cleanup (); + free (tvp->authnone_private_s); + free (tvp->clnt_perr_buf_s); + free (tvp->clntraw_private_s); + free (tvp->svcraw_private_s); + free (tvp->authdes_cache_s); + free (tvp->authdes_lru_s); + free (tvp); + } +} + + +struct rpc_thread_variables * +__rpc_thread_variables (void) +{ + struct rpc_thread_variables *tvp; + + tvp = __libc_tsd_get (RPC_VARS); + if (tvp == NULL) { + tvp = calloc (1, sizeof *tvp); + if (tvp != NULL) + __libc_tsd_set (RPC_VARS, tvp); + else + tvp = __libc_tsd_RPC_VARS_data; + } + return tvp; +} +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/sunrpc/svc.c b/sunrpc/svc.c index 4446692dc0..6357d51354 100644 --- a/sunrpc/svc.c +++ b/sunrpc/svc.c @@ -43,7 +43,11 @@ #include <rpc/pmap_clnt.h> #include <sys/poll.h> +#ifdef _RPC_THREAD_SAFE_ +#define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s)) +#else static SVCXPRT **xports; +#endif #define NULL_SVC ((struct svc_callout *)0) #define RQCRED_SIZE 400 /* this size is excessive */ @@ -52,12 +56,17 @@ static SVCXPRT **xports; Each entry represents a set of procedures (an rpc program). The dispatch routine takes request structs and runs the appropriate procedure. */ -static struct svc_callout { +struct svc_callout { struct svc_callout *sc_next; rpcprog_t sc_prog; rpcvers_t sc_vers; void (*sc_dispatch) (struct svc_req *, SVCXPRT *); -} *svc_head; +}; +#ifdef _RPC_THREAD_SAFE_ +#define svc_head ((struct svc_callout *)RPC_THREAD_VARIABLE(svc_head_s)) +#else +static struct svc_callout *svc_head; +#endif /* *************** SVCXPRT related stuff **************** */ @@ -464,3 +473,16 @@ svc_getreq_common (const int fd) } while (stat == XPRT_MOREREQS); } + +#ifdef _RPC_THREAD_SAFE_ + +void +__rpc_thread_svc_cleanup (void) +{ + struct svc_callout *svcp; + + while ((svcp = svc_head) != NULL) + svc_unregister (svcp->sc_prog, svcp->sc_vers); +} + +#endif /* _RPC_THREAD_SAFE_ */ diff --git a/sunrpc/svc_raw.c b/sunrpc/svc_raw.c index 1a7fcaa4e4..e4752a6cd1 100644 --- a/sunrpc/svc_raw.c +++ b/sunrpc/svc_raw.c @@ -46,14 +46,18 @@ static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro"; /* * This is the "network" that we will be moving data over */ -static struct svcraw_private +struct svcraw_private_s { char _raw_buf[UDPMSGSIZE]; SVCXPRT server; XDR xdr_stream; char verf_body[MAX_AUTH_BYTES]; - } - *svcraw_private; + }; +#ifdef _RPC_THREAD_SAFE_ +#define svcraw_private ((struct svcraw_private_s *)RPC_THREAD_VARIABLE(svcraw_private_s)) +#else +static struct svcraw_private_s *svcraw_private; +#endif static bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *); static enum xprt_stat svcraw_stat (SVCXPRT *); @@ -75,11 +79,11 @@ static struct xp_ops server_ops = SVCXPRT * svcraw_create (void) { - struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; if (srp == 0) { - srp = (struct svcraw_private *) calloc (1, sizeof (*srp)); + srp = (struct svcraw_private_s *) calloc (1, sizeof (*srp)); if (srp == 0) return NULL; } @@ -102,7 +106,7 @@ svcraw_recv (xprt, msg) SVCXPRT *xprt; struct rpc_msg *msg; { - struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; XDR *xdrs; if (srp == 0) @@ -118,7 +122,7 @@ svcraw_recv (xprt, msg) static bool_t svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg) { - struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; XDR *xdrs; if (srp == 0) @@ -135,7 +139,7 @@ svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg) static bool_t svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { - struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; if (srp == 0) return FALSE; @@ -145,7 +149,7 @@ svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) static bool_t svcraw_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) { - struct svcraw_private *srp = svcraw_private; + struct svcraw_private_s *srp = svcraw_private; XDR *xdrs; if (srp == 0) diff --git a/sunrpc/svc_simple.c b/sunrpc/svc_simple.c index 949ebba627..979b5b69df 100644 --- a/sunrpc/svc_simple.c +++ b/sunrpc/svc_simple.c @@ -51,24 +51,33 @@ static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro"; # define fputs(s, f) _IO_fputs (s, f) #endif -static struct proglst +struct proglst_ { char *(*p_progname) (char *); int p_prognum; int p_procnum; xdrproc_t p_inproc, p_outproc; - struct proglst *p_nxt; - } - *proglst; + struct proglst_ *p_nxt; + }; +#ifdef _RPC_THREAD_SAFE_ +#define proglst ((struct proglst_ *)RPC_THREAD_VARIABLE(svcsimple_proglst_s)) +#else +static struct proglst_ *proglst; +#endif + -static void universal (struct svc_req *rqstp, SVCXPRT *transp); +static void universal (struct svc_req *rqstp, SVCXPRT *transp_s); +#ifdef _RPC_THREAD_SAFE_ +#define transp ((SVCXPRT *)RPC_THREAD_VARIABLE(svcsimple_transp_s)) +#else static SVCXPRT *transp; +#endif int registerrpc (u_long prognum, u_long versnum, u_long procnum, char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc) { - struct proglst *pl; + struct proglst_ *pl; if (procnum == NULLPROC) { @@ -93,7 +102,7 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum, prognum, versnum); return -1; } - pl = (struct proglst *) malloc (sizeof (struct proglst)); + pl = (struct proglst_ *) malloc (sizeof (struct proglst_)); if (pl == NULL) { (void) fprintf (stderr, _("registerrpc: out of memory\n")); @@ -110,19 +119,19 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum, } static void -universal (struct svc_req *rqstp, SVCXPRT *transp) +universal (struct svc_req *rqstp, SVCXPRT *transp_l) { int prog, proc; char *outdata; char xdrbuf[UDPMSGSIZE]; - struct proglst *pl; + struct proglst_ *pl; /* * enforce "procnum 0 is echo" convention */ if (rqstp->rq_proc == NULLPROC) { - if (svc_sendreply (transp, (xdrproc_t)xdr_void, (char *) NULL) == FALSE) + if (svc_sendreply (transp_l, (xdrproc_t)xdr_void, (char *) NULL) == FALSE) { (void) fprintf (stderr, "xxx\n"); exit (1); @@ -136,16 +145,16 @@ universal (struct svc_req *rqstp, SVCXPRT *transp) { /* decode arguments into a CLEAN buffer */ __bzero (xdrbuf, sizeof (xdrbuf)); /* required ! */ - if (!svc_getargs (transp, pl->p_inproc, xdrbuf)) + if (!svc_getargs (transp_l, pl->p_inproc, xdrbuf)) { - svcerr_decode (transp); + svcerr_decode (transp_l); return; } outdata = (*(pl->p_progname)) (xdrbuf); if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void) /* there was an error */ return; - if (!svc_sendreply (transp, pl->p_outproc, outdata)) + if (!svc_sendreply (transp_l, pl->p_outproc, outdata)) { (void) fprintf (stderr, _ ("trouble replying to prog %d\n"), @@ -153,7 +162,7 @@ universal (struct svc_req *rqstp, SVCXPRT *transp) exit (1); } /* free the decoded arguments */ - (void) svc_freeargs (transp, pl->p_inproc, xdrbuf); + (void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf); return; } (void) fprintf (stderr, _ ("never registered prog %d\n"), prog); diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c index 56b683a3ab..4530066a45 100644 --- a/sunrpc/svcauth_des.c +++ b/sunrpc/svcauth_des.c @@ -46,7 +46,7 @@ #include <string.h> #include <sys/param.h> #include <netinet/in.h> -#include <rpc/types.h> +#include <rpc/rpc.h> #include <rpc/xdr.h> #include <rpc/auth.h> #include <rpc/auth_des.h> @@ -71,8 +71,13 @@ struct cache_entry struct rpc_timeval laststamp; /* detect replays of creds */ char *localcred; /* generic local credential */ }; -static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ; -static int *authdes_lru /* [AUTHDES_CACHESZ] */ ; +#ifdef _RPC_THREAD_SAFE_ +#define authdes_cache ((struct cache_entry *)RPC_THREAD_VARIABLE(authdes_cache_s)) +#define authdes_lru ((int *)RPC_THREAD_VARIABLE(authdes_lru_s)) +#else +static struct cache_entry *authdes_cache; +static int *authdes_lru; +#endif static void cache_init (void) internal_function; /* initialize the cache */ static short cache_spot (des_block *, char *, struct rpc_timeval *) |