]> git.sesse.net Git - rdpsrv/blob - Xserver/include/Xos_r.h
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / include / Xos_r.h
1 /* $XConsortium: Xos_r.h /main/5 1996/12/18 16:29:14 lehors $ */
2 /* 
3 Copyright (c) 1996  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
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 X CONSORTIUM 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 X Consortium 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 X Consortium.
25 */
26 /* $XFree86: xc/include/Xos_r.h,v 1.3 1997/01/18 07:17:11 dawes 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_isThreadsInitialized.  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 approriate _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 # endif
87 #endif /* _XOS_R_H */
88
89 #ifndef WIN32
90
91 #ifdef __cplusplus
92 extern "C" {
93 #endif
94
95 # if defined(XOS_USE_XLIB_LOCKING)
96 #  ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
97 typedef struct _LockInfoRec *LockInfoPtr;
98 extern LockInfoPtr _Xglobal_lock;
99 #  endif
100 #  ifndef _Xos_isThreadInitialized
101 #   define _Xos_isThreadInitialized     (_Xglobal_lock)
102 #  endif
103 #  if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
104 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
105 #    include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
106 extern void (*_XLockMutex_fn)(
107 #    if NeedFunctionPrototypes
108     LockInfoPtr /* lock */, char * /* file */, int /* line */
109 #    endif
110 );
111 extern void (*_XUnlockMutex_fn)(
112 #    if NeedFunctionPrototypes
113     LockInfoPtr /* lock */, char * /* file */, int /* line */
114 #    endif
115 );
116 #   endif
117 #   ifndef _Xos_processLock
118 #    define _Xos_processLock    \
119   (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
120 #   endif
121 #   ifndef _Xos_processUnlock
122 #    define _Xos_processUnlock  \
123   (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
124 #   endif
125 #  else
126 #   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
127 #    include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
128 extern void (*_XLockMutex_fn)(
129 #    if NeedFunctionPrototypes
130     LockInfoPtr /* lock */
131 #    endif
132 );
133 extern void (*_XUnlockMutex_fn)(
134 #    if NeedFunctionPrototypes
135     LockInfoPtr /* lock */
136 #    endif
137 );
138 #   endif
139 #   ifndef _Xos_processLock
140 #    define _Xos_processLock    \
141   (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
142 #   endif
143 #   ifndef _Xos_processUnlock
144 #    define _Xos_processUnlock  \
145   (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
146 #   endif
147 #  endif
148 # elif defined(XOS_USE_XT_LOCKING)
149 extern void (*_XtProcessLock)();
150 #  ifndef _XtintrinsicP_h
151 #   include <X11/Xfuncproto.h>  /* for NeedFunctionPrototypes */
152 extern void XtProcessLock(
153 #   if NeedFunctionPrototypes
154     void
155 #   endif
156 );
157 extern void XtProcessUnlock(
158 #   if NeedFunctionPrototypes
159     void
160 #   endif
161 );
162 #  endif
163 #  ifndef _Xos_isThreadInitialized
164 #   define _Xos_isThreadInitialized     _XtProcessLock
165 #  endif
166 #  ifndef _Xos_processLock
167 #   define _Xos_processLock             XtProcessLock()
168 #  endif
169 #  ifndef _Xos_processUnlock
170 #   define _Xos_processUnlock           XtProcessUnlock()
171 #  endif
172 # elif defined(XOS_USE_NO_LOCKING)
173 #  ifndef _Xos_isThreadInitialized
174 #   define _Xos_isThreadInitialized     0
175 #  endif
176 #  ifndef _Xos_processLock
177 #   define _Xos_processLock             0
178 #  endif
179 #  ifndef _Xos_processUnlock
180 #   define _Xos_processUnlock           0
181 #  endif
182 # endif
183
184 #endif /* !defined WIN32 */
185
186 /* 
187  * Solaris 2.5 has SVR4 thread-safe API, but defines the POSIX
188  * thread-safe feature test macro.  Fix the feature test macro.
189  */
190 #if defined(sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
191 # undef _POSIX_THREAD_SAFE_FUNCTIONS
192 #endif
193
194
195 /***** <pwd.h> wrappers *****/
196
197 /*
198  * Effective prototypes for <pwd.h> wrappers:
199  *
200  * #define X_INCLUDE_PWD_H
201  * #define XOS_USE_..._LOCKING
202  * #include <X11/Xos_r.h>
203  *
204  * typedef ... _Xgetpwparams;
205  *
206  * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
207  * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
208  */
209
210 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
211 # include <pwd.h>
212 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
213 #  define XOS_USE_MTSAFE_PWDAPI 1
214 # endif
215 #endif
216
217 #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
218 /* Do nothing */
219
220 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
221 /* Use regular, unsafe API. */
222 # if defined(X_NOT_POSIX) && !defined(i386) && !defined(SYSV)
223 extern struct passwd *getpwuid(), *getpwnam();
224 # endif
225 typedef int _Xgetpwparams;      /* dummy */
226 # define _XGetpwuid(u,p)        getpwuid((u))
227 # define _XGetpwnam(u,p)        getpwnam((u))
228
229 #elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
230 /* UnixWare 2.0, or other systems with thread support but no _r API. */
231 typedef struct {
232   struct passwd pws;
233   char   pwbuf[1024];
234   struct passwd* pwp;
235   size_t len;
236 } _Xgetpwparams;
237 # define _Xpw_copyPasswd(p) \
238    (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \
239     ((p).pws.pw_name = (p).pwbuf), \
240     ((p).len = strlen((p).pwp->pw_name)), \
241     strcpy((p).pws.pw_name, (p).pwp->pw_name), \
242     ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
243     ((p).len = strlen((p).pwp->pw_passwd)), \
244     strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
245     ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
246     ((p).len = strlen((p).pwp->pw_age)), \
247     strcpy((p).pws.pw_age, (p).pwp->pw_age), \
248     ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
249     ((p).len = strlen((p).pwp->pw_comment)), \
250     strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
251     ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
252     ((p).len = strlen((p).pwp->pw_gecos)), \
253     strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
254     ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
255     ((p).len = strlen((p).pwp->pw_dir)), \
256     strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
257     ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
258     ((p).len = strlen((p).pwp->pw_shell)), \
259     strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
260     ((p).pwp = &(p).pws), \
261     0 )
262 # define _XGetpwuid(u,p) \
263 ( (_Xos_processLock), \
264   (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p) : 0), \
265   (_Xos_processUnlock), \
266   (p).pwp )
267 # define _XGetpwnam(u,p) \
268 ( (_Xos_processLock), \
269   (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p) : 0), \
270   (_Xos_processUnlock), \
271   (p).pwp )
272
273 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
274 /* SVR4 threads, AIX 4.2.0 and earlier and OSF/1 3.2 and earlier pthreads */
275 # if defined(Lynx) && !defined(LINE_MAX)
276 #  define LINE_MAX      2048            /* what Xthreads.h does */
277 # endif
278 typedef struct {
279   struct passwd pws;
280   char pwbuf[LINE_MAX];
281 } _Xgetpwparams;
282 # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4) || defined(Lynx)
283 #  ifndef Lynx
284 #   define _XGetpwuid(u,p) \
285 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
286 #   define _XGetpwnam(u,p) \
287 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
288 #  else /* Lynx */
289 #   define _XGetpwuid(u,p) \
290 ((getpwuid_r(&(p).pws,(u),(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
291 #   define _XGetpwnam(u,p) \
292 ((getpwnam_r(&(p).pws,(u),(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
293 #  endif
294 # else /* SVR4 */
295 #  define _XGetpwuid(u,p) \
296 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
297 #  define _XGetpwnam(u,p) \
298 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
299 # endif /* SVR4 */
300
301 #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
302 /* Digital UNIX 4.0, but not (beta) T4.0-1 */
303 # if defined(__osf__)
304 /* OSF/1 V4.0 <pwd.h> doesn't declare the _P routines, breaking under C++. */
305 extern int _Pgetpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
306 extern int _Pgetpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **);
307 # endif
308 typedef struct {
309   struct passwd pws;
310   char pwbuf[LINE_MAX];
311   struct passwd* pwp;
312 } _Xgetpwparams;
313 typedef int _Xgetpwret;
314 # define _XGetpwuid(u,p) \
315 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == -1) ? \
316  NULL : (p).pwp)
317 # define _XGetpwnam(u,p) \
318 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == -1) ? \
319  NULL : (p).pwp)
320 #endif /* X_INCLUDE_PWD_H */
321
322 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
323 # define _XOS_INCLUDED_PWD_H
324 #endif
325
326
327 /***** <netdb.h> wrappers *****/
328
329 /* 
330  * Effective prototypes for <netdb.h> wrappers:
331  *
332  * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
333  *      Gethostbyaddr(), and Getservbyname() do NOT copy the host or
334  *      protocol lists!
335  *
336  * #define X_INCLUDE_NETDB_H
337  * #define XOS_USE_..._LOCKING
338  * #include <X11/Xos_r.h>
339  *
340  * typedef ... _Xgethostbynameparams;
341  * typedef ... _Xgetservbynameparams;
342  *
343  * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
344  * struct hostent* _XGethostbyaddr(const char* addr, int len, int type, 
345  *                                 _Xgethostbynameparams);
346  * struct servent* _XGetservbyname(const char* name, const char* proto,
347  *                               _Xgetservbynameparams);
348  */
349
350 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
351     && !defined(WIN32)
352 # include <netdb.h>
353 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
354 #  define XOS_USE_MTSAFE_NETDBAPI 1
355 # endif
356 #endif
357
358 #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
359 /* Do nothing. */
360
361 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
362 /* Use regular, unsafe API. */
363 typedef int _Xgethostbynameparams; /* dummy */
364 typedef int _Xgetservbynameparams; /* dummy */
365 # define _XGethostbyname(h,hp)          gethostbyname((h))
366 # define _XGethostbyaddr(a,al,t,hp)     gethostbyaddr((a),(al),(t))
367 # define _XGetservbyname(s,p,sp)        getservbyname((s),(p))
368
369 #elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
370 /* UnixWare 2.0, or other systems with thread support but no _r API. */
371 /* WARNING:  The h_addr_list and s_aliases values are *not* copied! */
372
373 typedef struct {
374   struct hostent hent;
375   char           h_name[MAXHOSTNAMELEN];
376   struct hostent *hptr;
377 } _Xgethostbynameparams;
378 typedef struct {
379   struct servent sent;
380   char           s_name[255];
381   char           s_proto[255];
382   struct servent *sptr;
383 } _Xgetservbynameparams;
384 # define _Xg_copyHostent(hp) \
385    (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
386     strcpy((hp).h_name, (hp).hptr->h_name), \
387     ((hp).hent.h_name = (hp).h_name), \
388     ((hp).hptr = &(hp).hent), \
389      0 )
390 # define _Xg_copyServent(sp) \
391    (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
392     strcpy((sp).s_name, (sp).sptr->s_name), \
393     ((sp).sent.s_name = (sp).s_name), \
394     strcpy((sp).s_proto, (sp).sptr->s_proto), \
395     ((sp).sent.s_proto = (sp).s_proto), \
396     ((sp).sptr = &(sp).sent), \
397     0 )
398 # define _XGethostbyname(h,hp) \
399    ((_Xos_processLock), \
400     (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
401     (_Xos_processUnlock), \
402     (hp).hptr )
403 # define _XGethostbyaddr(a,al,t,hp) \
404    ((_Xos_processLock), \
405     (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
406     (_Xos_processUnlock), \
407     (hp).hptr )
408 # define _XGetservbyname(s,p,sp) \
409    ((_Xos_processLock), \
410     (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
411     (_Xos_processUnlock), \
412     (sp).sptr )
413
414 #elif defined(XUSE_NETDB_R_API)
415 /*
416  * POSIX does not specify _r equivalents for <netdb.h> API, but some
417  * vendors provide them anyway.  Use them only when explicitly asked.
418  */
419 # ifdef _POSIX_REENTRANT_FUNCTIONS
420 #  ifndef _POSIX_THREAD_SAFE_FUNCTIONS
421 #   if defined(AIXV3) || defined(AIXV4) || defined(__osf__)
422 #    define X_POSIX_THREAD_SAFE_FUNCTIONS 1
423 #   endif
424 #  endif
425 # endif
426 # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
427 #  define X_POSIX_THREAD_SAFE_FUNCTIONS 1
428 # endif
429
430 # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
431 typedef struct {
432     struct hostent      hent;
433     char                hbuf[LINE_MAX];
434     int                 herr;
435 } _Xgethostbynameparams;
436 typedef struct {
437     struct servent      sent;
438     char                sbuf[LINE_MAX];
439 } _Xgetservbynameparams;
440 #  define _XGethostbyname(h,hp) \
441   gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
442 #  define _XGethostbyaddr(a,al,t,hp) \
443   gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
444 #  define _XGetservbyname(s,p,sp) \
445   getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
446 # else
447 typedef struct {
448   struct hostent      hent;
449   struct hostent_data hdata;
450 } _Xgethostbynameparams;
451 typedef struct {
452   struct servent      sent;
453   struct servent_data sdata;
454 } _Xgetservbynameparams;
455 #  define _XGethostbyname(h,hp) \
456   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),        \
457    ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
458 #  define _XGethostbyaddr(a,al,t,hp) \
459   (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),        \
460    ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
461 #  define _XGetservbyname(s,p,sp) \
462   (bzero((char*)&(sp).sdata,sizeof((sp).sdata)),        \
463    ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
464 # endif
465 # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
466 #  undef X_POSIX_THREAD_SAFE_FUNCTIONS
467 # endif
468
469 #else
470 /* The regular API is assumed to be MT-safe under POSIX. */
471 typedef int _Xgethostbynameparams; /* dummy */
472 typedef int _Xgetservbynameparams; /* dummy */
473 # define _XGethostbyname(h,hp)          gethostbyname((h))
474 # define _XGethostbyaddr(a,al,t,hp)     gethostbyaddr((a),(al),(t))
475 # define _XGetservbyname(s,p,sp)        getservbyname((s),(p))
476 #endif /* X_INCLUDE_NETDB_H */
477
478 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
479 # define _XOS_INCLUDED_NETDB_H
480 #endif
481
482
483 /***** <dirent.h> wrappers *****/
484
485 /*
486  * Effective prototypes for <dirent.h> wrappers:
487  *
488  * #define X_INCLUDE_DIRENT_H
489  * #define XOS_USE_..._LOCKING
490  * #include <X11/Xos_r.h>
491  * 
492  * typedef ... _Xreaddirparams;
493  *
494  * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
495  */
496
497 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
498 # include <sys/types.h>
499 # if !defined(X_NOT_POSIX) || defined(SYSV) || defined(USG)
500 #  include <dirent.h>
501 # else
502 #  include <sys/dir.h>
503 #  ifndef dirent
504 #   define dirent direct
505 #  endif
506 # endif
507 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
508 #  define XOS_USE_MTSAFE_DIRENTAPI 1
509 # endif
510 #endif
511
512 #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
513 /* Do nothing. */
514
515 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
516 /* Use regular, unsafe API. */
517 typedef int _Xreaddirparams;    /* dummy */
518 # define _XReaddir(d,p) readdir(d)
519
520 #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
521 /* Systems with thread support but no _r API. */
522 typedef struct {
523   struct dirent *result;
524   struct dirent dir_entry;
525 # ifdef _POSIX_PATH_MAX
526   char buf[_POSIX_PATH_MAX];
527 # elif defined(NAME_MAX)
528   char buf[NAME_MAX];
529 # else
530   char buf[255];
531 # endif
532 } _Xreaddirparams;
533
534 # define _XReaddir(d,p) \
535  ( (_Xos_processLock),                                           \
536    (((p).result = readdir((d))) ?                                \
537     (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
538      ((p).result = &(p).dir_entry), 0) :                         \
539     0),                                                          \
540    (_Xos_processUnlock),                                         \
541    (p).result )
542
543 #else
544 typedef struct {
545   struct dirent *result;
546   struct dirent dir_entry;
547 # ifdef _POSIX_PATH_MAX
548   char buf[_POSIX_PATH_MAX];
549 # elif defined(NAME_MAX)
550   char buf[NAME_MAX];
551 # else
552   char buf[255];
553 # endif
554 } _Xreaddirparams;
555
556 # if defined(AIXV3) || defined(AIXV4) || defined(_POSIX_THREAD_SAFE_FUNCTIONS)
557 /* AIX defines the draft POSIX symbol, but uses the final API. */
558 /* POSIX final API, returns (int)0 on success. */
559 #  if defined(__osf__)
560 /* OSF/1 V4.0 <dirent.h> doesn't declare _Preaddir_r, breaking under C++. */
561 extern int _Preaddir_r(DIR *, struct dirent *, struct dirent **);
562 #  endif
563 #  define _XReaddir(d,p)                                                \
564     (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
565 # elif defined(_POSIX_REENTRANT_FUNCTIONS) && defined(__osf__)
566 /*
567  * OSF/1 V3.2 readdir_r() will SEGV if the main program is not
568  * explicitly linked with -lc_r.  The library REQUIREDLIBS don't help.
569  * Assume that if threads have been initialized we're linked properly.
570  */
571 #  define _XReaddir(d,p)                                                \
572  ( (_Xos_isThreadInitialized) ?                                         \
573    (readdir_r((d), &((p).dir_entry)) ? NULL : &((p).dir_entry)) :       \
574    ((_Xos_processLock),                                                 \
575     (((p).result = readdir((d))) ?                                      \
576      (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen),       \
577       ((p).result = &(p).dir_entry), 0) :                               \
578      0),                                                                \
579     (_Xos_processUnlock),                                               \
580     (p).result) )
581 # elif defined(_POSIX_REENTRANT_FUNCTIONS)
582 /* POSIX draft API, returns (int)0 on success. */
583 #  define _XReaddir(d,p)        \
584     (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
585 # elif defined(SVR4)
586 /* Pre-POSIX API, returns non-NULL on success. */
587 #  define _XReaddir(d,p)        (readdir_r((d), &(p).dir_entry))
588 # else
589 /* We have no idea what is going on.  Fake it all using process locks. */
590 #  define _XReaddir(d,p)        \
591     ( (_Xos_processLock),                                               \
592       (((p).result = readdir((d))) ?                                    \
593        (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen),     \
594         ((p).result = &(p).dir_entry), 0) :                             \
595        0),                                                              \
596       (_Xos_processUnlock),                                             \
597       (p).result )
598 # endif
599 #endif /* X_INCLUDE_DIRENT_H */
600
601 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
602 # define _XOS_INCLUDED_DIRENT_H
603 #endif
604
605
606 /***** <unistd.h> wrappers *****/
607
608 /*
609  * Effective prototypes for <unistd.h> wrappers:
610  *
611  * #define X_INCLUDE_UNISTD_H
612  * #define XOS_USE_..._LOCKING
613  * #include <X11/Xos_r.h>
614  * 
615  * typedef ... _Xgetloginparams;
616  * typedef ... _Xttynameparams;
617  *
618  * char *_XGetlogin(_Xgetloginparams);
619  * char *_XTtyname(int, _Xttynameparams);
620  */
621
622 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
623 /* <unistd.h> already included by <X11/Xos.h> */
624 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
625 #  define XOS_USE_MTSAFE_UNISTDAPI 1
626 # endif
627 #endif
628
629 #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
630 /* Do nothing. */
631
632 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
633 /* Use regular, unsafe API. */
634 typedef int _Xgetloginparams;   /* dummy */
635 typedef int _Xttynameparams;    /* dummy */
636 # define _XGetlogin(p)  getlogin()
637 # define _XTtyname(f)   ttyname((f))
638
639 #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
640 /* Systems with thread support but no _r API. */
641 typedef struct {
642   char *result;
643 # if defined(MAXLOGNAME)
644   char buf[MAXLOGNAME];
645 # elif defined(LOGIN_NAME_MAX)
646   char buf[LOGIN_NAME_MAX];
647 # else
648   char buf[64];
649 # endif
650 } _Xgetloginparams;
651 typedef struct {
652   char *result;
653 # ifdef TTY_NAME_MAX
654   char buf[TTY_NAME_MAX];
655 # elif defined(_POSIX_TTY_NAME_MAX)
656   char buf[_POSIX_TTY_NAME_MAX];
657 # elif defined(_POSIX_PATH_MAX)
658   char buf[_POSIX_PATH_MAX];
659 # else
660   char buf[256];
661 # endif
662 } _Xttynameparams;
663
664 # define _XGetlogin(p) \
665  ( (_Xos_processLock), \
666    (((p).result = getlogin()) ? \
667     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
668      ((p).buf[sizeof((p).buf)-1] = '\0'), \
669      ((p).result = (p).buf), 0) : 0), \
670    (_Xos_processUnlock), \
671    (p).result )
672 #define _XTtyname(f,p) \
673  ( (_Xos_processLock), \
674    (((p).result = ttyname(f)) ? \
675     (strncpy((p).buf, (p).result, sizeof((p).buf)), \
676      ((p).buf[sizeof((p).buf)-1] = '\0'), \
677      ((p).result = (p).buf), 0) : 0), \
678    (_Xos_processUnlock), \
679    (p).result )
680
681 #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
682 /* POSIX API.
683  *
684  * extern int getlogin_r(char *, size_t);
685  * extern int ttyname_r(int, char *, size_t);
686  */
687 typedef struct {
688 # if defined(MAXLOGNAME)
689   char buf[MAXLOGNAME];
690 # elif defined(LOGIN_NAME_MAX)
691   char buf[LOGIN_NAME_MAX];
692 # else
693   char buf[64];
694 # endif
695 } _Xgetloginparams;
696 typedef struct {
697 # ifdef TTY_NAME_MAX
698   char buf[TTY_NAME_MAX];
699 # elif defined(_POSIX_TTY_NAME_MAX)
700   char buf[_POSIX_TTY_NAME_MAX];
701 # elif defined(_POSIX_PATH_MAX)
702   char buf[_POSIX_PATH_MAX];
703 # else
704   char buf[256];
705 # endif
706 } _Xttynameparams;
707
708 # define _XGetlogin(p)  (getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
709 # define _XTtyname(f,p) \
710         (ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
711
712 #else
713 /* Pre-POSIX API.
714  *
715  * extern char *getlogin_r(char *, size_t);
716  * extern char *ttyname_r(int, char *, size_t);
717  */
718 typedef struct {
719 # if defined(MAXLOGNAME)
720   char buf[MAXLOGNAME];
721 # elif defined(LOGIN_NAME_MAX)
722   char buf[LOGIN_NAME_MAX];
723 # else
724   char buf[64];
725 # endif
726 } _Xgetloginparams;
727 typedef struct {
728 # ifdef TTY_NAME_MAX
729   char buf[TTY_NAME_MAX];
730 # elif defined(_POSIX_TTY_NAME_MAX)
731   char buf[_POSIX_TTY_NAME_MAX];
732 # elif defined(_POSIX_PATH_MAX)
733   char buf[_POSIX_PATH_MAX];
734 # else
735   char buf[256];
736 # endif
737 } _Xttynameparams;
738
739 # define _XGetlogin(p)  getlogin_r((p).buf, sizeof((p).buf))
740 # define _XTtyname(f,p) ttyname_r((f), (p).buf, sizeof((p).buf))
741 #endif /* X_INCLUDE_UNISTD_H */
742
743 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
744 # define _XOS_INCLUDED_UNISTD_H
745 #endif
746
747
748 /***** <string.h> wrappers *****/
749
750 /*
751  * Effective prototypes for <string.h> wrappers:
752  *
753  * #define X_INCLUDE_STRING_H
754  * #define XOS_USE_..._LOCKING
755  * #include <X11/Xos_r.h>
756  *
757  * typedef ... _Xstrtokparams;
758  *
759  * char *_XStrtok(char *, const char*, _Xstrtokparams);
760  */
761
762 #if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
763 /* <string.h> has already been included by <X11/Xos.h> */
764 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
765 #  define XOS_USE_MTSAFE_STRINGAPI 1
766 # endif
767 #endif
768
769 #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
770 /* Do nothing. */
771
772 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
773 /* Use regular, unsafe API. */
774 typedef int _Xstrtokparams;     /* dummy */
775 # define _XStrtok(s1,s2,p)      strtok((s1),(s2))
776
777 #elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
778 /* Systems with thread support but no _r API. */
779 typedef char *_Xstrtokparams;
780 # define _XStrtok(s1,s2,p) \
781  ( (_Xos_processLock), \
782    ((p) = strtok((s1),(s2))), \
783    (_Xos_processUnlock), \
784    (p) )
785
786 #else
787 /* POSIX or pre-POSIX API. */
788 typedef char * _Xstrtokparams;
789 # define _XStrtok(s1,s2,p)      strtok_r((s1),(s2),&(p))
790 #endif /* X_INCLUDE_STRING_H */
791
792
793 /***** <time.h> wrappers *****/
794
795 /*
796  * Effective prototypes for <time.h> wrappers:
797  *
798  * #define X_INCLUDE_TIME_H
799  * #define XOS_USE_..._LOCKING
800  * #include <X11/Xos_r.h>
801  *
802  * typedef ... _Xatimeparams;
803  * typedef ... _Xctimeparams;
804  * typedef ... _Xgtimeparams;
805  * typedef ... _Xltimeparams;
806  *
807  * char *_XAsctime(const struct tm *, _Xatimeparams);
808  * char *_XCtime(const time_t *, _Xctimeparams);
809  * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
810  * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
811  */
812
813 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
814 # include <time.h>
815 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
816 #  define XOS_USE_MTSAFE_TIMEAPI 1
817 # endif
818 #endif
819
820 #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
821 /* Do nothing. */
822
823 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
824 /* Use regular, unsafe API. */
825 typedef int _Xatimeparams;      /* dummy */
826 # define _XAsctime(t,p)         asctime((t))
827 typedef int _Xctimeparams;      /* dummy */
828 # define _XCtime(t,p)           ctime((t))
829 typedef int _Xgtimeparams;      /* dummy */
830 # define _XGmtime(t,p)          gmtime((t))
831 typedef int _Xltimeparams;      /* dummy */
832 # define _XLocaltime(t,p)       localtime((t))
833
834 #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
835 /* Systems with thread support but no _r API. */
836 typedef struct {
837 # ifdef TIMELEN
838   char buf[TIMELEN];
839 # else
840   char buf[26];
841 # endif
842   char *result;
843 } _Xctimeparams, _Xatimeparams;
844 typedef struct {
845   struct tm buf;
846   struct tm *result;
847 } _Xgtimeparams, _Xltimeparams;
848 # define _XAsctime(t,p) \
849  ( (_Xos_processLock), \
850    (((p).result = asctime((t))) ? \
851     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
852     0), \
853    (_Xos_processUnlock), \
854    (p).result )
855 # define _XCtime(t,p) \
856  ( (_Xos_processLock), \
857    (((p).result = ctime((t))) ? \
858     (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
859     0), \
860    (_Xos_processUnlock), \
861    (p).result )
862 # define _XGmtime(t,p) \
863  ( (_Xos_processLock), \
864    (((p).result = gmtime(t)) ? \
865     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
866     0), \
867    (_Xos_processUnlock), \
868    (p).result )
869 # define _XLocaltime(t,p) \
870  ( (_Xos_processLock), \
871    (((p).result = localtime(t)) ? \
872     (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
873     0), \
874    (_Xos_processUnlock), \
875    (p).result )
876
877 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(__osf__) || defined(hpV4))
878 /* Returns (int)0 on success.  OSF/1 v3.2, HP/UX 10
879  *
880  * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
881  * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
882  * extern int gmtime_r(const time_t *timer, struct tm *result);
883  * extern int localtime_r(const time_t *timer, struct tm *result);
884  */
885 # ifdef TIMELEN
886 typedef char _Xatimeparams[TIMELEN];
887 typedef char _Xctimeparams[TIMELEN];
888 # else
889 typedef char _Xatimeparams[26];
890 typedef char _Xctimeparams[26];
891 # endif
892 typedef struct tm _Xgtimeparams;
893 typedef struct tm _Xltimeparams;
894 # define _XAsctime(t,p)         (asctime_r((t),(p),sizeof((p))) ? NULL : (p))
895 # define _XCtime(t,p)           (ctime_r((t),(p),sizeof((p))) ? NULL : (p))
896 # define _XGmtime(t,p)          (gmtime_r((t),&(p)) ? NULL : &(p))
897 # define _XLocaltime(t,p)       (localtime_r((t),&(p)) ? NULL : &(p))
898
899 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(sun)
900 /* Returns NULL on failure.  Solaris 2.5
901  *
902  * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
903  * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
904  * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
905  * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
906  */
907 # ifdef TIMELEN
908 typedef char _Xatimeparams[TIMELEN];
909 typedef char _Xctimeparams[TIMELEN];
910 # else
911 typedef char _Xatimeparams[26];
912 typedef char _Xctimeparams[26];
913 # endif
914 typedef struct tm _Xgtimeparams;
915 typedef struct tm _Xltimeparams;
916 # define _XAsctime(t,p)         asctime_r((t),(p),sizeof((p)))
917 # define _XCtime(t,p)           ctime_r((t),(p),sizeof((p)))
918 # define _XGmtime(t,p)          gmtime_r((t),&(p))
919 # define _XLocaltime(t,p)       localtime_r((t),&(p))
920
921 #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
922 /* POSIX final API.  OSF/1 v4.0, AIX, etc.
923  *
924  * extern char *asctime_r(const struct tm *timeptr, char *buffer);
925  * extern char *ctime_r(const time_t *timer, char *buffer);
926  * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
927  * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
928  */
929 # if defined(__osf__)
930 /* OSF/1 V4.0 <time.h> doesn't declare the _P routines, breaking under C++. */
931 extern char *_Pasctime_r(const struct tm *, char *);
932 extern char *_Pctime_r(const time_t *, char *);
933 extern struct tm *_Plocaltime_r(const time_t *, struct tm *);
934 # endif
935 # ifdef TIMELEN
936 typedef char _Xatimeparams[TIMELEN];
937 typedef char _Xctimeparams[TIMELEN];
938 # else
939 typedef char _Xatimeparams[26];
940 typedef char _Xctimeparams[26];
941 # endif
942 typedef struct tm _Xgtimeparams;
943 typedef struct tm _Xltimeparams;
944 # define _XAsctime(t,p)         asctime_r((t),(p))
945 # define _XCtime(t,p)           ctime_r((t),(p))
946 # define _XGmtime(t,p)          gmtime_r((t),&(p))
947 # define _XLocaltime(t,p)       localtime_r((t),&(p))
948 #endif /* X_INCLUDE_TIME_H */
949
950 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
951 # define _XOS_INCLUDED_TIME_H
952 #endif
953
954
955 /***** <grp.h> wrappers *****/
956
957 /*
958  * Effective prototypes for <grp.h> wrappers:
959  *
960  * NOTE: On systems lacking appropriate _r functions Getgrgid() and
961  *      Getgrnam() do NOT copy the list of group members!
962  *
963  * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
964  * are not included in POSIX.
965  *
966  * #define X_INCLUDE_GRP_H
967  * #define XOS_USE_..._LOCKING
968  * #include <X11/Xos_r.h>
969  *
970  * typedef ... _Xgetgrparams;
971  *
972  * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
973  * struct group *_XGetgrnam(const char *, _Xgetgrparams);
974  */
975
976 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
977 # include <grp.h>
978 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
979 #  define XOS_USE_MTSAFE_GRPAPI 1
980 # endif
981 #endif
982
983 #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
984 /* Do nothing. */
985
986 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
987 /* Use regular, unsafe API. */
988 typedef int _Xgetgrparams;      /* dummy */
989 #define _XGetgrgid(g,p) getgrgid((g))
990 #define _XGetgrnam(n,p) getgrnam((n))
991
992 #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
993 /* Systems with thread support but no _r API.  UnixWare 2.0. */
994 typedef struct {
995   struct group grp;
996 #ifdef LINE_MAX
997   char buf[LINE_MAX];   /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
998 #else
999   char buf[1024];       /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1000 #endif
1001   struct group *pgrp;
1002   size_t len;
1003 } _Xgetgrparams;
1004 #ifdef SVR4
1005 /* Copy the gr_passwd field too. */
1006 # define _Xgrp_copyGroup(p) \
1007  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1008    ((p).grp.gr_name = (p).buf), \
1009    ((p).len = strlen((p).pgrp->gr_name)), \
1010    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1011    ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
1012    ((p).pgrp = &(p).grp), \
1013    0 )
1014 #else
1015 # define _Xgrp_copyGroup(p) \
1016  ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1017    ((p).grp.gr_name = (p).buf), \
1018    strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1019    ((p).pgrp = &(p).grp), \
1020    0 )
1021 #endif
1022 #define _XGetgrgid(g,p) \
1023  ( (_Xos_processLock), \
1024    (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
1025    (_Xos_processUnlock), \
1026    (p).pgrp )
1027 #define _XGetgrnam(n,p) \
1028  ( (_Xos_processLock), \
1029    (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
1030    (_Xos_processUnlock), \
1031    (p).pgrp )
1032
1033 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(sun) || defined(__osf__))
1034 /* Non-POSIX API.  Solaris, DEC v3.2.
1035  *
1036  * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
1037  * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
1038  */
1039 typedef struct {
1040   struct group grp;
1041 #ifdef LINE_MAX
1042   char buf[LINE_MAX];   /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1043 #else
1044   char buf[1024];       /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1045 #endif
1046 } _Xgetgrparams;
1047 #define _XGetgrgid(g,p) getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
1048 #define _XGetgrnam(n,p) getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
1049
1050 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1051 /* Non-POSIX API.  HP/UX 10, AIX 4.
1052  *
1053  * extern int getgrgid_r(gid_t, struct group *, char *, int);
1054  * extern int getgrnam_r(const char *, struct group *, char *, int);
1055  */
1056 typedef struct {
1057   struct group grp;
1058 #ifdef LINE_MAX
1059   char buf[LINE_MAX];   /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1060 #else
1061   char buf[1024];       /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1062 #endif
1063 } _Xgetgrparams;
1064 #define _XGetgrgid(g,p) \
1065  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1066 #define _XGetgrnam(n,p) \
1067  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1068
1069 #else
1070 /* POSIX final API.  DEC v4.0, IRIX 6.2.
1071  *
1072  * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
1073  * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
1074  */
1075 # if defined(__osf__)
1076 /* OSF/1 V4.0 <grp.h> doesn't declare the _P routines, breaking under C++. */
1077 extern int _Pgetgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
1078 extern int _Pgetgrnam_r(const char *, struct group *, char *, size_t, struct group **);
1079 # endif
1080 typedef struct {
1081   struct group grp;
1082 #ifdef LINE_MAX
1083   char buf[LINE_MAX];   /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1084 #else
1085   char buf[1024];       /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1086 #endif
1087   struct group *result;
1088 } _Xgetgrparams;
1089
1090 #define _XGetgrgid(g,p) \
1091  ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1092    NULL : (p).result))
1093 #define _XGetgrnam(n,p) \
1094  ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1095    NULL : (p).result))
1096 #endif
1097
1098 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
1099 # define _XOS_INCLUDED_GRP_H
1100 #endif
1101
1102
1103 #ifdef __cplusplus
1104 }  /* Close scope of 'extern "C"' declaration which encloses file. */
1105 #endif