added new XOrg folders/makefiles
[openwrt/svn-archive/archive.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