129 lines
4.1 KiB
Diff
129 lines
4.1 KiB
Diff
|
From 5c797a24a7d6337b5e654079a8d815199b1e8364 Mon Sep 17 00:00:00 2001
|
||
|
From: Carmelo Amoroso <carmelo.amoroso@st.com>
|
||
|
Date: Thu, 2 Feb 2012 18:22:36 +0100
|
||
|
Subject: [PATCH] inet:rpc: fix authnone_marshal in multithreading context
|
||
|
|
||
|
This is a port of glibc's fix by Zack Weinberg as reported
|
||
|
in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=142312,
|
||
|
and discussed in http://sourceware.org/ml/libc-alpha/2002-04/msg00069.html
|
||
|
and following.
|
||
|
|
||
|
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
|
||
|
---
|
||
|
libc/inet/rpc/auth_none.c | 59 +++++++++++++++++++++----------------------
|
||
|
libc/inet/rpc/rpc_private.h | 2 --
|
||
|
libc/inet/rpc/rpc_thread.c | 1 -
|
||
|
3 files changed, 29 insertions(+), 33 deletions(-)
|
||
|
|
||
|
diff --git a/libc/inet/rpc/auth_none.c b/libc/inet/rpc/auth_none.c
|
||
|
index c48bbfe..d066f6b 100644
|
||
|
--- a/libc/inet/rpc/auth_none.c
|
||
|
+++ b/libc/inet/rpc/auth_none.c
|
||
|
@@ -66,49 +66,48 @@ struct authnone_private_s {
|
||
|
char marshalled_client[MAX_MARSHAL_SIZE];
|
||
|
u_int mcnt;
|
||
|
};
|
||
|
-#ifdef __UCLIBC_HAS_THREADS__
|
||
|
-#define authnone_private (*(struct authnone_private_s **)&RPC_THREAD_VARIABLE(authnone_private_s))
|
||
|
-#else
|
||
|
-static struct authnone_private_s *authnone_private;
|
||
|
-#endif
|
||
|
|
||
|
-AUTH *
|
||
|
-authnone_create (void)
|
||
|
+static struct authnone_private_s authnone_private;
|
||
|
+__libc_once_define(static, authnone_private_guard);
|
||
|
+
|
||
|
+static void authnone_create_once (void);
|
||
|
+
|
||
|
+static void
|
||
|
+authnone_create_once (void)
|
||
|
{
|
||
|
struct authnone_private_s *ap;
|
||
|
XDR xdr_stream;
|
||
|
XDR *xdrs;
|
||
|
|
||
|
- ap = (struct authnone_private_s *) authnone_private;
|
||
|
- if (ap == NULL)
|
||
|
- {
|
||
|
- ap = (struct authnone_private_s *) calloc (1, sizeof (*ap));
|
||
|
- if (ap == NULL)
|
||
|
- return NULL;
|
||
|
- authnone_private = ap;
|
||
|
- }
|
||
|
- if (!ap->mcnt)
|
||
|
- {
|
||
|
- ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
|
||
|
- ap->no_client.ah_ops = (struct auth_ops *)&ops;
|
||
|
- xdrs = &xdr_stream;
|
||
|
- xdrmem_create (xdrs, ap->marshalled_client, (u_int) MAX_MARSHAL_SIZE,
|
||
|
- XDR_ENCODE);
|
||
|
- (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_cred);
|
||
|
- (void) xdr_opaque_auth (xdrs, &ap->no_client.ah_verf);
|
||
|
- ap->mcnt = XDR_GETPOS (xdrs);
|
||
|
- XDR_DESTROY (xdrs);
|
||
|
- }
|
||
|
- return (&ap->no_client);
|
||
|
+ ap = &authnone_private;
|
||
|
+
|
||
|
+ ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
|
||
|
+ ap->no_client.ah_ops = (struct auth_ops *) &ops;
|
||
|
+ xdrs = &xdr_stream;
|
||
|
+ xdrmem_create(xdrs, ap->marshalled_client,
|
||
|
+ (u_int) MAX_MARSHAL_SIZE, XDR_ENCODE);
|
||
|
+ (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
|
||
|
+ (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
|
||
|
+ ap->mcnt = XDR_GETPOS (xdrs);
|
||
|
+ XDR_DESTROY (xdrs);
|
||
|
+}
|
||
|
+
|
||
|
+AUTH *
|
||
|
+authnone_create (void)
|
||
|
+{
|
||
|
+ __libc_once (authnone_private_guard, authnone_create_once);
|
||
|
+ return &authnone_private.no_client;
|
||
|
}
|
||
|
libc_hidden_def(authnone_create)
|
||
|
|
||
|
static bool_t
|
||
|
-authnone_marshal (AUTH *client attribute_unused, XDR *xdrs)
|
||
|
+authnone_marshal (AUTH *client, XDR *xdrs)
|
||
|
{
|
||
|
struct authnone_private_s *ap;
|
||
|
|
||
|
- ap = authnone_private;
|
||
|
+ /* authnone_create returned authnone_private->no_client, which is
|
||
|
+ the first field of struct authnone_private_s. */
|
||
|
+ ap = (struct authnone_private_s *) client;
|
||
|
if (ap == NULL)
|
||
|
return FALSE;
|
||
|
return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
|
||
|
diff --git a/libc/inet/rpc/rpc_private.h b/libc/inet/rpc/rpc_private.h
|
||
|
index ede3ddf..e1214d2 100644
|
||
|
--- a/libc/inet/rpc/rpc_private.h
|
||
|
+++ b/libc/inet/rpc/rpc_private.h
|
||
|
@@ -18,8 +18,6 @@ struct rpc_thread_variables {
|
||
|
struct pollfd *svc_pollfd_s; /* Global, rpc_common.c */
|
||
|
int svc_max_pollfd_s; /* Global, rpc_common.c */
|
||
|
|
||
|
- void *authnone_private_s; /* auth_none.c */
|
||
|
-
|
||
|
void *clnt_perr_buf_s; /* clnt_perr.c */
|
||
|
|
||
|
void *clntraw_private_s; /* clnt_raw.c */
|
||
|
diff --git a/libc/inet/rpc/rpc_thread.c b/libc/inet/rpc/rpc_thread.c
|
||
|
index 71303b2..3367659 100644
|
||
|
--- a/libc/inet/rpc/rpc_thread.c
|
||
|
+++ b/libc/inet/rpc/rpc_thread.c
|
||
|
@@ -32,7 +32,6 @@ __rpc_thread_destroy (void)
|
||
|
__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);
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|