Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:14:34

0001 /*
0002 Copyright 1996, 1998  The Open Group
0003 
0004 Permission to use, copy, modify, distribute, and sell this software and its
0005 documentation for any purpose is hereby granted without fee, provided that
0006 the above copyright notice appear in all copies and that both that
0007 copyright notice and this permission notice appear in supporting
0008 documentation.
0009 
0010 The above copyright notice and this permission notice shall be included in
0011 all copies or substantial portions of the Software.
0012 
0013 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0014 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0015 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
0016 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
0017 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0018 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0019 
0020 Except as contained in this notice, the name of The Open Group shall not be
0021 used in advertising or otherwise to promote the sale, use or other dealings
0022 in this Software without prior written authorization from The Open Group.
0023 */
0024 
0025 /*
0026  * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
0027  *
0028  * Use this file in MT-safe code where you would have included
0029  *  <dirent.h>  for readdir()
0030  *  <grp.h>     for getgrgid() or getgrnam()
0031  *  <netdb.h>   for gethostbyname(), gethostbyaddr(), or getservbyname()
0032  *  <pwd.h>     for getpwnam() or getpwuid()
0033  *  <string.h>  for strtok()
0034  *  <time.h>    for asctime(), ctime(), localtime(), or gmtime()
0035  *  <unistd.h>  for getlogin() or ttyname()
0036  * or their thread-safe analogs.
0037  *
0038  * If you are on a platform that defines XTHREADS but does not have
0039  * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
0040  * and _Xos_processUnlock macros before including this header.
0041  *
0042  * For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined
0043  * to obtain either Xlib-only or Xt-based versions of these macros.  These
0044  * macros won't result in truly thread-safe calls, but they are better than
0045  * nothing.  If you do not want locking in this situation define
0046  * XOS_USE_NO_LOCKING.
0047  *
0048  * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
0049  *  Gethostbyaddr(), and Getservbyname() do NOT copy the host or
0050  *  protocol lists!
0051  *
0052  * NOTE: On systems lacking appropriate _r functions Getgrgid() and
0053  *  Getgrnam() do NOT copy the list of group members!
0054  *
0055  * This header is nominally intended to simplify porting X11, Motif, and
0056  * CDE; it may be useful to other people too.  The structure below is
0057  * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
0058  * went through lots of drafts, and some vendors shipped systems based
0059  * on draft API that were changed later.  Unfortunately POSIX did not
0060  * provide a feature-test macro for distinguishing each of the drafts.
0061  */
0062 
0063 /*
0064  * This header has several parts.  Search for "Effective prototypes"
0065  * to locate the beginning of a section.
0066  */
0067 
0068 /* This header can be included multiple times with different defines! */
0069 #ifndef _XOS_R_H_
0070 # define _XOS_R_H_
0071 
0072 # include <X11/Xos.h>
0073 # include <X11/Xfuncs.h>
0074 
0075 # ifndef X_NOT_POSIX
0076 #  ifdef _POSIX_SOURCE
0077 #   include <limits.h>
0078 #  else
0079 #   define _POSIX_SOURCE
0080 #   include <limits.h>
0081 #   undef _POSIX_SOURCE
0082 #  endif
0083 #  ifndef LINE_MAX
0084 #   define X_LINE_MAX 2048
0085 #  else
0086 #   define X_LINE_MAX LINE_MAX
0087 #  endif
0088 # endif
0089 #endif /* _XOS_R_H */
0090 
0091 #ifndef WIN32
0092 
0093 #ifdef __cplusplus
0094 extern "C" {
0095 #endif
0096 
0097 # if defined(XOS_USE_XLIB_LOCKING)
0098 #  ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
0099 typedef struct _LockInfoRec *LockInfoPtr;
0100 extern LockInfoPtr _Xglobal_lock;
0101 #  endif
0102 #  ifndef _Xos_isThreadInitialized
0103 #   define _Xos_isThreadInitialized (_Xglobal_lock)
0104 #  endif
0105 #  if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
0106 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
0107 #    include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
0108 extern void (*_XLockMutex_fn)(
0109 #    if NeedFunctionPrototypes
0110     LockInfoPtr /* lock */, char * /* file */, int /* line */
0111 #    endif
0112 );
0113 extern void (*_XUnlockMutex_fn)(
0114 #    if NeedFunctionPrototypes
0115     LockInfoPtr /* lock */, char * /* file */, int /* line */
0116 #    endif
0117 );
0118 #   endif
0119 #   ifndef _Xos_processLock
0120 #    define _Xos_processLock    \
0121   (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
0122 #   endif
0123 #   ifndef _Xos_processUnlock
0124 #    define _Xos_processUnlock  \
0125   (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
0126 #   endif
0127 #  else
0128 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
0129 #    include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
0130 extern void (*_XLockMutex_fn)(
0131 #    if NeedFunctionPrototypes
0132     LockInfoPtr /* lock */
0133 #    endif
0134 );
0135 extern void (*_XUnlockMutex_fn)(
0136 #    if NeedFunctionPrototypes
0137     LockInfoPtr /* lock */
0138 #    endif
0139 );
0140 #   endif
0141 #   ifndef _Xos_processLock
0142 #    define _Xos_processLock    \
0143   (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
0144 #   endif
0145 #   ifndef _Xos_processUnlock
0146 #    define _Xos_processUnlock  \
0147   (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
0148 #   endif
0149 #  endif
0150 # elif defined(XOS_USE_XT_LOCKING)
0151 #  ifndef _XtThreadsI_h
0152 extern void (*_XtProcessLock)(void);
0153 #  endif
0154 #  ifndef _XtintrinsicP_h
0155 #   include <X11/Xfuncproto.h>  /* for NeedFunctionPrototypes */
0156 extern void XtProcessLock(
0157 #   if NeedFunctionPrototypes
0158     void
0159 #   endif
0160 );
0161 extern void XtProcessUnlock(
0162 #   if NeedFunctionPrototypes
0163     void
0164 #   endif
0165 );
0166 #  endif
0167 #  ifndef _Xos_isThreadInitialized
0168 #   define _Xos_isThreadInitialized _XtProcessLock
0169 #  endif
0170 #  ifndef _Xos_processLock
0171 #   define _Xos_processLock     XtProcessLock()
0172 #  endif
0173 #  ifndef _Xos_processUnlock
0174 #   define _Xos_processUnlock       XtProcessUnlock()
0175 #  endif
0176 # elif defined(XOS_USE_NO_LOCKING)
0177 #  ifndef _Xos_isThreadInitialized
0178 #   define _Xos_isThreadInitialized 0
0179 #  endif
0180 #  ifndef _Xos_processLock
0181 #   define _Xos_processLock     0
0182 #  endif
0183 #  ifndef _Xos_processUnlock
0184 #   define _Xos_processUnlock       0
0185 #  endif
0186 # endif
0187 
0188 #endif /* !defined WIN32 */
0189 
0190 /*
0191  * Solaris defines the POSIX thread-safe feature test macro, but
0192  * uses the older SVR4 thread-safe functions unless the POSIX ones
0193  * are specifically requested.  Fix the feature test macro.
0194  */
0195 #if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
0196     (_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS)
0197 # undef _POSIX_THREAD_SAFE_FUNCTIONS
0198 #endif
0199 
0200 /***** <pwd.h> wrappers *****/
0201 
0202 /*
0203  * Effective prototypes for <pwd.h> wrappers:
0204  *
0205  * #define X_INCLUDE_PWD_H
0206  * #define XOS_USE_..._LOCKING
0207  * #include <X11/Xos_r.h>
0208  *
0209  * typedef ... _Xgetpwparams;
0210  *
0211  * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
0212  * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
0213  */
0214 
0215 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
0216 # include <pwd.h>
0217 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
0218 #  define XOS_USE_MTSAFE_PWDAPI 1
0219 # endif
0220 #endif
0221 
0222 #undef X_NEEDS_PWPARAMS
0223 #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
0224 /* Do nothing */
0225 
0226 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0227 /* Use regular, unsafe API. */
0228 # if defined(X_NOT_POSIX) && !defined(__i386__) && !defined(SYSV)
0229 extern struct passwd *getpwuid(), *getpwnam();
0230 # endif
0231 typedef int _Xgetpwparams;  /* dummy */
0232 # define _XGetpwuid(u,p)    getpwuid((u))
0233 # define _XGetpwnam(u,p)    getpwnam((u))
0234 
0235 #elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
0236 /* UnixWare 2.0, or other systems with thread support but no _r API. */
0237 # define X_NEEDS_PWPARAMS
0238 typedef struct {
0239   struct passwd pws;
0240   char   pwbuf[1024];
0241   struct passwd* pwp;
0242   size_t len;
0243 } _Xgetpwparams;
0244 
0245 /*
0246  * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
0247  * fields.
0248  */
0249 
0250 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
0251     defined(__APPLE__) || defined(__DragonFly__)
0252 static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p)
0253 {
0254    memcpy(&(p).pws, (p).pwp, sizeof(struct passwd));
0255 
0256    (p).pws.pw_name = (p).pwbuf;
0257    (p).len = strlen((p).pwp->pw_name);
0258    strcpy((p).pws.pw_name, (p).pwp->pw_name);
0259 
0260    (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1;
0261    (p).len = strlen((p).pwp->pw_passwd);
0262    strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd);
0263 
0264    (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1;
0265    (p).len = strlen((p).pwp->pw_class);
0266    strcpy((p).pws.pw_class, (p).pwp->pw_class);
0267 
0268    (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1;
0269    (p).len = strlen((p).pwp->pw_gecos);
0270    strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos);
0271 
0272    (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1;
0273    (p).len = strlen((p).pwp->pw_dir);
0274    strcpy((p).pws.pw_dir, (p).pwp->pw_dir);
0275 
0276    (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1;
0277    (p).len = strlen((p).pwp->pw_shell);
0278    strcpy((p).pws.pw_shell, (p).pwp->pw_shell);
0279 
0280    (p).pwp = &(p).pws;
0281 }
0282 
0283 #else
0284 # define _Xpw_copyPasswd(p) \
0285    (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \
0286     ((p).pws.pw_name = (p).pwbuf), \
0287     ((p).len = strlen((p).pwp->pw_name)), \
0288     strcpy((p).pws.pw_name, (p).pwp->pw_name), \
0289     ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
0290     ((p).len = strlen((p).pwp->pw_passwd)), \
0291     strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
0292     ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
0293     ((p).len = strlen((p).pwp->pw_age)), \
0294     strcpy((p).pws.pw_age, (p).pwp->pw_age), \
0295     ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
0296     ((p).len = strlen((p).pwp->pw_comment)), \
0297     strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
0298     ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
0299     ((p).len = strlen((p).pwp->pw_gecos)), \
0300     strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
0301     ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
0302     ((p).len = strlen((p).pwp->pw_dir)), \
0303     strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
0304     ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
0305     ((p).len = strlen((p).pwp->pw_shell)), \
0306     strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
0307     ((p).pwp = &(p).pws), \
0308     0 )
0309 #endif
0310 # define _XGetpwuid(u,p) \
0311 ( (_Xos_processLock), \
0312   (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
0313   (_Xos_processUnlock), \
0314   (p).pwp )
0315 # define _XGetpwnam(u,p) \
0316 ( (_Xos_processLock), \
0317   (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
0318   (_Xos_processUnlock), \
0319   (p).pwp )
0320 
0321 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__)
0322 # define X_NEEDS_PWPARAMS
0323 typedef struct {
0324   struct passwd pws;
0325   char pwbuf[X_LINE_MAX];
0326 } _Xgetpwparams;
0327 # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4)
0328 #   define _XGetpwuid(u,p) \
0329 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
0330 #   define _XGetpwnam(u,p) \
0331 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
0332 # else /* SVR4 */
0333 #  define _XGetpwuid(u,p) \
0334 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
0335 #  define _XGetpwnam(u,p) \
0336 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
0337 # endif /* SVR4 */
0338 
0339 #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
0340 # define X_NEEDS_PWPARAMS
0341 typedef struct {
0342   struct passwd pws;
0343   char pwbuf[X_LINE_MAX];
0344   struct passwd* pwp;
0345 } _Xgetpwparams;
0346 typedef int _Xgetpwret;
0347 # define _XGetpwuid(u,p) \
0348 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
0349  (p).pwp : NULL)
0350 # define _XGetpwnam(u,p) \
0351 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
0352  (p).pwp : NULL)
0353 #endif /* X_INCLUDE_PWD_H */
0354 
0355 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
0356 # define _XOS_INCLUDED_PWD_H
0357 #endif
0358 
0359 
0360 /***** <netdb.h> wrappers *****/
0361 
0362 /*
0363  * Effective prototypes for <netdb.h> wrappers:
0364  *
0365  * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
0366  *  Gethostbyaddr(), and Getservbyname() do NOT copy the host or
0367  *  protocol lists!
0368  *
0369  * #define X_INCLUDE_NETDB_H
0370  * #define XOS_USE_..._LOCKING
0371  * #include <X11/Xos_r.h>
0372  *
0373  * typedef ... _Xgethostbynameparams;
0374  * typedef ... _Xgetservbynameparams;
0375  *
0376  * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
0377  * struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
0378  *                 _Xgethostbynameparams);
0379  * struct servent* _XGetservbyname(const char* name, const char* proto,
0380  *               _Xgetservbynameparams);
0381  */
0382 
0383 #undef XTHREADS_NEEDS_BYNAMEPARAMS
0384 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
0385     && !defined(WIN32)
0386 # include <netdb.h>
0387 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
0388 #  define XOS_USE_MTSAFE_NETDBAPI 1
0389 # endif
0390 #endif
0391 
0392 #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
0393 /* Do nothing. */
0394 
0395 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0396 /* Use regular, unsafe API. */
0397 typedef int _Xgethostbynameparams; /* dummy */
0398 typedef int _Xgetservbynameparams; /* dummy */
0399 # define _XGethostbyname(h,hp)      gethostbyname((h))
0400 # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
0401 # define _XGetservbyname(s,p,sp)    getservbyname((s),(p))
0402 
0403 #elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
0404 /* WARNING:  The h_addr_list and s_aliases values are *not* copied! */
0405 
0406 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
0407 #include <sys/param.h>
0408 #endif
0409 
0410 typedef struct {
0411   struct hostent hent;
0412   char           h_name[MAXHOSTNAMELEN];
0413   struct hostent *hptr;
0414 } _Xgethostbynameparams;
0415 typedef struct {
0416   struct servent sent;
0417   char           s_name[255];
0418   char       s_proto[255];
0419   struct servent *sptr;
0420 } _Xgetservbynameparams;
0421 
0422 # define XTHREADS_NEEDS_BYNAMEPARAMS
0423 
0424 # define _Xg_copyHostent(hp) \
0425    (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
0426     strcpy((hp).h_name, (hp).hptr->h_name), \
0427     ((hp).hent.h_name = (hp).h_name), \
0428     ((hp).hptr = &(hp).hent), \
0429      0 )
0430 # define _Xg_copyServent(sp) \
0431    (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
0432     strcpy((sp).s_name, (sp).sptr->s_name), \
0433     ((sp).sent.s_name = (sp).s_name), \
0434     strcpy((sp).s_proto, (sp).sptr->s_proto), \
0435     ((sp).sent.s_proto = (sp).s_proto), \
0436     ((sp).sptr = &(sp).sent), \
0437     0 )
0438 # define _XGethostbyname(h,hp) \
0439    ((_Xos_processLock), \
0440     (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
0441     (_Xos_processUnlock), \
0442     (hp).hptr )
0443 # define _XGethostbyaddr(a,al,t,hp) \
0444    ((_Xos_processLock), \
0445     (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
0446     (_Xos_processUnlock), \
0447     (hp).hptr )
0448 # define _XGetservbyname(s,p,sp) \
0449    ((_Xos_processLock), \
0450     (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
0451     (_Xos_processUnlock), \
0452     (sp).sptr )
0453 
0454 #elif defined(XUSE_NETDB_R_API)
0455 /*
0456  * POSIX does not specify _r equivalents for <netdb.h> API, but some
0457  * vendors provide them anyway.  Use them only when explicitly asked.
0458  */
0459 # ifdef _POSIX_REENTRANT_FUNCTIONS
0460 #  ifndef _POSIX_THREAD_SAFE_FUNCTIONS
0461 #  endif
0462 # endif
0463 # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
0464 #  define X_POSIX_THREAD_SAFE_FUNCTIONS 1
0465 # endif
0466 
0467 # define XTHREADS_NEEDS_BYNAMEPARAMS
0468 
0469 # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
0470 typedef struct {
0471     struct hostent      hent;
0472     char                hbuf[X_LINE_MAX];
0473     int                 herr;
0474 } _Xgethostbynameparams;
0475 typedef struct {
0476     struct servent      sent;
0477     char                sbuf[X_LINE_MAX];
0478 } _Xgetservbynameparams;
0479 #  define _XGethostbyname(h,hp) \
0480   gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
0481 #  define _XGethostbyaddr(a,al,t,hp) \
0482   gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
0483 #  define _XGetservbyname(s,p,sp) \
0484   getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
0485 # else
0486 typedef struct {
0487   struct hostent      hent;
0488   struct hostent_data hdata;
0489 } _Xgethostbynameparams;
0490 typedef struct {
0491   struct servent      sent;
0492   struct servent_data sdata;
0493 } _Xgetservbynameparams;
0494 #  define _XGethostbyname(h,hp) \
0495   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),    \
0496    ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
0497 #  define _XGethostbyaddr(a,al,t,hp) \
0498   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),    \
0499    ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
0500 #  define _XGetservbyname(s,p,sp) \
0501   (bzero((char*)&(sp).sdata,sizeof((sp).sdata)),    \
0502    ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
0503 # endif
0504 # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
0505 #  undef X_POSIX_THREAD_SAFE_FUNCTIONS
0506 # endif
0507 
0508 #else
0509 /* The regular API is assumed to be MT-safe under POSIX. */
0510 typedef int _Xgethostbynameparams; /* dummy */
0511 typedef int _Xgetservbynameparams; /* dummy */
0512 # define _XGethostbyname(h,hp)      gethostbyname((h))
0513 # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
0514 # define _XGetservbyname(s,p,sp)    getservbyname((s),(p))
0515 #endif /* X_INCLUDE_NETDB_H */
0516 
0517 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
0518 # define _XOS_INCLUDED_NETDB_H
0519 #endif
0520 
0521 
0522 /***** <dirent.h> wrappers *****/
0523 
0524 /*
0525  * Effective prototypes for <dirent.h> wrappers:
0526  *
0527  * #define X_INCLUDE_DIRENT_H
0528  * #define XOS_USE_..._LOCKING
0529  * #include <X11/Xos_r.h>
0530  *
0531  * typedef ... _Xreaddirparams;
0532  *
0533  * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
0534  */
0535 
0536 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
0537 # include <sys/types.h>
0538 # if !defined(X_NOT_POSIX) || defined(SYSV)
0539 #  include <dirent.h>
0540 # else
0541 #  include <sys/dir.h>
0542 #  ifndef dirent
0543 #   define dirent direct
0544 #  endif
0545 # endif
0546 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
0547 #  define XOS_USE_MTSAFE_DIRENTAPI 1
0548 # endif
0549 #endif
0550 
0551 #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
0552 /* Do nothing. */
0553 
0554 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0555 /* Use regular, unsafe API. */
0556 typedef int _Xreaddirparams;    /* dummy */
0557 # define _XReaddir(d,p) readdir(d)
0558 
0559 #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
0560 /* Systems with thread support but no _r API. */
0561 typedef struct {
0562   struct dirent *result;
0563   struct dirent dir_entry;
0564 # ifdef _POSIX_PATH_MAX
0565   char buf[_POSIX_PATH_MAX];
0566 # elif defined(NAME_MAX)
0567   char buf[NAME_MAX];
0568 # else
0569   char buf[255];
0570 # endif
0571 } _Xreaddirparams;
0572 
0573 # define _XReaddir(d,p) \
0574  ( (_Xos_processLock),                       \
0575    (((p).result = readdir((d))) ?                \
0576     (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
0577      ((p).result = &(p).dir_entry), 0) :             \
0578     0),                              \
0579    (_Xos_processUnlock),                     \
0580    (p).result )
0581 
0582 #else
0583 typedef struct {
0584   struct dirent *result;
0585   struct dirent dir_entry;
0586 # ifdef _POSIX_PATH_MAX
0587   char buf[_POSIX_PATH_MAX];
0588 # elif defined(NAME_MAX)
0589   char buf[NAME_MAX];
0590 # else
0591   char buf[255];
0592 # endif
0593 } _Xreaddirparams;
0594 
0595 # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__)
0596 /* POSIX final API, returns (int)0 on success. */
0597 #  define _XReaddir(d,p)                        \
0598     (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
0599 # elif defined(_POSIX_REENTRANT_FUNCTIONS)
0600 /* POSIX draft API, returns (int)0 on success. */
0601 #  define _XReaddir(d,p)    \
0602     (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
0603 # elif defined(SVR4)
0604 /* Pre-POSIX API, returns non-NULL on success. */
0605 #  define _XReaddir(d,p)    (readdir_r((d), &(p).dir_entry))
0606 # else
0607 /* We have no idea what is going on.  Fake it all using process locks. */
0608 #  define _XReaddir(d,p)    \
0609     ( (_Xos_processLock),                       \
0610       (((p).result = readdir((d))) ?                    \
0611        (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
0612     ((p).result = &(p).dir_entry), 0) :             \
0613        0),                              \
0614       (_Xos_processUnlock),                     \
0615       (p).result )
0616 # endif
0617 #endif /* X_INCLUDE_DIRENT_H */
0618 
0619 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
0620 # define _XOS_INCLUDED_DIRENT_H
0621 #endif
0622 
0623 
0624 /***** <unistd.h> wrappers *****/
0625 
0626 /*
0627  * Effective prototypes for <unistd.h> wrappers:
0628  *
0629  * #define X_INCLUDE_UNISTD_H
0630  * #define XOS_USE_..._LOCKING
0631  * #include <X11/Xos_r.h>
0632  *
0633  * typedef ... _Xgetloginparams;
0634  * typedef ... _Xttynameparams;
0635  *
0636  * char *_XGetlogin(_Xgetloginparams);
0637  * char *_XTtyname(int, _Xttynameparams);
0638  */
0639 
0640 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
0641 /* <unistd.h> already included by <X11/Xos.h> */
0642 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
0643 #  define XOS_USE_MTSAFE_UNISTDAPI 1
0644 # endif
0645 #endif
0646 
0647 #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
0648 /* Do nothing. */
0649 
0650 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0651 /* Use regular, unsafe API. */
0652 typedef int _Xgetloginparams;   /* dummy */
0653 typedef int _Xttynameparams;    /* dummy */
0654 # define _XGetlogin(p)  getlogin()
0655 # define _XTtyname(f)   ttyname((f))
0656 
0657 #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
0658 /* Systems with thread support but no _r API. */
0659 typedef struct {
0660   char *result;
0661 # if defined(MAXLOGNAME)
0662   char buf[MAXLOGNAME];
0663 # elif defined(LOGIN_NAME_MAX)
0664   char buf[LOGIN_NAME_MAX];
0665 # else
0666   char buf[64];
0667 # endif
0668 } _Xgetloginparams;
0669 typedef struct {
0670   char *result;
0671 # ifdef TTY_NAME_MAX
0672   char buf[TTY_NAME_MAX];
0673 # elif defined(_POSIX_TTY_NAME_MAX)
0674   char buf[_POSIX_TTY_NAME_MAX];
0675 # elif defined(_POSIX_PATH_MAX)
0676   char buf[_POSIX_PATH_MAX];
0677 # else
0678   char buf[256];
0679 # endif
0680 } _Xttynameparams;
0681 
0682 # define _XGetlogin(p) \
0683  ( (_Xos_processLock), \
0684    (((p).result = getlogin()) ? \
0685     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
0686      ((p).buf[sizeof((p).buf)-1] = '\0'), \
0687      ((p).result = (p).buf), 0) : 0), \
0688    (_Xos_processUnlock), \
0689    (p).result )
0690 #define _XTtyname(f,p) \
0691  ( (_Xos_processLock), \
0692    (((p).result = ttyname(f)) ? \
0693     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
0694      ((p).buf[sizeof((p).buf)-1] = '\0'), \
0695      ((p).result = (p).buf), 0) : 0), \
0696    (_Xos_processUnlock), \
0697    (p).result )
0698 
0699 #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
0700 /* POSIX API.
0701  *
0702  * extern int getlogin_r(char *, size_t);
0703  * extern int ttyname_r(int, char *, size_t);
0704  */
0705 typedef struct {
0706 # if defined(MAXLOGNAME)
0707   char buf[MAXLOGNAME];
0708 # elif defined(LOGIN_NAME_MAX)
0709   char buf[LOGIN_NAME_MAX];
0710 # else
0711   char buf[64];
0712 # endif
0713 } _Xgetloginparams;
0714 typedef struct {
0715 # ifdef TTY_NAME_MAX
0716   char buf[TTY_NAME_MAX];
0717 # elif defined(_POSIX_TTY_NAME_MAX)
0718   char buf[_POSIX_TTY_NAME_MAX];
0719 # elif defined(_POSIX_PATH_MAX)
0720   char buf[_POSIX_PATH_MAX];
0721 # else
0722   char buf[256];
0723 # endif
0724 } _Xttynameparams;
0725 
0726 # define _XGetlogin(p)  (getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
0727 # define _XTtyname(f,p) \
0728     (ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
0729 
0730 #else
0731 /* Pre-POSIX API.
0732  *
0733  * extern char *getlogin_r(char *, size_t);
0734  * extern char *ttyname_r(int, char *, size_t);
0735  */
0736 typedef struct {
0737 # if defined(MAXLOGNAME)
0738   char buf[MAXLOGNAME];
0739 # elif defined(LOGIN_NAME_MAX)
0740   char buf[LOGIN_NAME_MAX];
0741 # else
0742   char buf[64];
0743 # endif
0744 } _Xgetloginparams;
0745 typedef struct {
0746 # ifdef TTY_NAME_MAX
0747   char buf[TTY_NAME_MAX];
0748 # elif defined(_POSIX_TTY_NAME_MAX)
0749   char buf[_POSIX_TTY_NAME_MAX];
0750 # elif defined(_POSIX_PATH_MAX)
0751   char buf[_POSIX_PATH_MAX];
0752 # else
0753   char buf[256];
0754 # endif
0755 } _Xttynameparams;
0756 
0757 # define _XGetlogin(p)  getlogin_r((p).buf, sizeof((p).buf))
0758 # define _XTtyname(f,p) ttyname_r((f), (p).buf, sizeof((p).buf))
0759 #endif /* X_INCLUDE_UNISTD_H */
0760 
0761 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
0762 # define _XOS_INCLUDED_UNISTD_H
0763 #endif
0764 
0765 
0766 /***** <string.h> wrappers *****/
0767 
0768 /*
0769  * Effective prototypes for <string.h> wrappers:
0770  *
0771  * #define X_INCLUDE_STRING_H
0772  * #define XOS_USE_..._LOCKING
0773  * #include <X11/Xos_r.h>
0774  *
0775  * typedef ... _Xstrtokparams;
0776  *
0777  * char *_XStrtok(char *, const char*, _Xstrtokparams);
0778  */
0779 
0780 #if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
0781 /* <string.h> has already been included by <X11/Xos.h> */
0782 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
0783 #  define XOS_USE_MTSAFE_STRINGAPI 1
0784 # endif
0785 #endif
0786 
0787 #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
0788 /* Do nothing. */
0789 
0790 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0791 /* Use regular, unsafe API. */
0792 typedef int _Xstrtokparams; /* dummy */
0793 # define _XStrtok(s1,s2,p) \
0794  ( p = 0, (void)p, strtok((s1),(s2)) )
0795 
0796 #elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
0797 /* Systems with thread support but no _r API. */
0798 typedef char *_Xstrtokparams;
0799 # define _XStrtok(s1,s2,p) \
0800  ( (_Xos_processLock), \
0801    ((p) = strtok((s1),(s2))), \
0802    (_Xos_processUnlock), \
0803    (p) )
0804 
0805 #else
0806 /* POSIX or pre-POSIX API. */
0807 typedef char * _Xstrtokparams;
0808 # define _XStrtok(s1,s2,p)  strtok_r((s1),(s2),&(p))
0809 #endif /* X_INCLUDE_STRING_H */
0810 
0811 
0812 /***** <time.h> wrappers *****/
0813 
0814 /*
0815  * Effective prototypes for <time.h> wrappers:
0816  *
0817  * #define X_INCLUDE_TIME_H
0818  * #define XOS_USE_..._LOCKING
0819  * #include <X11/Xos_r.h>
0820  *
0821  * typedef ... _Xatimeparams;
0822  * typedef ... _Xctimeparams;
0823  * typedef ... _Xgtimeparams;
0824  * typedef ... _Xltimeparams;
0825  *
0826  * char *_XAsctime(const struct tm *, _Xatimeparams);
0827  * char *_XCtime(const time_t *, _Xctimeparams);
0828  * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
0829  * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
0830  */
0831 
0832 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
0833 # include <time.h>
0834 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
0835 #  define XOS_USE_MTSAFE_TIMEAPI 1
0836 # endif
0837 #endif
0838 
0839 #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
0840 /* Do nothing. */
0841 
0842 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0843 /* Use regular, unsafe API. */
0844 typedef int _Xatimeparams;  /* dummy */
0845 # define _XAsctime(t,p)     asctime((t))
0846 typedef int _Xctimeparams;  /* dummy */
0847 # define _XCtime(t,p)       ctime((t))
0848 typedef int _Xgtimeparams;  /* dummy */
0849 # define _XGmtime(t,p)      gmtime((t))
0850 typedef int _Xltimeparams;  /* dummy */
0851 # define _XLocaltime(t,p)   localtime((t))
0852 
0853 #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
0854 /* Systems with thread support but no _r API. */
0855 typedef struct {
0856 # ifdef TIMELEN
0857   char buf[TIMELEN];
0858 # else
0859   char buf[26];
0860 # endif
0861   char *result;
0862 } _Xctimeparams, _Xatimeparams;
0863 typedef struct {
0864   struct tm buf;
0865   struct tm *result;
0866 } _Xgtimeparams, _Xltimeparams;
0867 # define _XAsctime(t,p) \
0868  ( (_Xos_processLock), \
0869    (((p).result = asctime((t))) ? \
0870     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
0871     0), \
0872    (_Xos_processUnlock), \
0873    (p).result )
0874 # define _XCtime(t,p) \
0875  ( (_Xos_processLock), \
0876    (((p).result = ctime((t))) ? \
0877     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
0878     0), \
0879    (_Xos_processUnlock), \
0880    (p).result )
0881 # define _XGmtime(t,p) \
0882  ( (_Xos_processLock), \
0883    (((p).result = gmtime(t)) ? \
0884     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
0885     0), \
0886    (_Xos_processUnlock), \
0887    (p).result )
0888 # define _XLocaltime(t,p) \
0889  ( (_Xos_processLock), \
0890    (((p).result = localtime(t)) ? \
0891     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
0892     0), \
0893    (_Xos_processUnlock), \
0894    (p).result )
0895 
0896 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) &&  defined(hpV4)
0897 /* Returns (int)0 on success.
0898  *
0899  * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
0900  * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
0901  * extern int gmtime_r(const time_t *timer, struct tm *result);
0902  * extern int localtime_r(const time_t *timer, struct tm *result);
0903  */
0904 # ifdef TIMELEN
0905 typedef char _Xatimeparams[TIMELEN];
0906 typedef char _Xctimeparams[TIMELEN];
0907 # else
0908 typedef char _Xatimeparams[26];
0909 typedef char _Xctimeparams[26];
0910 # endif
0911 typedef struct tm _Xgtimeparams;
0912 typedef struct tm _Xltimeparams;
0913 # define _XAsctime(t,p)     (asctime_r((t),(p),sizeof((p))) ? NULL : (p))
0914 # define _XCtime(t,p)       (ctime_r((t),(p),sizeof((p))) ? NULL : (p))
0915 # define _XGmtime(t,p)      (gmtime_r((t),&(p)) ? NULL : &(p))
0916 # define _XLocaltime(t,p)   (localtime_r((t),&(p)) ? NULL : &(p))
0917 
0918 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
0919 /* Returns NULL on failure.  Solaris 2.5
0920  *
0921  * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
0922  * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
0923  * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
0924  * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
0925  */
0926 # ifdef TIMELEN
0927 typedef char _Xatimeparams[TIMELEN];
0928 typedef char _Xctimeparams[TIMELEN];
0929 # else
0930 typedef char _Xatimeparams[26];
0931 typedef char _Xctimeparams[26];
0932 # endif
0933 typedef struct tm _Xgtimeparams;
0934 typedef struct tm _Xltimeparams;
0935 # define _XAsctime(t,p)     asctime_r((t),(p),sizeof((p)))
0936 # define _XCtime(t,p)       ctime_r((t),(p),sizeof((p)))
0937 # define _XGmtime(t,p)      gmtime_r((t),&(p))
0938 # define _XLocaltime(t,p)   localtime_r((t),&(p))
0939 
0940 #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
0941 /* POSIX final API.
0942  * extern char *asctime_r(const struct tm *timeptr, char *buffer);
0943  * extern char *ctime_r(const time_t *timer, char *buffer);
0944  * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
0945  * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
0946  */
0947 # ifdef TIMELEN
0948 typedef char _Xatimeparams[TIMELEN];
0949 typedef char _Xctimeparams[TIMELEN];
0950 # else
0951 typedef char _Xatimeparams[26];
0952 typedef char _Xctimeparams[26];
0953 # endif
0954 typedef struct tm _Xgtimeparams;
0955 typedef struct tm _Xltimeparams;
0956 # define _XAsctime(t,p)     asctime_r((t),(p))
0957 # define _XCtime(t,p)       ctime_r((t),(p))
0958 # define _XGmtime(t,p)      gmtime_r((t),&(p))
0959 # define _XLocaltime(t,p)   localtime_r((t),&(p))
0960 #endif /* X_INCLUDE_TIME_H */
0961 
0962 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
0963 # define _XOS_INCLUDED_TIME_H
0964 #endif
0965 
0966 
0967 /***** <grp.h> wrappers *****/
0968 
0969 /*
0970  * Effective prototypes for <grp.h> wrappers:
0971  *
0972  * NOTE: On systems lacking appropriate _r functions Getgrgid() and
0973  *  Getgrnam() do NOT copy the list of group members!
0974  *
0975  * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
0976  * are not included in POSIX.
0977  *
0978  * #define X_INCLUDE_GRP_H
0979  * #define XOS_USE_..._LOCKING
0980  * #include <X11/Xos_r.h>
0981  *
0982  * typedef ... _Xgetgrparams;
0983  *
0984  * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
0985  * struct group *_XGetgrnam(const char *, _Xgetgrparams);
0986  */
0987 
0988 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
0989 # include <grp.h>
0990 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
0991 #  define XOS_USE_MTSAFE_GRPAPI 1
0992 # endif
0993 #endif
0994 
0995 #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
0996 /* Do nothing. */
0997 
0998 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
0999 /* Use regular, unsafe API. */
1000 typedef int _Xgetgrparams;  /* dummy */
1001 #define _XGetgrgid(g,p) getgrgid((g))
1002 #define _XGetgrnam(n,p) getgrnam((n))
1003 
1004 #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
1005 /* Systems with thread support but no _r API.  UnixWare 2.0. */
1006 typedef struct {
1007   struct group grp;
1008   char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1009   struct group *pgrp;
1010   size_t len;
1011 } _Xgetgrparams;
1012 #ifdef SVR4
1013 /* Copy the gr_passwd field too. */
1014 # define _Xgrp_copyGroup(p) \
1015  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1016    ((p).grp.gr_name = (p).buf), \
1017    ((p).len = strlen((p).pgrp->gr_name)), \
1018    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1019    ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
1020    ((p).pgrp = &(p).grp), \
1021    0 )
1022 #else
1023 # define _Xgrp_copyGroup(p) \
1024  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1025    ((p).grp.gr_name = (p).buf), \
1026    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1027    ((p).pgrp = &(p).grp), \
1028    0 )
1029 #endif
1030 #define _XGetgrgid(g,p) \
1031  ( (_Xos_processLock), \
1032    (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
1033    (_Xos_processUnlock), \
1034    (p).pgrp )
1035 #define _XGetgrnam(n,p) \
1036  ( (_Xos_processLock), \
1037    (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
1038    (_Xos_processUnlock), \
1039    (p).pgrp )
1040 
1041 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
1042 /* Non-POSIX API.  Solaris.
1043  *
1044  * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
1045  * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
1046  */
1047 typedef struct {
1048   struct group grp;
1049   char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1050 } _Xgetgrparams;
1051 #define _XGetgrgid(g,p) getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
1052 #define _XGetgrnam(n,p) getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
1053 
1054 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1055 /* Non-POSIX API.
1056  * extern int getgrgid_r(gid_t, struct group *, char *, int);
1057  * extern int getgrnam_r(const char *, struct group *, char *, int);
1058  */
1059 typedef struct {
1060   struct group grp;
1061   char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1062 } _Xgetgrparams;
1063 #define _XGetgrgid(g,p) \
1064  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1065 #define _XGetgrnam(n,p) \
1066  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1067 
1068 #else
1069 /* POSIX final API.
1070  *
1071  * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
1072  * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
1073  */
1074 typedef struct {
1075   struct group grp;
1076   char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1077   struct group *result;
1078 } _Xgetgrparams;
1079 
1080 #define _XGetgrgid(g,p) \
1081  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1082    NULL : (p).result))
1083 #define _XGetgrnam(n,p) \
1084  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1085    NULL : (p).result))
1086 #endif
1087 
1088 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
1089 # define _XOS_INCLUDED_GRP_H
1090 #endif
1091 
1092 
1093 #ifdef __cplusplus
1094 }  /* Close scope of 'extern "C"' declaration which encloses file. */
1095 #endif