Category reorganization
[packages.git] / XOrg / headers / native / src / X11 / Xos_r.h
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.6 2006/04/20 01:24:25 alanc 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