Home | History | Annotate | Download | only in X11
      1 /* $Xorg: Xos_r.h,v 1.4 2001/02/09 02:03:22 xorgcvs Exp $ */
      2 /* $XdotOrg: proto/X11/Xos_r.h,v 1.5 2005/07/13 07:23:56 keithp Exp $ */
      3 /*
      4 Copyright 1996, 1998  The Open Group
      5 
      6 Permission to use, copy, modify, distribute, and sell this software and its
      7 documentation for any purpose is hereby granted without fee, provided that
      8 the above copyright notice appear in all copies and that both that
      9 copyright notice and this permission notice appear in supporting
     10 documentation.
     11 
     12 The above copyright notice and this permission notice shall be included in
     13 all copies or substantial portions of the Software.
     14 
     15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall not be
     23 used in advertising or otherwise to promote the sale, use or other dealings
     24 in this Software without prior written authorization from The Open Group.
     25 */
     26 /* $XFree86: xc/include/Xos_r.h,v 1.18tsi Exp $ */
     27 
     28 /*
     29  * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
     30  *
     31  * Use this file in MT-safe code where you would have included
     32  *	<dirent.h>	for readdir()
     33  *	<grp.h>		for getgrgid() or getgrnam()
     34  *	<netdb.h>	for gethostbyname(), gethostbyaddr(), or getservbyname()
     35  *	<pwd.h>		for getpwnam() or getpwuid()
     36  *	<string.h>	for strtok()
     37  *	<time.h>	for asctime(), ctime(), localtime(), or gmtime()
     38  *	<unistd.h>	for getlogin() or ttyname()
     39  * or their thread-safe analogs.
     40  *
     41  * If you are on a platform that defines XTHREADS but does not have
     42  * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
     43  * and _Xos_processUnlock macros before including this header.  If
     44  * you are on OSF/1 V3.2 and plan to use readdir(), you must also define
     45  * _Xos_isThreadInitialized.  For convenience XOS_USE_XLIB_LOCKING or
     46  * XOS_USE_XT_LOCKING may be defined to obtain either Xlib-only or
     47  * Xt-based versions of these macros.  These macros won't result in
     48  * truly thread-safe calls, but they are better than nothing.  If you
     49  * do not want locking in this situation define XOS_USE_NO_LOCKING.
     50  *
     51  * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
     52  *	Gethostbyaddr(), and Getservbyname() do NOT copy the host or
     53  *	protocol lists!
     54  *
     55  * NOTE: On systems lacking appropriate _r functions Getgrgid() and
     56  *	Getgrnam() do NOT copy the list of group members!
     57  *
     58  * This header is nominally intended to simplify porting X11, Motif, and
     59  * CDE; it may be useful to other people too.  The structure below is
     60  * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
     61  * went through lots of drafts, and some vendors shipped systems based
     62  * on draft API that were changed later.  Unfortunately POSIX did not
     63  * provide a feature-test macro for distinguishing each of the drafts.
     64  */
     65 
     66 /*
     67  * This header has several parts.  Search for "Effective prototypes"
     68  * to locate the beginning of a section.
     69  */
     70 
     71 /* This header can be included multiple times with different defines! */
     72 #ifndef _XOS_R_H_
     73 # define _XOS_R_H_
     74 
     75 # include <X11/Xos.h>
     76 # include <X11/Xfuncs.h>
     77 
     78 # ifndef X_NOT_POSIX
     79 #  ifdef _POSIX_SOURCE
     80 #   include <limits.h>
     81 #  else
     82 #   define _POSIX_SOURCE
     83 #   include <limits.h>
     84 #   undef _POSIX_SOURCE
     85 #  endif
     86 #  ifndef LINE_MAX
     87 #   define X_LINE_MAX 2048
     88 #  else
     89 #   define X_LINE_MAX LINE_MAX
     90 #  endif
     91 # endif
     92 #endif /* _XOS_R_H */
     93 
     94 #ifndef WIN32
     95 
     96 #ifdef __cplusplus
     97 extern "C" {
     98 #endif
     99 
    100 # if defined(XOS_USE_XLIB_LOCKING)
    101 #  ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
    102 typedef struct _LockInfoRec *LockInfoPtr;
    103 extern LockInfoPtr _Xglobal_lock;
    104 #  endif
    105 #  ifndef _Xos_isThreadInitialized
    106 #   define _Xos_isThreadInitialized	(_Xglobal_lock)
    107 #  endif
    108 #  if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
    109 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
    110 #    include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
    111 extern void (*_XLockMutex_fn)(
    112 #    if NeedFunctionPrototypes
    113     LockInfoPtr	/* lock */, char * /* file */, int /* line */
    114 #    endif
    115 );
    116 extern void (*_XUnlockMutex_fn)(
    117 #    if NeedFunctionPrototypes
    118     LockInfoPtr	/* lock */, char * /* file */, int /* line */
    119 #    endif
    120 );
    121 #   endif
    122 #   ifndef _Xos_processLock
    123 #    define _Xos_processLock	\
    124   (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
    125 #   endif
    126 #   ifndef _Xos_processUnlock
    127 #    define _Xos_processUnlock	\
    128   (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
    129 #   endif
    130 #  else
    131 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
    132 #    include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
    133 extern void (*_XLockMutex_fn)(
    134 #    if NeedFunctionPrototypes
    135     LockInfoPtr	/* lock */
    136 #    endif
    137 );
    138 extern void (*_XUnlockMutex_fn)(
    139 #    if NeedFunctionPrototypes
    140     LockInfoPtr	/* lock */
    141 #    endif
    142 );
    143 #   endif
    144 #   ifndef _Xos_processLock
    145 #    define _Xos_processLock	\
    146   (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
    147 #   endif
    148 #   ifndef _Xos_processUnlock
    149 #    define _Xos_processUnlock	\
    150   (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
    151 #   endif
    152 #  endif
    153 # elif defined(XOS_USE_XT_LOCKING)
    154 #  ifndef _XtThreadsI_h
    155 extern void (*_XtProcessLock)(void);
    156 #  endif
    157 #  ifndef _XtintrinsicP_h
    158 #   include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
    159 extern void XtProcessLock(
    160 #   if NeedFunctionPrototypes
    161     void
    162 #   endif
    163 );
    164 extern void XtProcessUnlock(
    165 #   if NeedFunctionPrototypes
    166     void
    167 #   endif
    168 );
    169 #  endif
    170 #  ifndef _Xos_isThreadInitialized
    171 #   define _Xos_isThreadInitialized	_XtProcessLock
    172 #  endif
    173 #  ifndef _Xos_processLock
    174 #   define _Xos_processLock		XtProcessLock()
    175 #  endif
    176 #  ifndef _Xos_processUnlock
    177 #   define _Xos_processUnlock		XtProcessUnlock()
    178 #  endif
    179 # elif defined(XOS_USE_NO_LOCKING)
    180 #  ifndef _Xos_isThreadInitialized
    181 #   define _Xos_isThreadInitialized	0
    182 #  endif
    183 #  ifndef _Xos_processLock
    184 #   define _Xos_processLock		0
    185 #  endif
    186 #  ifndef _Xos_processUnlock
    187 #   define _Xos_processUnlock		0
    188 #  endif
    189 # endif
    190 
    191 #endif /* !defined WIN32 */
    192 
    193 /*
    194  * Solaris defines the POSIX thread-safe feature test macro, but
    195  * uses the older SVR4 thread-safe functions unless the POSIX ones
    196  * are specifically requested.  Fix the feature test macro.
    197  */
    198 #if defined(sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
    199 	(_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS)
    200 # undef _POSIX_THREAD_SAFE_FUNCTIONS
    201 #endif
    202 
    203 /*
    204  * LynxOS 3.1 defines _POSIX_THREAD_SAFE_FUNCTIONS but
    205  * getpwuid_r has different semantics than defined by POSIX
    206  */
    207 #if defined(Lynx) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
    208 # undef _POSIX_THREAD_SAFE_FUNCTIONS
    209 #endif
    210 
    211 
    212 /***** <pwd.h> wrappers *****/
    213 
    214 /*
    215  * Effective prototypes for <pwd.h> wrappers:
    216  *
    217  * #define X_INCLUDE_PWD_H
    218  * #define XOS_USE_..._LOCKING
    219  * #include <X11/Xos_r.h>
    220  *
    221  * typedef ... _Xgetpwparams;
    222  *
    223  * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
    224  * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
    225  */
    226 
    227 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
    228 # include <pwd.h>
    229 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
    230 #  define XOS_USE_MTSAFE_PWDAPI 1
    231 # endif
    232 #endif
    233 
    234 #undef X_NEEDS_PWPARAMS
    235 #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
    236 /* Do nothing */
    237 
    238 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    239 /* Use regular, unsafe API. */
    240 # if defined(X_NOT_POSIX) && !defined(i386) && !defined(SYSV)
    241 extern struct passwd *getpwuid(), *getpwnam();
    242 # endif
    243 typedef int _Xgetpwparams;	/* dummy */
    244 # define _XGetpwuid(u,p)	getpwuid((u))
    245 # define _XGetpwnam(u,p)	getpwnam((u))
    246 
    247 #elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
    248 /* UnixWare 2.0, or other systems with thread support but no _r API. */
    249 # define X_NEEDS_PWPARAMS
    250 typedef struct {
    251   struct passwd pws;
    252   char   pwbuf[1024];
    253   struct passwd* pwp;
    254   size_t len;
    255 } _Xgetpwparams;
    256 
    257 /*
    258  * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
    259  * fields.
    260  */
    261 
    262 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
    263     defined(__APPLE__) || defined(__DragonFly__)
    264 static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p)
    265 {
    266    memcpy(&(p).pws, (p).pwp, sizeof(struct passwd));
    267 
    268    (p).pws.pw_name = (p).pwbuf;
    269    (p).len = strlen((p).pwp->pw_name);
    270    strcpy((p).pws.pw_name, (p).pwp->pw_name);
    271 
    272    (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1;
    273    (p).len = strlen((p).pwp->pw_passwd);
    274    strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd);
    275 
    276    (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1;
    277    (p).len = strlen((p).pwp->pw_class);
    278    strcpy((p).pws.pw_class, (p).pwp->pw_class);
    279 
    280    (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1;
    281    (p).len = strlen((p).pwp->pw_gecos);
    282    strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos);
    283 
    284    (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1;
    285    (p).len = strlen((p).pwp->pw_dir);
    286    strcpy((p).pws.pw_dir, (p).pwp->pw_dir);
    287 
    288    (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1;
    289    (p).len = strlen((p).pwp->pw_shell);
    290    strcpy((p).pws.pw_shell, (p).pwp->pw_shell);
    291 
    292    (p).pwp = &(p).pws;
    293 }
    294 
    295 #else
    296 # define _Xpw_copyPasswd(p) \
    297    (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \
    298     ((p).pws.pw_name = (p).pwbuf), \
    299     ((p).len = strlen((p).pwp->pw_name)), \
    300     strcpy((p).pws.pw_name, (p).pwp->pw_name), \
    301     ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
    302     ((p).len = strlen((p).pwp->pw_passwd)), \
    303     strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
    304     ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
    305     ((p).len = strlen((p).pwp->pw_age)), \
    306     strcpy((p).pws.pw_age, (p).pwp->pw_age), \
    307     ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
    308     ((p).len = strlen((p).pwp->pw_comment)), \
    309     strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
    310     ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
    311     ((p).len = strlen((p).pwp->pw_gecos)), \
    312     strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
    313     ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
    314     ((p).len = strlen((p).pwp->pw_dir)), \
    315     strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
    316     ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
    317     ((p).len = strlen((p).pwp->pw_shell)), \
    318     strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
    319     ((p).pwp = &(p).pws), \
    320     0 )
    321 #endif
    322 # define _XGetpwuid(u,p) \
    323 ( (_Xos_processLock), \
    324   (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
    325   (_Xos_processUnlock), \
    326   (p).pwp )
    327 # define _XGetpwnam(u,p) \
    328 ( (_Xos_processLock), \
    329   (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
    330   (_Xos_processUnlock), \
    331   (p).pwp )
    332 
    333 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__)
    334 /* SVR4 threads, AIX 4.2.0 and earlier and OSF/1 3.2 and earlier pthreads */
    335 # define X_NEEDS_PWPARAMS
    336 typedef struct {
    337   struct passwd pws;
    338   char pwbuf[X_LINE_MAX];
    339 } _Xgetpwparams;
    340 # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4) || defined(Lynx)
    341 #  ifndef Lynx
    342 #   define _XGetpwuid(u,p) \
    343 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
    344 #   define _XGetpwnam(u,p) \
    345 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
    346 #  else /* Lynx */
    347 #   define _XGetpwuid(u,p) \
    348 ((getpwuid_r(&(p).pws,(u),(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
    349 #   define _XGetpwnam(u,p) \
    350 ((getpwnam_r(&(p).pws,(u),(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
    351 #  endif
    352 # else /* SVR4 */
    353 #  define _XGetpwuid(u,p) \
    354 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
    355 #  define _XGetpwnam(u,p) \
    356 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
    357 # endif /* SVR4 */
    358 
    359 #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
    360 /* Digital UNIX 4.0, but not (beta) T4.0-1 */
    361 # if defined(__osf__)
    362 /* OSF/1 V4.0 <pwd.h> doesn't declare the _P routines, breaking under C++. */
    363 extern int _Pgetpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
    364 extern int _Pgetpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **);
    365 # endif
    366 # define X_NEEDS_PWPARAMS
    367 typedef struct {
    368   struct passwd pws;
    369   char pwbuf[X_LINE_MAX];
    370   struct passwd* pwp;
    371 } _Xgetpwparams;
    372 typedef int _Xgetpwret;
    373 # define _XGetpwuid(u,p) \
    374 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
    375  (p).pwp : NULL)
    376 # define _XGetpwnam(u,p) \
    377 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
    378  (p).pwp : NULL)
    379 #endif /* X_INCLUDE_PWD_H */
    380 
    381 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
    382 # define _XOS_INCLUDED_PWD_H
    383 #endif
    384 
    385 
    386 /***** <netdb.h> wrappers *****/
    387 
    388 /*
    389  * Effective prototypes for <netdb.h> wrappers:
    390  *
    391  * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
    392  *	Gethostbyaddr(), and Getservbyname() do NOT copy the host or
    393  *	protocol lists!
    394  *
    395  * #define X_INCLUDE_NETDB_H
    396  * #define XOS_USE_..._LOCKING
    397  * #include <X11/Xos_r.h>
    398  *
    399  * typedef ... _Xgethostbynameparams;
    400  * typedef ... _Xgetservbynameparams;
    401  *
    402  * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
    403  * struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
    404  *				   _Xgethostbynameparams);
    405  * struct servent* _XGetservbyname(const char* name, const char* proto,
    406  *				 _Xgetservbynameparams);
    407  */
    408 
    409 #undef XTHREADS_NEEDS_BYNAMEPARAMS
    410 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
    411     && !defined(WIN32)
    412 # include <netdb.h>
    413 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
    414 #  define XOS_USE_MTSAFE_NETDBAPI 1
    415 # endif
    416 #endif
    417 
    418 #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
    419 /* Do nothing. */
    420 
    421 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    422 /* Use regular, unsafe API. */
    423 typedef int _Xgethostbynameparams; /* dummy */
    424 typedef int _Xgetservbynameparams; /* dummy */
    425 # define _XGethostbyname(h,hp)		gethostbyname((h))
    426 # define _XGethostbyaddr(a,al,t,hp)	gethostbyaddr((a),(al),(t))
    427 # define _XGetservbyname(s,p,sp)	getservbyname((s),(p))
    428 
    429 #elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
    430 /* UnixWare 2.0, or other systems with thread support but no _r API. */
    431 /* WARNING:  The h_addr_list and s_aliases values are *not* copied! */
    432 
    433 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
    434 #include <sys/param.h>
    435 #endif
    436 
    437 typedef struct {
    438   struct hostent hent;
    439   char           h_name[MAXHOSTNAMELEN];
    440   struct hostent *hptr;
    441 } _Xgethostbynameparams;
    442 typedef struct {
    443   struct servent sent;
    444   char           s_name[255];
    445   char		 s_proto[255];
    446   struct servent *sptr;
    447 } _Xgetservbynameparams;
    448 
    449 # define XTHREADS_NEEDS_BYNAMEPARAMS
    450 
    451 # define _Xg_copyHostent(hp) \
    452    (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
    453     strcpy((hp).h_name, (hp).hptr->h_name), \
    454     ((hp).hent.h_name = (hp).h_name), \
    455     ((hp).hptr = &(hp).hent), \
    456      0 )
    457 # define _Xg_copyServent(sp) \
    458    (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
    459     strcpy((sp).s_name, (sp).sptr->s_name), \
    460     ((sp).sent.s_name = (sp).s_name), \
    461     strcpy((sp).s_proto, (sp).sptr->s_proto), \
    462     ((sp).sent.s_proto = (sp).s_proto), \
    463     ((sp).sptr = &(sp).sent), \
    464     0 )
    465 # define _XGethostbyname(h,hp) \
    466    ((_Xos_processLock), \
    467     (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
    468     (_Xos_processUnlock), \
    469     (hp).hptr )
    470 # define _XGethostbyaddr(a,al,t,hp) \
    471    ((_Xos_processLock), \
    472     (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
    473     (_Xos_processUnlock), \
    474     (hp).hptr )
    475 # define _XGetservbyname(s,p,sp) \
    476    ((_Xos_processLock), \
    477     (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
    478     (_Xos_processUnlock), \
    479     (sp).sptr )
    480 
    481 #elif defined(XUSE_NETDB_R_API)
    482 /*
    483  * POSIX does not specify _r equivalents for <netdb.h> API, but some
    484  * vendors provide them anyway.  Use them only when explicitly asked.
    485  */
    486 # ifdef _POSIX_REENTRANT_FUNCTIONS
    487 #  ifndef _POSIX_THREAD_SAFE_FUNCTIONS
    488 #   if defined(AIXV3) || defined(AIXV4) || defined(__osf__)
    489 #    define X_POSIX_THREAD_SAFE_FUNCTIONS 1
    490 #   endif
    491 #  endif
    492 # endif
    493 # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
    494 #  define X_POSIX_THREAD_SAFE_FUNCTIONS 1
    495 # endif
    496 
    497 # define XTHREADS_NEEDS_BYNAMEPARAMS
    498 
    499 # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
    500 typedef struct {
    501     struct hostent      hent;
    502     char                hbuf[X_LINE_MAX];
    503     int                 herr;
    504 } _Xgethostbynameparams;
    505 typedef struct {
    506     struct servent      sent;
    507     char                sbuf[X_LINE_MAX];
    508 } _Xgetservbynameparams;
    509 #  define _XGethostbyname(h,hp) \
    510   gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
    511 #  define _XGethostbyaddr(a,al,t,hp) \
    512   gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
    513 #  define _XGetservbyname(s,p,sp) \
    514   getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
    515 # else
    516 typedef struct {
    517   struct hostent      hent;
    518   struct hostent_data hdata;
    519 } _Xgethostbynameparams;
    520 typedef struct {
    521   struct servent      sent;
    522   struct servent_data sdata;
    523 } _Xgetservbynameparams;
    524 #  define _XGethostbyname(h,hp) \
    525   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),	\
    526    ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
    527 #  define _XGethostbyaddr(a,al,t,hp) \
    528   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),	\
    529    ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
    530 #  define _XGetservbyname(s,p,sp) \
    531   (bzero((char*)&(sp).sdata,sizeof((sp).sdata)),	\
    532    ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
    533 # endif
    534 # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
    535 #  undef X_POSIX_THREAD_SAFE_FUNCTIONS
    536 # endif
    537 
    538 #else
    539 /* The regular API is assumed to be MT-safe under POSIX. */
    540 typedef int _Xgethostbynameparams; /* dummy */
    541 typedef int _Xgetservbynameparams; /* dummy */
    542 # define _XGethostbyname(h,hp)		gethostbyname((h))
    543 # define _XGethostbyaddr(a,al,t,hp)	gethostbyaddr((a),(al),(t))
    544 # define _XGetservbyname(s,p,sp)	getservbyname((s),(p))
    545 #endif /* X_INCLUDE_NETDB_H */
    546 
    547 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
    548 # define _XOS_INCLUDED_NETDB_H
    549 #endif
    550 
    551 
    552 /***** <dirent.h> wrappers *****/
    553 
    554 /*
    555  * Effective prototypes for <dirent.h> wrappers:
    556  *
    557  * #define X_INCLUDE_DIRENT_H
    558  * #define XOS_USE_..._LOCKING
    559  * #include <X11/Xos_r.h>
    560  *
    561  * typedef ... _Xreaddirparams;
    562  *
    563  * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
    564  */
    565 
    566 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
    567 # include <sys/types.h>
    568 # if !defined(X_NOT_POSIX) || defined(SYSV) || defined(USG)
    569 #  include <dirent.h>
    570 # else
    571 #  include <sys/dir.h>
    572 #  ifndef dirent
    573 #   define dirent direct
    574 #  endif
    575 # endif
    576 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
    577 #  define XOS_USE_MTSAFE_DIRENTAPI 1
    578 # endif
    579 #endif
    580 
    581 #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
    582 /* Do nothing. */
    583 
    584 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    585 /* Use regular, unsafe API. */
    586 typedef int _Xreaddirparams;	/* dummy */
    587 # define _XReaddir(d,p)	readdir(d)
    588 
    589 #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
    590 /* Systems with thread support but no _r API. */
    591 typedef struct {
    592   struct dirent *result;
    593   struct dirent dir_entry;
    594 # ifdef _POSIX_PATH_MAX
    595   char buf[_POSIX_PATH_MAX];
    596 # elif defined(NAME_MAX)
    597   char buf[NAME_MAX];
    598 # else
    599   char buf[255];
    600 # endif
    601 } _Xreaddirparams;
    602 
    603 # define _XReaddir(d,p)	\
    604  ( (_Xos_processLock),						 \
    605    (((p).result = readdir((d))) ?				 \
    606     (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
    607      ((p).result = &(p).dir_entry), 0) :			 \
    608     0),								 \
    609    (_Xos_processUnlock),					 \
    610    (p).result )
    611 
    612 #else
    613 typedef struct {
    614   struct dirent *result;
    615   struct dirent dir_entry;
    616 # ifdef _POSIX_PATH_MAX
    617   char buf[_POSIX_PATH_MAX];
    618 # elif defined(NAME_MAX)
    619   char buf[NAME_MAX];
    620 # else
    621   char buf[255];
    622 # endif
    623 } _Xreaddirparams;
    624 
    625 # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(AIXV3) || \
    626      defined(AIXV4) || defined(__APPLE__)
    627 /* AIX defines the draft POSIX symbol, but uses the final API. */
    628 /* POSIX final API, returns (int)0 on success. */
    629 #  if defined(__osf__)
    630 /* OSF/1 V4.0 <dirent.h> doesn't declare _Preaddir_r, breaking under C++. */
    631 extern int _Preaddir_r(DIR *, struct dirent *, struct dirent **);
    632 #  endif
    633 #  define _XReaddir(d,p)						\
    634     (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
    635 # elif defined(_POSIX_REENTRANT_FUNCTIONS) && defined(__osf__)
    636 /*
    637  * OSF/1 V3.2 readdir_r() will SEGV if the main program is not
    638  * explicitly linked with -lc_r.  The library REQUIREDLIBS don't help.
    639  * Assume that if threads have been initialized we're linked properly.
    640  */
    641 #  define _XReaddir(d,p)						\
    642  ( (_Xos_isThreadInitialized) ?						\
    643    (readdir_r((d), &((p).dir_entry)) ? NULL : &((p).dir_entry)) :	\
    644    ((_Xos_processLock),							\
    645     (((p).result = readdir((d))) ?					\
    646      (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen),	\
    647       ((p).result = &(p).dir_entry), 0) :				\
    648      0),								\
    649     (_Xos_processUnlock),						\
    650     (p).result) )
    651 # elif defined(_POSIX_REENTRANT_FUNCTIONS)
    652 /* POSIX draft API, returns (int)0 on success. */
    653 #  define _XReaddir(d,p)	\
    654     (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
    655 # elif defined(SVR4)
    656 /* Pre-POSIX API, returns non-NULL on success. */
    657 #  define _XReaddir(d,p)	(readdir_r((d), &(p).dir_entry))
    658 # else
    659 /* We have no idea what is going on.  Fake it all using process locks. */
    660 #  define _XReaddir(d,p)	\
    661     ( (_Xos_processLock),						\
    662       (((p).result = readdir((d))) ?					\
    663        (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen),	\
    664 	((p).result = &(p).dir_entry), 0) :				\
    665        0),								\
    666       (_Xos_processUnlock),						\
    667       (p).result )
    668 # endif
    669 #endif /* X_INCLUDE_DIRENT_H */
    670 
    671 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
    672 # define _XOS_INCLUDED_DIRENT_H
    673 #endif
    674 
    675 
    676 /***** <unistd.h> wrappers *****/
    677 
    678 /*
    679  * Effective prototypes for <unistd.h> wrappers:
    680  *
    681  * #define X_INCLUDE_UNISTD_H
    682  * #define XOS_USE_..._LOCKING
    683  * #include <X11/Xos_r.h>
    684  *
    685  * typedef ... _Xgetloginparams;
    686  * typedef ... _Xttynameparams;
    687  *
    688  * char *_XGetlogin(_Xgetloginparams);
    689  * char *_XTtyname(int, _Xttynameparams);
    690  */
    691 
    692 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
    693 /* <unistd.h> already included by <X11/Xos.h> */
    694 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
    695 #  define XOS_USE_MTSAFE_UNISTDAPI 1
    696 # endif
    697 #endif
    698 
    699 #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
    700 /* Do nothing. */
    701 
    702 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    703 /* Use regular, unsafe API. */
    704 typedef int _Xgetloginparams;	/* dummy */
    705 typedef int _Xttynameparams;	/* dummy */
    706 # define _XGetlogin(p)	getlogin()
    707 # define _XTtyname(f)	ttyname((f))
    708 
    709 #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
    710 /* Systems with thread support but no _r API. */
    711 typedef struct {
    712   char *result;
    713 # if defined(MAXLOGNAME)
    714   char buf[MAXLOGNAME];
    715 # elif defined(LOGIN_NAME_MAX)
    716   char buf[LOGIN_NAME_MAX];
    717 # else
    718   char buf[64];
    719 # endif
    720 } _Xgetloginparams;
    721 typedef struct {
    722   char *result;
    723 # ifdef TTY_NAME_MAX
    724   char buf[TTY_NAME_MAX];
    725 # elif defined(_POSIX_TTY_NAME_MAX)
    726   char buf[_POSIX_TTY_NAME_MAX];
    727 # elif defined(_POSIX_PATH_MAX)
    728   char buf[_POSIX_PATH_MAX];
    729 # else
    730   char buf[256];
    731 # endif
    732 } _Xttynameparams;
    733 
    734 # define _XGetlogin(p) \
    735  ( (_Xos_processLock), \
    736    (((p).result = getlogin()) ? \
    737     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
    738      ((p).buf[sizeof((p).buf)-1] = '\0'), \
    739      ((p).result = (p).buf), 0) : 0), \
    740    (_Xos_processUnlock), \
    741    (p).result )
    742 #define _XTtyname(f,p) \
    743  ( (_Xos_processLock), \
    744    (((p).result = ttyname(f)) ? \
    745     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
    746      ((p).buf[sizeof((p).buf)-1] = '\0'), \
    747      ((p).result = (p).buf), 0) : 0), \
    748    (_Xos_processUnlock), \
    749    (p).result )
    750 
    751 #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
    752 /* POSIX API.
    753  *
    754  * extern int getlogin_r(char *, size_t);
    755  * extern int ttyname_r(int, char *, size_t);
    756  */
    757 typedef struct {
    758 # if defined(MAXLOGNAME)
    759   char buf[MAXLOGNAME];
    760 # elif defined(LOGIN_NAME_MAX)
    761   char buf[LOGIN_NAME_MAX];
    762 # else
    763   char buf[64];
    764 # endif
    765 } _Xgetloginparams;
    766 typedef struct {
    767 # ifdef TTY_NAME_MAX
    768   char buf[TTY_NAME_MAX];
    769 # elif defined(_POSIX_TTY_NAME_MAX)
    770   char buf[_POSIX_TTY_NAME_MAX];
    771 # elif defined(_POSIX_PATH_MAX)
    772   char buf[_POSIX_PATH_MAX];
    773 # else
    774   char buf[256];
    775 # endif
    776 } _Xttynameparams;
    777 
    778 # define _XGetlogin(p)	(getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
    779 # define _XTtyname(f,p)	\
    780 	(ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
    781 
    782 #else
    783 /* Pre-POSIX API.
    784  *
    785  * extern char *getlogin_r(char *, size_t);
    786  * extern char *ttyname_r(int, char *, size_t);
    787  */
    788 typedef struct {
    789 # if defined(MAXLOGNAME)
    790   char buf[MAXLOGNAME];
    791 # elif defined(LOGIN_NAME_MAX)
    792   char buf[LOGIN_NAME_MAX];
    793 # else
    794   char buf[64];
    795 # endif
    796 } _Xgetloginparams;
    797 typedef struct {
    798 # ifdef TTY_NAME_MAX
    799   char buf[TTY_NAME_MAX];
    800 # elif defined(_POSIX_TTY_NAME_MAX)
    801   char buf[_POSIX_TTY_NAME_MAX];
    802 # elif defined(_POSIX_PATH_MAX)
    803   char buf[_POSIX_PATH_MAX];
    804 # else
    805   char buf[256];
    806 # endif
    807 } _Xttynameparams;
    808 
    809 # define _XGetlogin(p)	getlogin_r((p).buf, sizeof((p).buf))
    810 # define _XTtyname(f,p)	ttyname_r((f), (p).buf, sizeof((p).buf))
    811 #endif /* X_INCLUDE_UNISTD_H */
    812 
    813 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
    814 # define _XOS_INCLUDED_UNISTD_H
    815 #endif
    816 
    817 
    818 /***** <string.h> wrappers *****/
    819 
    820 /*
    821  * Effective prototypes for <string.h> wrappers:
    822  *
    823  * #define X_INCLUDE_STRING_H
    824  * #define XOS_USE_..._LOCKING
    825  * #include <X11/Xos_r.h>
    826  *
    827  * typedef ... _Xstrtokparams;
    828  *
    829  * char *_XStrtok(char *, const char*, _Xstrtokparams);
    830  */
    831 
    832 #if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
    833 /* <string.h> has already been included by <X11/Xos.h> */
    834 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
    835 #  define XOS_USE_MTSAFE_STRINGAPI 1
    836 # endif
    837 #endif
    838 
    839 #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
    840 /* Do nothing. */
    841 
    842 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    843 /* Use regular, unsafe API. */
    844 typedef int _Xstrtokparams;	/* dummy */
    845 # define _XStrtok(s1,s2,p) \
    846  ( p = 0, (void)p, strtok((s1),(s2)) )
    847 
    848 #elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
    849 /* Systems with thread support but no _r API. */
    850 typedef char *_Xstrtokparams;
    851 # define _XStrtok(s1,s2,p) \
    852  ( (_Xos_processLock), \
    853    ((p) = strtok((s1),(s2))), \
    854    (_Xos_processUnlock), \
    855    (p) )
    856 
    857 #else
    858 /* POSIX or pre-POSIX API. */
    859 typedef char * _Xstrtokparams;
    860 # define _XStrtok(s1,s2,p)	strtok_r((s1),(s2),&(p))
    861 #endif /* X_INCLUDE_STRING_H */
    862 
    863 
    864 /***** <time.h> wrappers *****/
    865 
    866 /*
    867  * Effective prototypes for <time.h> wrappers:
    868  *
    869  * #define X_INCLUDE_TIME_H
    870  * #define XOS_USE_..._LOCKING
    871  * #include <X11/Xos_r.h>
    872  *
    873  * typedef ... _Xatimeparams;
    874  * typedef ... _Xctimeparams;
    875  * typedef ... _Xgtimeparams;
    876  * typedef ... _Xltimeparams;
    877  *
    878  * char *_XAsctime(const struct tm *, _Xatimeparams);
    879  * char *_XCtime(const time_t *, _Xctimeparams);
    880  * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
    881  * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
    882  */
    883 
    884 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
    885 # include <time.h>
    886 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
    887 #  define XOS_USE_MTSAFE_TIMEAPI 1
    888 # endif
    889 #endif
    890 
    891 #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
    892 /* Do nothing. */
    893 
    894 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
    895 /* Use regular, unsafe API. */
    896 typedef int _Xatimeparams;	/* dummy */
    897 # define _XAsctime(t,p)		asctime((t))
    898 typedef int _Xctimeparams;	/* dummy */
    899 # define _XCtime(t,p)		ctime((t))
    900 typedef int _Xgtimeparams;	/* dummy */
    901 # define _XGmtime(t,p)		gmtime((t))
    902 typedef int _Xltimeparams;	/* dummy */
    903 # define _XLocaltime(t,p)	localtime((t))
    904 
    905 #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
    906 /* Systems with thread support but no _r API. */
    907 typedef struct {
    908 # ifdef TIMELEN
    909   char buf[TIMELEN];
    910 # else
    911   char buf[26];
    912 # endif
    913   char *result;
    914 } _Xctimeparams, _Xatimeparams;
    915 typedef struct {
    916   struct tm buf;
    917   struct tm *result;
    918 } _Xgtimeparams, _Xltimeparams;
    919 # define _XAsctime(t,p) \
    920  ( (_Xos_processLock), \
    921    (((p).result = asctime((t))) ? \
    922     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
    923     0), \
    924    (_Xos_processUnlock), \
    925    (p).result )
    926 # define _XCtime(t,p) \
    927  ( (_Xos_processLock), \
    928    (((p).result = ctime((t))) ? \
    929     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
    930     0), \
    931    (_Xos_processUnlock), \
    932    (p).result )
    933 # define _XGmtime(t,p) \
    934  ( (_Xos_processLock), \
    935    (((p).result = gmtime(t)) ? \
    936     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
    937     0), \
    938    (_Xos_processUnlock), \
    939    (p).result )
    940 # define _XLocaltime(t,p) \
    941  ( (_Xos_processLock), \
    942    (((p).result = localtime(t)) ? \
    943     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
    944     0), \
    945    (_Xos_processUnlock), \
    946    (p).result )
    947 
    948 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(__osf__) || defined(hpV4))
    949 /* Returns (int)0 on success.  OSF/1 v3.2, HP/UX 10
    950  *
    951  * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
    952  * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
    953  * extern int gmtime_r(const time_t *timer, struct tm *result);
    954  * extern int localtime_r(const time_t *timer, struct tm *result);
    955  */
    956 # ifdef TIMELEN
    957 typedef char _Xatimeparams[TIMELEN];
    958 typedef char _Xctimeparams[TIMELEN];
    959 # else
    960 typedef char _Xatimeparams[26];
    961 typedef char _Xctimeparams[26];
    962 # endif
    963 typedef struct tm _Xgtimeparams;
    964 typedef struct tm _Xltimeparams;
    965 # define _XAsctime(t,p)		(asctime_r((t),(p),sizeof((p))) ? NULL : (p))
    966 # define _XCtime(t,p)		(ctime_r((t),(p),sizeof((p))) ? NULL : (p))
    967 # define _XGmtime(t,p)		(gmtime_r((t),&(p)) ? NULL : &(p))
    968 # define _XLocaltime(t,p)	(localtime_r((t),&(p)) ? NULL : &(p))
    969 
    970 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(sun)
    971 /* Returns NULL on failure.  Solaris 2.5
    972  *
    973  * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
    974  * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
    975  * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
    976  * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
    977  */
    978 # ifdef TIMELEN
    979 typedef char _Xatimeparams[TIMELEN];
    980 typedef char _Xctimeparams[TIMELEN];
    981 # else
    982 typedef char _Xatimeparams[26];
    983 typedef char _Xctimeparams[26];
    984 # endif
    985 typedef struct tm _Xgtimeparams;
    986 typedef struct tm _Xltimeparams;
    987 # define _XAsctime(t,p)		asctime_r((t),(p),sizeof((p)))
    988 # define _XCtime(t,p)		ctime_r((t),(p),sizeof((p)))
    989 # define _XGmtime(t,p)		gmtime_r((t),&(p))
    990 # define _XLocaltime(t,p)	localtime_r((t),&(p))
    991 
    992 #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
    993 /* POSIX final API.  OSF/1 v4.0, AIX, etc.
    994  *
    995  * extern char *asctime_r(const struct tm *timeptr, char *buffer);
    996  * extern char *ctime_r(const time_t *timer, char *buffer);
    997  * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
    998  * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
    999  */
   1000 # if defined(__osf__)
   1001 /* OSF/1 V4.0 <time.h> doesn't declare the _P routines, breaking under C++. */
   1002 extern char *_Pasctime_r(const struct tm *, char *);
   1003 extern char *_Pctime_r(const time_t *, char *);
   1004 extern struct tm *_Plocaltime_r(const time_t *, struct tm *);
   1005 # endif
   1006 # ifdef TIMELEN
   1007 typedef char _Xatimeparams[TIMELEN];
   1008 typedef char _Xctimeparams[TIMELEN];
   1009 # else
   1010 typedef char _Xatimeparams[26];
   1011 typedef char _Xctimeparams[26];
   1012 # endif
   1013 typedef struct tm _Xgtimeparams;
   1014 typedef struct tm _Xltimeparams;
   1015 # define _XAsctime(t,p)		asctime_r((t),(p))
   1016 # define _XCtime(t,p)		ctime_r((t),(p))
   1017 # define _XGmtime(t,p)		gmtime_r((t),&(p))
   1018 # define _XLocaltime(t,p)	localtime_r((t),&(p))
   1019 #endif /* X_INCLUDE_TIME_H */
   1020 
   1021 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
   1022 # define _XOS_INCLUDED_TIME_H
   1023 #endif
   1024 
   1025 
   1026 /***** <grp.h> wrappers *****/
   1027 
   1028 /*
   1029  * Effective prototypes for <grp.h> wrappers:
   1030  *
   1031  * NOTE: On systems lacking appropriate _r functions Getgrgid() and
   1032  *	Getgrnam() do NOT copy the list of group members!
   1033  *
   1034  * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
   1035  * are not included in POSIX.
   1036  *
   1037  * #define X_INCLUDE_GRP_H
   1038  * #define XOS_USE_..._LOCKING
   1039  * #include <X11/Xos_r.h>
   1040  *
   1041  * typedef ... _Xgetgrparams;
   1042  *
   1043  * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
   1044  * struct group *_XGetgrnam(const char *, _Xgetgrparams);
   1045  */
   1046 
   1047 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
   1048 # include <grp.h>
   1049 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
   1050 #  define XOS_USE_MTSAFE_GRPAPI 1
   1051 # endif
   1052 #endif
   1053 
   1054 #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
   1055 /* Do nothing. */
   1056 
   1057 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
   1058 /* Use regular, unsafe API. */
   1059 typedef int _Xgetgrparams;	/* dummy */
   1060 #define _XGetgrgid(g,p)	getgrgid((g))
   1061 #define _XGetgrnam(n,p)	getgrnam((n))
   1062 
   1063 #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
   1064 /* Systems with thread support but no _r API.  UnixWare 2.0. */
   1065 typedef struct {
   1066   struct group grp;
   1067   char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
   1068   struct group *pgrp;
   1069   size_t len;
   1070 } _Xgetgrparams;
   1071 #ifdef SVR4
   1072 /* Copy the gr_passwd field too. */
   1073 # define _Xgrp_copyGroup(p) \
   1074  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
   1075    ((p).grp.gr_name = (p).buf), \
   1076    ((p).len = strlen((p).pgrp->gr_name)), \
   1077    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
   1078    ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
   1079    ((p).pgrp = &(p).grp), \
   1080    0 )
   1081 #else
   1082 # define _Xgrp_copyGroup(p) \
   1083  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
   1084    ((p).grp.gr_name = (p).buf), \
   1085    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
   1086    ((p).pgrp = &(p).grp), \
   1087    0 )
   1088 #endif
   1089 #define _XGetgrgid(g,p) \
   1090  ( (_Xos_processLock), \
   1091    (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
   1092    (_Xos_processUnlock), \
   1093    (p).pgrp )
   1094 #define _XGetgrnam(n,p) \
   1095  ( (_Xos_processLock), \
   1096    (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
   1097    (_Xos_processUnlock), \
   1098    (p).pgrp )
   1099 
   1100 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(sun) || defined(__osf__))
   1101 /* Non-POSIX API.  Solaris, DEC v3.2.
   1102  *
   1103  * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
   1104  * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
   1105  */
   1106 typedef struct {
   1107   struct group grp;
   1108   char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
   1109 } _Xgetgrparams;
   1110 #define _XGetgrgid(g,p)	getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
   1111 #define _XGetgrnam(n,p)	getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
   1112 
   1113 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
   1114 /* Non-POSIX API.  HP/UX 10, AIX 4.
   1115  *
   1116  * extern int getgrgid_r(gid_t, struct group *, char *, int);
   1117  * extern int getgrnam_r(const char *, struct group *, char *, int);
   1118  */
   1119 typedef struct {
   1120   struct group grp;
   1121   char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
   1122 } _Xgetgrparams;
   1123 #define _XGetgrgid(g,p)	\
   1124  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
   1125 #define _XGetgrnam(n,p)	\
   1126  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
   1127 
   1128 #else
   1129 /* POSIX final API.  DEC v4.0, IRIX 6.2.
   1130  *
   1131  * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
   1132  * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
   1133  */
   1134 # if defined(__osf__)
   1135 /* OSF/1 V4.0 <grp.h> doesn't declare the _P routines, breaking under C++. */
   1136 extern int _Pgetgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
   1137 extern int _Pgetgrnam_r(const char *, struct group *, char *, size_t, struct group **);
   1138 # endif
   1139 typedef struct {
   1140   struct group grp;
   1141   char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
   1142   struct group *result;
   1143 } _Xgetgrparams;
   1144 
   1145 #define _XGetgrgid(g,p)	\
   1146  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
   1147    NULL : (p).result))
   1148 #define _XGetgrnam(n,p)	\
   1149  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
   1150    NULL : (p).result))
   1151 #endif
   1152 
   1153 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
   1154 # define _XOS_INCLUDED_GRP_H
   1155 #endif
   1156 
   1157 
   1158 #ifdef __cplusplus
   1159 }  /* Close scope of 'extern "C"' declaration which encloses file. */
   1160 #endif
   1161