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 $ */
4 Copyright 1996, 1998 The Open Group
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
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
26 /* $XFree86: xc/include/Xos_r.h,v 1.18tsi Exp $ */
29 * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
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.
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.
51 * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
52 * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
55 * NOTE: On systems lacking appropriate _r functions Getgrgid() and
56 * Getgrnam() do NOT copy the list of group members!
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.
67 * This header has several parts. Search for "Effective prototypes"
68 * to locate the beginning of a section.
71 /* This header can be included multiple times with different defines! */
76 # include <X11/Xfuncs.h>
82 # define _POSIX_SOURCE
87 # define X_LINE_MAX 2048
89 # define X_LINE_MAX LINE_MAX
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
;
105 # ifndef _Xos_isThreadInitialized
106 # define _Xos_isThreadInitialized (_Xglobal_lock)
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 */
116 extern void (*_XUnlockMutex_fn
)(
117 # if NeedFunctionPrototypes
118 LockInfoPtr
/* lock */, char * /* file */, int /* line */
122 # ifndef _Xos_processLock
123 # define _Xos_processLock \
124 (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
126 # ifndef _Xos_processUnlock
127 # define _Xos_processUnlock \
128 (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
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 */
138 extern void (*_XUnlockMutex_fn
)(
139 # if NeedFunctionPrototypes
140 LockInfoPtr
/* lock */
144 # ifndef _Xos_processLock
145 # define _Xos_processLock \
146 (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
148 # ifndef _Xos_processUnlock
149 # define _Xos_processUnlock \
150 (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
153 # elif defined(XOS_USE_XT_LOCKING)
154 # ifndef _XtThreadsI_h
155 extern void (*_XtProcessLock
)(void);
157 # ifndef _XtintrinsicP_h
158 # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
159 extern void XtProcessLock(
160 # if NeedFunctionPrototypes
164 extern void XtProcessUnlock(
165 # if NeedFunctionPrototypes
170 # ifndef _Xos_isThreadInitialized
171 # define _Xos_isThreadInitialized _XtProcessLock
173 # ifndef _Xos_processLock
174 # define _Xos_processLock XtProcessLock()
176 # ifndef _Xos_processUnlock
177 # define _Xos_processUnlock XtProcessUnlock()
179 # elif defined(XOS_USE_NO_LOCKING)
180 # ifndef _Xos_isThreadInitialized
181 # define _Xos_isThreadInitialized 0
183 # ifndef _Xos_processLock
184 # define _Xos_processLock 0
186 # ifndef _Xos_processUnlock
187 # define _Xos_processUnlock 0
191 #endif /* !defined WIN32 */
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.
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
204 * LynxOS 3.1 defines _POSIX_THREAD_SAFE_FUNCTIONS but
205 * getpwuid_r has different semantics than defined by POSIX
207 #if defined(Lynx) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
208 # undef _POSIX_THREAD_SAFE_FUNCTIONS
212 /***** <pwd.h> wrappers *****/
215 * Effective prototypes for <pwd.h> wrappers:
217 * #define X_INCLUDE_PWD_H
218 * #define XOS_USE_..._LOCKING
219 * #include <X11/Xos_r.h>
221 * typedef ... _Xgetpwparams;
223 * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
224 * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
227 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
229 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
230 # define XOS_USE_MTSAFE_PWDAPI 1
234 #undef X_NEEDS_PWPARAMS
235 #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
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();
243 typedef int _Xgetpwparams
; /* dummy */
244 # define _XGetpwuid(u,p) getpwuid((u))
245 # define _XGetpwnam(u,p) getpwnam((u))
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
258 * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
262 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
263 defined(__APPLE__) || defined(__DragonFly__)
264 static __inline__
void _Xpw_copyPasswd(_Xgetpwparams p
)
266 memcpy(&(p
).pws
, (p
).pwp
, sizeof(struct passwd
));
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
);
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
);
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
);
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
);
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
);
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
);
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), \
322 # define _XGetpwuid(u,p) \
323 ( (_Xos_processLock), \
324 (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
325 (_Xos_processUnlock), \
327 # define _XGetpwnam(u,p) \
328 ( (_Xos_processLock), \
329 (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
330 (_Xos_processUnlock), \
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
338 char pwbuf
[X_LINE_MAX
];
340 # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4) || defined(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)
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)
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)
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
**);
366 # define X_NEEDS_PWPARAMS
369 char pwbuf
[X_LINE_MAX
];
372 typedef int _Xgetpwret
;
373 # define _XGetpwuid(u,p) \
374 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
376 # define _XGetpwnam(u,p) \
377 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
379 #endif /* X_INCLUDE_PWD_H */
381 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
382 # define _XOS_INCLUDED_PWD_H
386 /***** <netdb.h> wrappers *****/
389 * Effective prototypes for <netdb.h> wrappers:
391 * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
392 * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
395 * #define X_INCLUDE_NETDB_H
396 * #define XOS_USE_..._LOCKING
397 * #include <X11/Xos_r.h>
399 * typedef ... _Xgethostbynameparams;
400 * typedef ... _Xgetservbynameparams;
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);
409 #undef XTHREADS_NEEDS_BYNAMEPARAMS
410 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
413 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
414 # define XOS_USE_MTSAFE_NETDBAPI 1
418 #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
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))
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! */
433 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
434 #include <sys/param.h>
439 char h_name
[MAXHOSTNAMELEN
];
440 struct hostent
*hptr
;
441 } _Xgethostbynameparams
;
446 struct servent
*sptr
;
447 } _Xgetservbynameparams
;
449 # define XTHREADS_NEEDS_BYNAMEPARAMS
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), \
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), \
465 # define _XGethostbyname(h,hp) \
466 ((_Xos_processLock), \
467 (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
468 (_Xos_processUnlock), \
470 # define _XGethostbyaddr(a,al,t,hp) \
471 ((_Xos_processLock), \
472 (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
473 (_Xos_processUnlock), \
475 # define _XGetservbyname(s,p,sp) \
476 ((_Xos_processLock), \
477 (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
478 (_Xos_processUnlock), \
481 #elif defined(XUSE_NETDB_R_API)
483 * POSIX does not specify _r equivalents for <netdb.h> API, but some
484 * vendors provide them anyway. Use them only when explicitly asked.
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
493 # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
494 # define X_POSIX_THREAD_SAFE_FUNCTIONS 1
497 # define XTHREADS_NEEDS_BYNAMEPARAMS
499 # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
502 char hbuf
[X_LINE_MAX
];
504 } _Xgethostbynameparams
;
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))
518 struct hostent_data hdata
;
519 } _Xgethostbynameparams
;
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) )
534 # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
535 # undef X_POSIX_THREAD_SAFE_FUNCTIONS
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 */
547 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
548 # define _XOS_INCLUDED_NETDB_H
552 /***** <dirent.h> wrappers *****/
555 * Effective prototypes for <dirent.h> wrappers:
557 * #define X_INCLUDE_DIRENT_H
558 * #define XOS_USE_..._LOCKING
559 * #include <X11/Xos_r.h>
561 * typedef ... _Xreaddirparams;
563 * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
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)
571 # include <sys/dir.h>
573 # define dirent direct
576 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
577 # define XOS_USE_MTSAFE_DIRENTAPI 1
581 #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
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)
589 #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
590 /* Systems with thread support but no _r API. */
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)
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) : \
609 (_Xos_processUnlock), \
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)
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
**);
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__)
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.
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) : \
649 (_Xos_processUnlock), \
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))
656 /* Pre-POSIX API, returns non-NULL on success. */
657 # define _XReaddir(d,p) (readdir_r((d), &(p).dir_entry))
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) : \
666 (_Xos_processUnlock), \
669 #endif /* X_INCLUDE_DIRENT_H */
671 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
672 # define _XOS_INCLUDED_DIRENT_H
676 /***** <unistd.h> wrappers *****/
679 * Effective prototypes for <unistd.h> wrappers:
681 * #define X_INCLUDE_UNISTD_H
682 * #define XOS_USE_..._LOCKING
683 * #include <X11/Xos_r.h>
685 * typedef ... _Xgetloginparams;
686 * typedef ... _Xttynameparams;
688 * char *_XGetlogin(_Xgetloginparams);
689 * char *_XTtyname(int, _Xttynameparams);
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
699 #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
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))
709 #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
710 /* Systems with thread support but no _r API. */
713 # if defined(MAXLOGNAME)
714 char buf
[MAXLOGNAME
];
715 # elif defined(LOGIN_NAME_MAX)
716 char buf
[LOGIN_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
];
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), \
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), \
751 #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
754 * extern int getlogin_r(char *, size_t);
755 * extern int ttyname_r(int, char *, size_t);
758 # if defined(MAXLOGNAME)
759 char buf
[MAXLOGNAME
];
760 # elif defined(LOGIN_NAME_MAX)
761 char buf
[LOGIN_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
];
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)
785 * extern char *getlogin_r(char *, size_t);
786 * extern char *ttyname_r(int, char *, size_t);
789 # if defined(MAXLOGNAME)
790 char buf
[MAXLOGNAME
];
791 # elif defined(LOGIN_NAME_MAX)
792 char buf
[LOGIN_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
];
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 */
813 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
814 # define _XOS_INCLUDED_UNISTD_H
818 /***** <string.h> wrappers *****/
821 * Effective prototypes for <string.h> wrappers:
823 * #define X_INCLUDE_STRING_H
824 * #define XOS_USE_..._LOCKING
825 * #include <X11/Xos_r.h>
827 * typedef ... _Xstrtokparams;
829 * char *_XStrtok(char *, const char*, _Xstrtokparams);
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
839 #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
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)) )
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), \
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 */
864 /***** <time.h> wrappers *****/
867 * Effective prototypes for <time.h> wrappers:
869 * #define X_INCLUDE_TIME_H
870 * #define XOS_USE_..._LOCKING
871 * #include <X11/Xos_r.h>
873 * typedef ... _Xatimeparams;
874 * typedef ... _Xctimeparams;
875 * typedef ... _Xgtimeparams;
876 * typedef ... _Xltimeparams;
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);
884 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
886 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
887 # define XOS_USE_MTSAFE_TIMEAPI 1
891 #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
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))
905 #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
906 /* Systems with thread support but no _r API. */
914 } _Xctimeparams
, _Xatimeparams
;
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) : \
924 (_Xos_processUnlock), \
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) : \
931 (_Xos_processUnlock), \
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) : \
938 (_Xos_processUnlock), \
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) : \
945 (_Xos_processUnlock), \
948 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(__osf__) || defined(hpV4))
949 /* Returns (int)0 on success. OSF/1 v3.2, HP/UX 10
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);
957 typedef char _Xatimeparams
[TIMELEN
];
958 typedef char _Xctimeparams
[TIMELEN
];
960 typedef char _Xatimeparams
[26];
961 typedef char _Xctimeparams
[26];
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))
970 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(sun)
971 /* Returns NULL on failure. Solaris 2.5
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);
979 typedef char _Xatimeparams
[TIMELEN
];
980 typedef char _Xctimeparams
[TIMELEN
];
982 typedef char _Xatimeparams
[26];
983 typedef char _Xctimeparams
[26];
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))
992 #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
993 /* POSIX final API. OSF/1 v4.0, AIX, etc.
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);
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
*);
1007 typedef char _Xatimeparams
[TIMELEN
];
1008 typedef char _Xctimeparams
[TIMELEN
];
1010 typedef char _Xatimeparams
[26];
1011 typedef char _Xctimeparams
[26];
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 */
1021 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
1022 # define _XOS_INCLUDED_TIME_H
1026 /***** <grp.h> wrappers *****/
1029 * Effective prototypes for <grp.h> wrappers:
1031 * NOTE: On systems lacking appropriate _r functions Getgrgid() and
1032 * Getgrnam() do NOT copy the list of group members!
1034 * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
1035 * are not included in POSIX.
1037 * #define X_INCLUDE_GRP_H
1038 * #define XOS_USE_..._LOCKING
1039 * #include <X11/Xos_r.h>
1041 * typedef ... _Xgetgrparams;
1043 * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
1044 * struct group *_XGetgrnam(const char *, _Xgetgrparams);
1047 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
1049 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
1050 # define XOS_USE_MTSAFE_GRPAPI 1
1054 #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
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))
1063 #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
1064 /* Systems with thread support but no _r API. UnixWare 2.0. */
1067 char buf
[X_LINE_MAX
]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
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), \
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), \
1089 #define _XGetgrgid(g,p) \
1090 ( (_Xos_processLock), \
1091 (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
1092 (_Xos_processUnlock), \
1094 #define _XGetgrnam(n,p) \
1095 ( (_Xos_processLock), \
1096 (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
1097 (_Xos_processUnlock), \
1100 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (defined(sun) || defined(__osf__))
1101 /* Non-POSIX API. Solaris, DEC v3.2.
1103 * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
1104 * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
1108 char buf
[X_LINE_MAX
]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
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))
1113 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1114 /* Non-POSIX API. HP/UX 10, AIX 4.
1116 * extern int getgrgid_r(gid_t, struct group *, char *, int);
1117 * extern int getgrnam_r(const char *, struct group *, char *, int);
1121 char buf
[X_LINE_MAX
]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
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))
1129 /* POSIX final API. DEC v4.0, IRIX 6.2.
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 **);
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
**);
1141 char buf
[X_LINE_MAX
]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1142 struct group
*result
;
1145 #define _XGetgrgid(g,p) \
1146 ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1148 #define _XGetgrnam(n,p) \
1149 ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1153 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
1154 # define _XOS_INCLUDED_GRP_H
1159 } /* Close scope of 'extern "C"' declaration which encloses file. */