mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
Update.
* sunrpc/Makefile (routines): Add rpc_thread. (CPPFLAGS): Add -D_RPC_THREAD_SAFE. * sunrpc/rpc_thread.c: New file. * sunrpc/Versions [libc] (GLIBC_2.2.3): Export __rpc_thread_destroy. * sunrpc/auth_none.c: Don't use global variables. Access state in thread-local storage. * sunrpc/clnt_perr.c: Likewise. * sunrpc/clnt_raw.c: Likewise. * sunrpc/clnt_simp.c: Likewise. * sunrpc/key_call.c: Likewise. * sunrpc/rpc_common.c: Likewise. * sunrpc/svc.c: Likewise. * sunrpc/svc_raw.c: Likewise. * sunrpc/svc_simple.c: Likewise. * sunrpc/svcauth_des.c: Likewise. * hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add _HURD_THREADVAR_RPC_VARS. * sysdeps/generic/bits/libc-tsd.h: Mention _LIBC_TSD_KEY_RPC_VARS. * include/rpc/rpc.h: Define data structures for internal thread-local "global" variables. Based on patches by Eric Norum <eric.norum@usask.ca>.
This commit is contained in:
parent
373e6a512c
commit
f1e4a4a403
22
ChangeLog
22
ChangeLog
@ -1,5 +1,27 @@
|
|||||||
2001-03-20 Ulrich Drepper <drepper@redhat.com>
|
2001-03-20 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sunrpc/Makefile (routines): Add rpc_thread.
|
||||||
|
(CPPFLAGS): Add -D_RPC_THREAD_SAFE.
|
||||||
|
* sunrpc/rpc_thread.c: New file.
|
||||||
|
* sunrpc/Versions [libc] (GLIBC_2.2.3): Export __rpc_thread_destroy.
|
||||||
|
* sunrpc/auth_none.c: Don't use global variables. Access state in
|
||||||
|
thread-local storage.
|
||||||
|
* sunrpc/clnt_perr.c: Likewise.
|
||||||
|
* sunrpc/clnt_raw.c: Likewise.
|
||||||
|
* sunrpc/clnt_simp.c: Likewise.
|
||||||
|
* sunrpc/key_call.c: Likewise.
|
||||||
|
* sunrpc/rpc_common.c: Likewise.
|
||||||
|
* sunrpc/svc.c: Likewise.
|
||||||
|
* sunrpc/svc_raw.c: Likewise.
|
||||||
|
* sunrpc/svc_simple.c: Likewise.
|
||||||
|
* sunrpc/svcauth_des.c: Likewise.
|
||||||
|
* hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add
|
||||||
|
_HURD_THREADVAR_RPC_VARS.
|
||||||
|
* sysdeps/generic/bits/libc-tsd.h: Mention _LIBC_TSD_KEY_RPC_VARS.
|
||||||
|
* include/rpc/rpc.h: Define data structures for internal thread-local
|
||||||
|
"global" variables.
|
||||||
|
Based on patches by Eric Norum <eric.norum@usask.ca>.
|
||||||
|
|
||||||
* elf/dl-load.c: Various little optimizations.
|
* elf/dl-load.c: Various little optimizations.
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Return
|
* sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Return
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* libc-internal interface for thread-specific data. Stub version.
|
/* libc-internal interface for thread-specific data. Stub version.
|
||||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -35,6 +35,7 @@
|
|||||||
and contains (at least):
|
and contains (at least):
|
||||||
_LIBC_TSD_KEY_MALLOC
|
_LIBC_TSD_KEY_MALLOC
|
||||||
_LIBC_TSD_KEY_DL_ERROR
|
_LIBC_TSD_KEY_DL_ERROR
|
||||||
|
_LIBC_TSD_KEY_RPC_VARS
|
||||||
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
|
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
|
||||||
Some implementations may not provide any enum at all and instead
|
Some implementations may not provide any enum at all and instead
|
||||||
using string pasting in the macros. */
|
using string pasting in the macros. */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Internal per-thread variables for the Hurd.
|
/* Internal per-thread variables for the Hurd.
|
||||||
Copyright (C) 1994, 95, 97, 98, 99 Free Software Foundation, Inc.
|
Copyright (C) 1994, 95, 97, 98, 99, 2001 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -59,9 +59,10 @@ enum __hurd_threadvar_index
|
|||||||
_HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */
|
_HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */
|
||||||
_HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */
|
_HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */
|
||||||
_HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */
|
_HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */
|
||||||
_HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */
|
_HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */
|
||||||
_HURD_THREADVAR_MALLOC, /* For use of malloc. */
|
_HURD_THREADVAR_MALLOC, /* For use of malloc. */
|
||||||
_HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */
|
_HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */
|
||||||
|
_HURD_THREADVAR_RPC_VARS, /* For state of RPC functions. */
|
||||||
_HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */
|
_HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
2001-03-20 Ulrich Drepper <drepper@redhat.com>
|
2001-03-20 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* cancel.c (__pthread_perform_cleanup): Call __rpc_thread_destroy.
|
* cancel.c (__pthread_perform_cleanup): Call __rpc_thread_destroy.
|
||||||
|
* sysdeps/pthread/bits/libc-tsd.h: Define _LIBC_TSD_KEY_VARS.
|
||||||
|
|
||||||
2001-03-18 Ulrich Drepper <drepper@redhat.com>
|
2001-03-18 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* libc-internal interface for thread-specific data. LinuxThreads version.
|
/* libc-internal interface for thread-specific data. LinuxThreads version.
|
||||||
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
|
Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -24,6 +24,7 @@
|
|||||||
/* Fast thread-specific data internal to libc. */
|
/* Fast thread-specific data internal to libc. */
|
||||||
enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
|
enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
|
||||||
_LIBC_TSD_KEY_DL_ERROR,
|
_LIBC_TSD_KEY_DL_ERROR,
|
||||||
|
_LIBC_TSD_KEY_RPC_VARS,
|
||||||
_LIBC_TSD_KEY_N };
|
_LIBC_TSD_KEY_N };
|
||||||
|
|
||||||
extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW;
|
extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW;
|
||||||
|
@ -60,7 +60,7 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
|
|||||||
clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \
|
clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \
|
||||||
clnt_udp rpc_dtable get_myaddr getrpcport \
|
clnt_udp rpc_dtable get_myaddr getrpcport \
|
||||||
pmap_clnt pm_getmaps pm_getport pmap_prot \
|
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 svc_auth svc_authux svc_raw svc_run svc_simple \
|
||||||
svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
|
svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
|
||||||
xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
|
xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
|
||||||
@ -116,6 +116,7 @@ CFLAGS-xkey_prot.c = -Wno-unused
|
|||||||
ifeq (yes,$(have_doors))
|
ifeq (yes,$(have_doors))
|
||||||
CPPFLAGS-key_call.c += -DHAVE_DOORS=1
|
CPPFLAGS-key_call.c += -DHAVE_DOORS=1
|
||||||
endif
|
endif
|
||||||
|
CPPFLAGS += -D_RPC_THREAD_SAFE_
|
||||||
|
|
||||||
include ../Rules
|
include ../Rules
|
||||||
|
|
||||||
|
@ -109,4 +109,7 @@ libc {
|
|||||||
GLIBC_2.2 {
|
GLIBC_2.2 {
|
||||||
svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd;
|
svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd;
|
||||||
}
|
}
|
||||||
|
GLIBC_2.2.3 {
|
||||||
|
__rpc_thread_destroy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,7 @@
|
|||||||
* credentials and verifiers to remote systems.
|
* credentials and verifiers to remote systems.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rpc/types.h>
|
#include <rpc/rpc.h>
|
||||||
#include <rpc/auth.h>
|
|
||||||
|
|
||||||
#define MAX_MARSHEL_SIZE 20
|
#define MAX_MARSHEL_SIZE 20
|
||||||
|
|
||||||
@ -57,24 +56,29 @@ static struct auth_ops ops = {
|
|||||||
authnone_destroy
|
authnone_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct authnone_private
|
struct authnone_private_s {
|
||||||
{
|
|
||||||
AUTH no_client;
|
AUTH no_client;
|
||||||
char marshalled_client[MAX_MARSHEL_SIZE];
|
char marshalled_client[MAX_MARSHEL_SIZE];
|
||||||
u_int mcnt;
|
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 *
|
AUTH *
|
||||||
authnone_create (void)
|
authnone_create (void)
|
||||||
{
|
{
|
||||||
struct authnone_private *ap = authnone_private;
|
struct authnone_private_s *ap;
|
||||||
XDR xdr_stream;
|
XDR xdr_stream;
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
|
|
||||||
if (ap == 0)
|
ap = (struct authnone_private_s *) authnone_private;
|
||||||
|
if (ap == NULL)
|
||||||
{
|
{
|
||||||
ap = (struct authnone_private *) calloc (1, sizeof (*ap));
|
ap = (struct authnone_private_s *) calloc (1, sizeof (*ap));
|
||||||
if (ap == 0)
|
if (ap == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
authnone_private = ap;
|
authnone_private = ap;
|
||||||
}
|
}
|
||||||
@ -97,10 +101,11 @@ authnone_create (void)
|
|||||||
static bool_t
|
static bool_t
|
||||||
authnone_marshal (AUTH *client, XDR *xdrs)
|
authnone_marshal (AUTH *client, XDR *xdrs)
|
||||||
{
|
{
|
||||||
struct authnone_private *ap = authnone_private;
|
struct authnone_private_s *ap;
|
||||||
|
|
||||||
if (ap == 0)
|
ap = (struct authnone_private_s *) authnone_private;
|
||||||
return 0;
|
if (ap == NULL)
|
||||||
|
return FALSE;
|
||||||
return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
|
return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,7 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <rpc/types.h>
|
#include <rpc/rpc.h>
|
||||||
#include <rpc/auth.h>
|
|
||||||
#include <rpc/clnt.h>
|
|
||||||
|
|
||||||
#ifdef USE_IN_LIBIO
|
#ifdef USE_IN_LIBIO
|
||||||
# include <libio/iolibio.h>
|
# 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;
|
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;
|
static char *buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
_buf (void)
|
_buf (void)
|
||||||
@ -67,7 +74,7 @@ _buf (void)
|
|||||||
char *
|
char *
|
||||||
clnt_sperror (CLIENT * rpch, const char *msg)
|
clnt_sperror (CLIENT * rpch, const char *msg)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char chrbuf[1024];
|
||||||
struct rpc_err e;
|
struct rpc_err e;
|
||||||
char *err;
|
char *err;
|
||||||
char *str = _buf ();
|
char *str = _buf ();
|
||||||
@ -103,7 +110,7 @@ clnt_sperror (CLIENT * rpch, const char *msg)
|
|||||||
case RPC_CANTSEND:
|
case RPC_CANTSEND:
|
||||||
case RPC_CANTRECV:
|
case RPC_CANTRECV:
|
||||||
len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno,
|
len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno,
|
||||||
buf, sizeof buf));
|
chrbuf, sizeof chrbuf));
|
||||||
str += len;
|
str += len;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -281,7 +288,7 @@ clnt_perrno (enum clnt_stat num)
|
|||||||
char *
|
char *
|
||||||
clnt_spcreateerror (const char *msg)
|
clnt_spcreateerror (const char *msg)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char chrbuf[1024];
|
||||||
char *str = _buf ();
|
char *str = _buf ();
|
||||||
char *cp;
|
char *cp;
|
||||||
int len;
|
int len;
|
||||||
@ -301,7 +308,7 @@ clnt_spcreateerror (const char *msg)
|
|||||||
case RPC_SYSTEMERROR:
|
case RPC_SYSTEMERROR:
|
||||||
cp = stpcpy (stpcpy (cp, " - "),
|
cp = stpcpy (stpcpy (cp, " - "),
|
||||||
__strerror_r (rpc_createerr.cf_error.re_errno,
|
__strerror_r (rpc_createerr.cf_error.re_errno,
|
||||||
buf, sizeof buf));
|
chrbuf, sizeof chrbuf));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -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.
|
* This is the "network" we will be moving stuff over.
|
||||||
*/
|
*/
|
||||||
static struct clntraw_private
|
struct clntraw_private_s
|
||||||
{
|
{
|
||||||
CLIENT client_object;
|
CLIENT client_object;
|
||||||
XDR xdr_stream;
|
XDR xdr_stream;
|
||||||
char _raw_buf[UDPMSGSIZE];
|
char _raw_buf[UDPMSGSIZE];
|
||||||
char mashl_callmsg[MCALL_MSG_SIZE];
|
char mashl_callmsg[MCALL_MSG_SIZE];
|
||||||
u_int mcnt;
|
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,
|
static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t,
|
||||||
xdrproc_t, caddr_t, struct timeval);
|
xdrproc_t, caddr_t, struct timeval);
|
||||||
@ -86,14 +90,14 @@ static struct clnt_ops client_ops =
|
|||||||
CLIENT *
|
CLIENT *
|
||||||
clntraw_create (u_long prog, u_long vers)
|
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;
|
struct rpc_msg call_msg;
|
||||||
XDR *xdrs = &clp->xdr_stream;
|
XDR *xdrs = &clp->xdr_stream;
|
||||||
CLIENT *client = &clp->client_object;
|
CLIENT *client = &clp->client_object;
|
||||||
|
|
||||||
if (clp == 0)
|
if (clp == 0)
|
||||||
{
|
{
|
||||||
clp = (struct clntraw_private *) calloc (1, sizeof (*clp));
|
clp = (struct clntraw_private_s *) calloc (1, sizeof (*clp));
|
||||||
if (clp == 0)
|
if (clp == 0)
|
||||||
return (0);
|
return (0);
|
||||||
clntraw_private = clp;
|
clntraw_private = clp;
|
||||||
@ -136,7 +140,7 @@ clntraw_call (h, proc, xargs, argsp, xresults, resultsp, timeout)
|
|||||||
caddr_t resultsp;
|
caddr_t resultsp;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
{
|
{
|
||||||
struct clntraw_private *clp = clntraw_private;
|
struct clntraw_private_s *clp = clntraw_private;
|
||||||
XDR *xdrs = &clp->xdr_stream;
|
XDR *xdrs = &clp->xdr_stream;
|
||||||
struct rpc_msg msg;
|
struct rpc_msg msg;
|
||||||
enum clnt_stat status;
|
enum clnt_stat status;
|
||||||
@ -220,7 +224,7 @@ clntraw_freeres (cl, xdr_res, res_ptr)
|
|||||||
xdrproc_t xdr_res;
|
xdrproc_t xdr_res;
|
||||||
caddr_t res_ptr;
|
caddr_t res_ptr;
|
||||||
{
|
{
|
||||||
struct clntraw_private *clp = clntraw_private;
|
struct clntraw_private_s *clp = clntraw_private;
|
||||||
XDR *xdrs = &clp->xdr_stream;
|
XDR *xdrs = &clp->xdr_stream;
|
||||||
bool_t rval;
|
bool_t rval;
|
||||||
|
|
||||||
|
@ -47,20 +47,24 @@ static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static struct callrpc_private
|
struct callrpc_private_s
|
||||||
{
|
{
|
||||||
CLIENT *client;
|
CLIENT *client;
|
||||||
int socket;
|
int socket;
|
||||||
u_long oldprognum, oldversnum, valid;
|
u_long oldprognum, oldversnum, valid;
|
||||||
char *oldhost;
|
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
|
int
|
||||||
callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
|
callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
|
||||||
xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
|
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;
|
struct sockaddr_in server_addr;
|
||||||
enum clnt_stat clnt_stat;
|
enum clnt_stat clnt_stat;
|
||||||
struct hostent hostbuf, *hp;
|
struct hostent hostbuf, *hp;
|
||||||
@ -68,7 +72,7 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
|
|||||||
|
|
||||||
if (crp == 0)
|
if (crp == 0)
|
||||||
{
|
{
|
||||||
crp = (struct callrpc_private *) calloc (1, sizeof (*crp));
|
crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
|
||||||
if (crp == 0)
|
if (crp == 0)
|
||||||
return 0;
|
return 0;
|
||||||
callrpc_private = crp;
|
callrpc_private = crp;
|
||||||
@ -141,3 +145,17 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
|
|||||||
crp->valid = 0;
|
crp->valid = 0;
|
||||||
return (int) clnt_stat;
|
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_ */
|
||||||
|
@ -359,7 +359,11 @@ struct key_call_private {
|
|||||||
pid_t pid; /* process-id at moment of creation */
|
pid_t pid; /* process-id at moment of creation */
|
||||||
uid_t uid; /* user-id at last authorization */
|
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;
|
static struct key_call_private *key_call_private_main;
|
||||||
|
#endif
|
||||||
__libc_lock_define_initialized (static, keycall_lock)
|
__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);
|
return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
|
||||||
#endif
|
#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_ */
|
||||||
|
@ -27,6 +27,14 @@
|
|||||||
* Mountain View, California 94043
|
* Mountain View, California 94043
|
||||||
*/
|
*/
|
||||||
#include <rpc/rpc.h>
|
#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
|
* This file should only contain common data (global data) that is exported
|
||||||
* by public interfaces
|
* by public interfaces
|
||||||
|
55
sunrpc/rpc_thread.c
Normal file
55
sunrpc/rpc_thread.c
Normal file
@ -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_ */
|
26
sunrpc/svc.c
26
sunrpc/svc.c
@ -43,7 +43,11 @@
|
|||||||
#include <rpc/pmap_clnt.h>
|
#include <rpc/pmap_clnt.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
#ifdef _RPC_THREAD_SAFE_
|
||||||
|
#define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s))
|
||||||
|
#else
|
||||||
static SVCXPRT **xports;
|
static SVCXPRT **xports;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NULL_SVC ((struct svc_callout *)0)
|
#define NULL_SVC ((struct svc_callout *)0)
|
||||||
#define RQCRED_SIZE 400 /* this size is excessive */
|
#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).
|
Each entry represents a set of procedures (an rpc program).
|
||||||
The dispatch routine takes request structs and runs the
|
The dispatch routine takes request structs and runs the
|
||||||
appropriate procedure. */
|
appropriate procedure. */
|
||||||
static struct svc_callout {
|
struct svc_callout {
|
||||||
struct svc_callout *sc_next;
|
struct svc_callout *sc_next;
|
||||||
rpcprog_t sc_prog;
|
rpcprog_t sc_prog;
|
||||||
rpcvers_t sc_vers;
|
rpcvers_t sc_vers;
|
||||||
void (*sc_dispatch) (struct svc_req *, SVCXPRT *);
|
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 **************** */
|
/* *************** SVCXPRT related stuff **************** */
|
||||||
|
|
||||||
@ -464,3 +473,16 @@ svc_getreq_common (const int fd)
|
|||||||
}
|
}
|
||||||
while (stat == XPRT_MOREREQS);
|
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_ */
|
||||||
|
@ -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
|
* This is the "network" that we will be moving data over
|
||||||
*/
|
*/
|
||||||
static struct svcraw_private
|
struct svcraw_private_s
|
||||||
{
|
{
|
||||||
char _raw_buf[UDPMSGSIZE];
|
char _raw_buf[UDPMSGSIZE];
|
||||||
SVCXPRT server;
|
SVCXPRT server;
|
||||||
XDR xdr_stream;
|
XDR xdr_stream;
|
||||||
char verf_body[MAX_AUTH_BYTES];
|
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 bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *);
|
||||||
static enum xprt_stat svcraw_stat (SVCXPRT *);
|
static enum xprt_stat svcraw_stat (SVCXPRT *);
|
||||||
@ -75,11 +79,11 @@ static struct xp_ops server_ops =
|
|||||||
SVCXPRT *
|
SVCXPRT *
|
||||||
svcraw_create (void)
|
svcraw_create (void)
|
||||||
{
|
{
|
||||||
struct svcraw_private *srp = svcraw_private;
|
struct svcraw_private_s *srp = svcraw_private;
|
||||||
|
|
||||||
if (srp == 0)
|
if (srp == 0)
|
||||||
{
|
{
|
||||||
srp = (struct svcraw_private *) calloc (1, sizeof (*srp));
|
srp = (struct svcraw_private_s *) calloc (1, sizeof (*srp));
|
||||||
if (srp == 0)
|
if (srp == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -102,7 +106,7 @@ svcraw_recv (xprt, msg)
|
|||||||
SVCXPRT *xprt;
|
SVCXPRT *xprt;
|
||||||
struct rpc_msg *msg;
|
struct rpc_msg *msg;
|
||||||
{
|
{
|
||||||
struct svcraw_private *srp = svcraw_private;
|
struct svcraw_private_s *srp = svcraw_private;
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
|
|
||||||
if (srp == 0)
|
if (srp == 0)
|
||||||
@ -118,7 +122,7 @@ svcraw_recv (xprt, msg)
|
|||||||
static bool_t
|
static bool_t
|
||||||
svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
|
svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
|
||||||
{
|
{
|
||||||
struct svcraw_private *srp = svcraw_private;
|
struct svcraw_private_s *srp = svcraw_private;
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
|
|
||||||
if (srp == 0)
|
if (srp == 0)
|
||||||
@ -135,7 +139,7 @@ svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
|
|||||||
static bool_t
|
static bool_t
|
||||||
svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
|
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)
|
if (srp == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -145,7 +149,7 @@ svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
|
|||||||
static bool_t
|
static bool_t
|
||||||
svcraw_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
|
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;
|
XDR *xdrs;
|
||||||
|
|
||||||
if (srp == 0)
|
if (srp == 0)
|
||||||
|
@ -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)
|
# define fputs(s, f) _IO_fputs (s, f)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct proglst
|
struct proglst_
|
||||||
{
|
{
|
||||||
char *(*p_progname) (char *);
|
char *(*p_progname) (char *);
|
||||||
int p_prognum;
|
int p_prognum;
|
||||||
int p_procnum;
|
int p_procnum;
|
||||||
xdrproc_t p_inproc, p_outproc;
|
xdrproc_t p_inproc, p_outproc;
|
||||||
struct proglst *p_nxt;
|
struct proglst_ *p_nxt;
|
||||||
}
|
};
|
||||||
*proglst;
|
#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;
|
static SVCXPRT *transp;
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
registerrpc (u_long prognum, u_long versnum, u_long procnum,
|
registerrpc (u_long prognum, u_long versnum, u_long procnum,
|
||||||
char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
|
char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
|
||||||
{
|
{
|
||||||
struct proglst *pl;
|
struct proglst_ *pl;
|
||||||
|
|
||||||
if (procnum == NULLPROC)
|
if (procnum == NULLPROC)
|
||||||
{
|
{
|
||||||
@ -93,7 +102,7 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum,
|
|||||||
prognum, versnum);
|
prognum, versnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pl = (struct proglst *) malloc (sizeof (struct proglst));
|
pl = (struct proglst_ *) malloc (sizeof (struct proglst_));
|
||||||
if (pl == NULL)
|
if (pl == NULL)
|
||||||
{
|
{
|
||||||
(void) fprintf (stderr, _("registerrpc: out of memory\n"));
|
(void) fprintf (stderr, _("registerrpc: out of memory\n"));
|
||||||
@ -110,19 +119,19 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
universal (struct svc_req *rqstp, SVCXPRT *transp)
|
universal (struct svc_req *rqstp, SVCXPRT *transp_l)
|
||||||
{
|
{
|
||||||
int prog, proc;
|
int prog, proc;
|
||||||
char *outdata;
|
char *outdata;
|
||||||
char xdrbuf[UDPMSGSIZE];
|
char xdrbuf[UDPMSGSIZE];
|
||||||
struct proglst *pl;
|
struct proglst_ *pl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enforce "procnum 0 is echo" convention
|
* enforce "procnum 0 is echo" convention
|
||||||
*/
|
*/
|
||||||
if (rqstp->rq_proc == NULLPROC)
|
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");
|
(void) fprintf (stderr, "xxx\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
@ -136,16 +145,16 @@ universal (struct svc_req *rqstp, SVCXPRT *transp)
|
|||||||
{
|
{
|
||||||
/* decode arguments into a CLEAN buffer */
|
/* decode arguments into a CLEAN buffer */
|
||||||
__bzero (xdrbuf, sizeof (xdrbuf)); /* required ! */
|
__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;
|
return;
|
||||||
}
|
}
|
||||||
outdata = (*(pl->p_progname)) (xdrbuf);
|
outdata = (*(pl->p_progname)) (xdrbuf);
|
||||||
if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
|
if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
|
||||||
/* there was an error */
|
/* there was an error */
|
||||||
return;
|
return;
|
||||||
if (!svc_sendreply (transp, pl->p_outproc, outdata))
|
if (!svc_sendreply (transp_l, pl->p_outproc, outdata))
|
||||||
{
|
{
|
||||||
(void) fprintf (stderr,
|
(void) fprintf (stderr,
|
||||||
_ ("trouble replying to prog %d\n"),
|
_ ("trouble replying to prog %d\n"),
|
||||||
@ -153,7 +162,7 @@ universal (struct svc_req *rqstp, SVCXPRT *transp)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
/* free the decoded arguments */
|
/* free the decoded arguments */
|
||||||
(void) svc_freeargs (transp, pl->p_inproc, xdrbuf);
|
(void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void) fprintf (stderr, _ ("never registered prog %d\n"), prog);
|
(void) fprintf (stderr, _ ("never registered prog %d\n"), prog);
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <rpc/types.h>
|
#include <rpc/rpc.h>
|
||||||
#include <rpc/xdr.h>
|
#include <rpc/xdr.h>
|
||||||
#include <rpc/auth.h>
|
#include <rpc/auth.h>
|
||||||
#include <rpc/auth_des.h>
|
#include <rpc/auth_des.h>
|
||||||
@ -71,8 +71,13 @@ struct cache_entry
|
|||||||
struct rpc_timeval laststamp; /* detect replays of creds */
|
struct rpc_timeval laststamp; /* detect replays of creds */
|
||||||
char *localcred; /* generic local credential */
|
char *localcred; /* generic local credential */
|
||||||
};
|
};
|
||||||
static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ;
|
#ifdef _RPC_THREAD_SAFE_
|
||||||
static int *authdes_lru /* [AUTHDES_CACHESZ] */ ;
|
#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 void cache_init (void) internal_function; /* initialize the cache */
|
||||||
static short cache_spot (des_block *, char *, struct rpc_timeval *)
|
static short cache_spot (des_block *, char *, struct rpc_timeval *)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* libc-internal interface for thread-specific data. Stub version.
|
/* libc-internal interface for thread-specific data. Stub version.
|
||||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -35,6 +35,7 @@
|
|||||||
and contains (at least):
|
and contains (at least):
|
||||||
_LIBC_TSD_KEY_MALLOC
|
_LIBC_TSD_KEY_MALLOC
|
||||||
_LIBC_TSD_KEY_DL_ERROR
|
_LIBC_TSD_KEY_DL_ERROR
|
||||||
|
_LIBC_TSD_KEY_RPC_VARS
|
||||||
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
|
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
|
||||||
Some implementations may not provide any enum at all and instead
|
Some implementations may not provide any enum at all and instead
|
||||||
using string pasting in the macros. */
|
using string pasting in the macros. */
|
||||||
|
Loading…
Reference in New Issue
Block a user