2 Copyright 1996, 1998 The Open Group
4 Permission to use, copy, modify, distribute, and sell this software and its
5 documentation for any purpose is hereby granted without fee, provided that
6 the above copyright notice appear in all copies and that both that
7 copyright notice and this permission notice appear in supporting
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 Except as contained in this notice, the name of The Open Group shall not be
21 used in advertising or otherwise to promote the sale, use or other dealings
22 in this Software without prior written authorization from The Open Group.
26 * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
28 * Use this file in MT-safe code where you would have included
29 * <dirent.h> for readdir()
30 * <grp.h> for getgrgid() or getgrnam()
31 * <netdb.h> for gethostbyname(), gethostbyaddr(), or getservbyname()
32 * <pwd.h> for getpwnam() or getpwuid()
33 * <string.h> for strtok()
34 * <time.h> for asctime(), ctime(), localtime(), or gmtime()
35 * <unistd.h> for getlogin() or ttyname()
36 * or their thread-safe analogs.
38 * If you are on a platform that defines XTHREADS but does not have
39 * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
40 * and _Xos_processUnlock macros before including this header.
42 * For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined
43 * to obtain either Xlib-only or Xt-based versions of these macros. These
44 * macros won't result in truly thread-safe calls, but they are better than
45 * nothing. If you do not want locking in this situation define
48 * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
49 * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
52 * NOTE: On systems lacking appropriate _r functions Getgrgid() and
53 * Getgrnam() do NOT copy the list of group members!
55 * This header is nominally intended to simplify porting X11, Motif, and
56 * CDE; it may be useful to other people too. The structure below is
57 * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
58 * went through lots of drafts, and some vendors shipped systems based
59 * on draft API that were changed later. Unfortunately POSIX did not
60 * provide a feature-test macro for distinguishing each of the drafts.
64 * This header has several parts. Search for "Effective prototypes"
65 * to locate the beginning of a section.
68 /* This header can be included multiple times with different defines! */
73 # include <X11/Xfuncs.h>
79 # define _POSIX_SOURCE
84 # define X_LINE_MAX 2048
86 # define X_LINE_MAX LINE_MAX
97 # if defined(XOS_USE_XLIB_LOCKING)
98 # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
99 typedef struct _LockInfoRec *LockInfoPtr;
100 extern LockInfoPtr _Xglobal_lock;
102 # ifndef _Xos_isThreadInitialized
103 # define _Xos_isThreadInitialized (_Xglobal_lock)
105 # if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
106 # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
107 # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
108 extern void (*_XLockMutex_fn)(
109 # if NeedFunctionPrototypes
110 LockInfoPtr /* lock */, char * /* file */, int /* line */
113 extern void (*_XUnlockMutex_fn)(
114 # if NeedFunctionPrototypes
115 LockInfoPtr /* lock */, char * /* file */, int /* line */
119 # ifndef _Xos_processLock
120 # define _Xos_processLock \
121 (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
123 # ifndef _Xos_processUnlock
124 # define _Xos_processUnlock \
125 (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
128 # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
129 # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
130 extern void (*_XLockMutex_fn)(
131 # if NeedFunctionPrototypes
132 LockInfoPtr /* lock */
135 extern void (*_XUnlockMutex_fn)(
136 # if NeedFunctionPrototypes
137 LockInfoPtr /* lock */
141 # ifndef _Xos_processLock
142 # define _Xos_processLock \
143 (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
145 # ifndef _Xos_processUnlock
146 # define _Xos_processUnlock \
147 (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
150 # elif defined(XOS_USE_XT_LOCKING)
151 # ifndef _XtThreadsI_h
152 extern void (*_XtProcessLock)(void);
154 # ifndef _XtintrinsicP_h
155 # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
156 extern void XtProcessLock(
157 # if NeedFunctionPrototypes
161 extern void XtProcessUnlock(
162 # if NeedFunctionPrototypes
167 # ifndef _Xos_isThreadInitialized
168 # define _Xos_isThreadInitialized _XtProcessLock
170 # ifndef _Xos_processLock
171 # define _Xos_processLock XtProcessLock()
173 # ifndef _Xos_processUnlock
174 # define _Xos_processUnlock XtProcessUnlock()
176 # elif defined(XOS_USE_NO_LOCKING)
177 # ifndef _Xos_isThreadInitialized
178 # define _Xos_isThreadInitialized 0
180 # ifndef _Xos_processLock
181 # define _Xos_processLock 0
183 # ifndef _Xos_processUnlock
184 # define _Xos_processUnlock 0
188 #endif /* !defined WIN32 */
191 * Solaris defines the POSIX thread-safe feature test macro, but
192 * uses the older SVR4 thread-safe functions unless the POSIX ones
193 * are specifically requested. Fix the feature test macro.
195 #if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
196 (_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS)
197 # undef _POSIX_THREAD_SAFE_FUNCTIONS
200 /***** <pwd.h> wrappers *****/
203 * Effective prototypes for <pwd.h> wrappers:
205 * #define X_INCLUDE_PWD_H
206 * #define XOS_USE_..._LOCKING
207 * #include <X11/Xos_r.h>
209 * typedef ... _Xgetpwparams;
211 * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
212 * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
215 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
217 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
218 # define XOS_USE_MTSAFE_PWDAPI 1
222 #undef X_NEEDS_PWPARAMS
223 #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
226 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
227 /* Use regular, unsafe API. */
228 # if defined(X_NOT_POSIX) && !defined(__i386__) && !defined(SYSV)
229 extern struct passwd *getpwuid(), *getpwnam();
231 typedef int _Xgetpwparams; /* dummy */
232 # define _XGetpwuid(u,p) getpwuid((u))
233 # define _XGetpwnam(u,p) getpwnam((u))
235 #elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
236 /* UnixWare 2.0, or other systems with thread support but no _r API. */
237 # define X_NEEDS_PWPARAMS
246 * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
250 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
251 defined(__APPLE__) || defined(__DragonFly__)
252 static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p)
254 memcpy(&(p).pws, (p).pwp, sizeof(struct passwd));
256 (p).pws.pw_name = (p).pwbuf;
257 (p).len = strlen((p).pwp->pw_name);
258 strcpy((p).pws.pw_name, (p).pwp->pw_name);
260 (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1;
261 (p).len = strlen((p).pwp->pw_passwd);
262 strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd);
264 (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1;
265 (p).len = strlen((p).pwp->pw_class);
266 strcpy((p).pws.pw_class, (p).pwp->pw_class);
268 (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1;
269 (p).len = strlen((p).pwp->pw_gecos);
270 strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos);
272 (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1;
273 (p).len = strlen((p).pwp->pw_dir);
274 strcpy((p).pws.pw_dir, (p).pwp->pw_dir);
276 (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1;
277 (p).len = strlen((p).pwp->pw_shell);
278 strcpy((p).pws.pw_shell, (p).pwp->pw_shell);
284 # define _Xpw_copyPasswd(p) \
285 (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \
286 ((p).pws.pw_name = (p).pwbuf), \
287 ((p).len = strlen((p).pwp->pw_name)), \
288 strcpy((p).pws.pw_name, (p).pwp->pw_name), \
289 ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
290 ((p).len = strlen((p).pwp->pw_passwd)), \
291 strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
292 ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
293 ((p).len = strlen((p).pwp->pw_age)), \
294 strcpy((p).pws.pw_age, (p).pwp->pw_age), \
295 ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
296 ((p).len = strlen((p).pwp->pw_comment)), \
297 strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
298 ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
299 ((p).len = strlen((p).pwp->pw_gecos)), \
300 strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
301 ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
302 ((p).len = strlen((p).pwp->pw_dir)), \
303 strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
304 ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
305 ((p).len = strlen((p).pwp->pw_shell)), \
306 strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
307 ((p).pwp = &(p).pws), \
310 # define _XGetpwuid(u,p) \
311 ( (_Xos_processLock), \
312 (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
313 (_Xos_processUnlock), \
315 # define _XGetpwnam(u,p) \
316 ( (_Xos_processLock), \
317 (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
318 (_Xos_processUnlock), \
321 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__)
322 # define X_NEEDS_PWPARAMS
325 char pwbuf[X_LINE_MAX];
327 # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4)
328 # define _XGetpwuid(u,p) \
329 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
330 # define _XGetpwnam(u,p) \
331 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
333 # define _XGetpwuid(u,p) \
334 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
335 # define _XGetpwnam(u,p) \
336 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
339 #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
340 # define X_NEEDS_PWPARAMS
343 char pwbuf[X_LINE_MAX];
346 typedef int _Xgetpwret;
347 # define _XGetpwuid(u,p) \
348 ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
350 # define _XGetpwnam(u,p) \
351 ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
353 #endif /* X_INCLUDE_PWD_H */
355 #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
356 # define _XOS_INCLUDED_PWD_H
360 /***** <netdb.h> wrappers *****/
363 * Effective prototypes for <netdb.h> wrappers:
365 * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
366 * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
369 * #define X_INCLUDE_NETDB_H
370 * #define XOS_USE_..._LOCKING
371 * #include <X11/Xos_r.h>
373 * typedef ... _Xgethostbynameparams;
374 * typedef ... _Xgetservbynameparams;
376 * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
377 * struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
378 * _Xgethostbynameparams);
379 * struct servent* _XGetservbyname(const char* name, const char* proto,
380 * _Xgetservbynameparams);
383 #undef XTHREADS_NEEDS_BYNAMEPARAMS
384 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
387 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
388 # define XOS_USE_MTSAFE_NETDBAPI 1
392 #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
395 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
396 /* Use regular, unsafe API. */
397 typedef int _Xgethostbynameparams; /* dummy */
398 typedef int _Xgetservbynameparams; /* dummy */
399 # define _XGethostbyname(h,hp) gethostbyname((h))
400 # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
401 # define _XGetservbyname(s,p,sp) getservbyname((s),(p))
403 #elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
404 /* WARNING: The h_addr_list and s_aliases values are *not* copied! */
406 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
407 #include <sys/param.h>
412 char h_name[MAXHOSTNAMELEN];
413 struct hostent *hptr;
414 } _Xgethostbynameparams;
419 struct servent *sptr;
420 } _Xgetservbynameparams;
422 # define XTHREADS_NEEDS_BYNAMEPARAMS
424 # define _Xg_copyHostent(hp) \
425 (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
426 strcpy((hp).h_name, (hp).hptr->h_name), \
427 ((hp).hent.h_name = (hp).h_name), \
428 ((hp).hptr = &(hp).hent), \
430 # define _Xg_copyServent(sp) \
431 (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
432 strcpy((sp).s_name, (sp).sptr->s_name), \
433 ((sp).sent.s_name = (sp).s_name), \
434 strcpy((sp).s_proto, (sp).sptr->s_proto), \
435 ((sp).sent.s_proto = (sp).s_proto), \
436 ((sp).sptr = &(sp).sent), \
438 # define _XGethostbyname(h,hp) \
439 ((_Xos_processLock), \
440 (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
441 (_Xos_processUnlock), \
443 # define _XGethostbyaddr(a,al,t,hp) \
444 ((_Xos_processLock), \
445 (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
446 (_Xos_processUnlock), \
448 # define _XGetservbyname(s,p,sp) \
449 ((_Xos_processLock), \
450 (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
451 (_Xos_processUnlock), \
454 #elif defined(XUSE_NETDB_R_API)
456 * POSIX does not specify _r equivalents for <netdb.h> API, but some
457 * vendors provide them anyway. Use them only when explicitly asked.
459 # ifdef _POSIX_REENTRANT_FUNCTIONS
460 # ifndef _POSIX_THREAD_SAFE_FUNCTIONS
463 # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
464 # define X_POSIX_THREAD_SAFE_FUNCTIONS 1
467 # define XTHREADS_NEEDS_BYNAMEPARAMS
469 # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
472 char hbuf[X_LINE_MAX];
474 } _Xgethostbynameparams;
477 char sbuf[X_LINE_MAX];
478 } _Xgetservbynameparams;
479 # define _XGethostbyname(h,hp) \
480 gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
481 # define _XGethostbyaddr(a,al,t,hp) \
482 gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
483 # define _XGetservbyname(s,p,sp) \
484 getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
488 struct hostent_data hdata;
489 } _Xgethostbynameparams;
492 struct servent_data sdata;
493 } _Xgetservbynameparams;
494 # define _XGethostbyname(h,hp) \
495 (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \
496 ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
497 # define _XGethostbyaddr(a,al,t,hp) \
498 (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \
499 ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
500 # define _XGetservbyname(s,p,sp) \
501 (bzero((char*)&(sp).sdata,sizeof((sp).sdata)), \
502 ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
504 # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
505 # undef X_POSIX_THREAD_SAFE_FUNCTIONS
509 /* The regular API is assumed to be MT-safe under POSIX. */
510 typedef int _Xgethostbynameparams; /* dummy */
511 typedef int _Xgetservbynameparams; /* dummy */
512 # define _XGethostbyname(h,hp) gethostbyname((h))
513 # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
514 # define _XGetservbyname(s,p,sp) getservbyname((s),(p))
515 #endif /* X_INCLUDE_NETDB_H */
517 #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
518 # define _XOS_INCLUDED_NETDB_H
522 /***** <dirent.h> wrappers *****/
525 * Effective prototypes for <dirent.h> wrappers:
527 * #define X_INCLUDE_DIRENT_H
528 * #define XOS_USE_..._LOCKING
529 * #include <X11/Xos_r.h>
531 * typedef ... _Xreaddirparams;
533 * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
536 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
537 # include <sys/types.h>
538 # if !defined(X_NOT_POSIX) || defined(SYSV)
541 # include <sys/dir.h>
543 # define dirent direct
546 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
547 # define XOS_USE_MTSAFE_DIRENTAPI 1
551 #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
554 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
555 /* Use regular, unsafe API. */
556 typedef int _Xreaddirparams; /* dummy */
557 # define _XReaddir(d,p) readdir(d)
559 #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
560 /* Systems with thread support but no _r API. */
562 struct dirent *result;
563 struct dirent dir_entry;
564 # ifdef _POSIX_PATH_MAX
565 char buf[_POSIX_PATH_MAX];
566 # elif defined(NAME_MAX)
573 # define _XReaddir(d,p) \
574 ( (_Xos_processLock), \
575 (((p).result = readdir((d))) ? \
576 (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
577 ((p).result = &(p).dir_entry), 0) : \
579 (_Xos_processUnlock), \
584 struct dirent *result;
585 struct dirent dir_entry;
586 # ifdef _POSIX_PATH_MAX
587 char buf[_POSIX_PATH_MAX];
588 # elif defined(NAME_MAX)
595 # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__)
596 /* POSIX final API, returns (int)0 on success. */
597 # define _XReaddir(d,p) \
598 (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
599 # elif defined(_POSIX_REENTRANT_FUNCTIONS)
600 /* POSIX draft API, returns (int)0 on success. */
601 # define _XReaddir(d,p) \
602 (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
604 /* Pre-POSIX API, returns non-NULL on success. */
605 # define _XReaddir(d,p) (readdir_r((d), &(p).dir_entry))
607 /* We have no idea what is going on. Fake it all using process locks. */
608 # define _XReaddir(d,p) \
609 ( (_Xos_processLock), \
610 (((p).result = readdir((d))) ? \
611 (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
612 ((p).result = &(p).dir_entry), 0) : \
614 (_Xos_processUnlock), \
617 #endif /* X_INCLUDE_DIRENT_H */
619 #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
620 # define _XOS_INCLUDED_DIRENT_H
624 /***** <unistd.h> wrappers *****/
627 * Effective prototypes for <unistd.h> wrappers:
629 * #define X_INCLUDE_UNISTD_H
630 * #define XOS_USE_..._LOCKING
631 * #include <X11/Xos_r.h>
633 * typedef ... _Xgetloginparams;
634 * typedef ... _Xttynameparams;
636 * char *_XGetlogin(_Xgetloginparams);
637 * char *_XTtyname(int, _Xttynameparams);
640 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
641 /* <unistd.h> already included by <X11/Xos.h> */
642 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
643 # define XOS_USE_MTSAFE_UNISTDAPI 1
647 #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
650 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
651 /* Use regular, unsafe API. */
652 typedef int _Xgetloginparams; /* dummy */
653 typedef int _Xttynameparams; /* dummy */
654 # define _XGetlogin(p) getlogin()
655 # define _XTtyname(f) ttyname((f))
657 #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
658 /* Systems with thread support but no _r API. */
661 # if defined(MAXLOGNAME)
662 char buf[MAXLOGNAME];
663 # elif defined(LOGIN_NAME_MAX)
664 char buf[LOGIN_NAME_MAX];
672 char buf[TTY_NAME_MAX];
673 # elif defined(_POSIX_TTY_NAME_MAX)
674 char buf[_POSIX_TTY_NAME_MAX];
675 # elif defined(_POSIX_PATH_MAX)
676 char buf[_POSIX_PATH_MAX];
682 # define _XGetlogin(p) \
683 ( (_Xos_processLock), \
684 (((p).result = getlogin()) ? \
685 (strncpy((p).buf, (p).result, sizeof((p).buf)), \
686 ((p).buf[sizeof((p).buf)-1] = '\0'), \
687 ((p).result = (p).buf), 0) : 0), \
688 (_Xos_processUnlock), \
690 #define _XTtyname(f,p) \
691 ( (_Xos_processLock), \
692 (((p).result = ttyname(f)) ? \
693 (strncpy((p).buf, (p).result, sizeof((p).buf)), \
694 ((p).buf[sizeof((p).buf)-1] = '\0'), \
695 ((p).result = (p).buf), 0) : 0), \
696 (_Xos_processUnlock), \
699 #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
702 * extern int getlogin_r(char *, size_t);
703 * extern int ttyname_r(int, char *, size_t);
706 # if defined(MAXLOGNAME)
707 char buf[MAXLOGNAME];
708 # elif defined(LOGIN_NAME_MAX)
709 char buf[LOGIN_NAME_MAX];
716 char buf[TTY_NAME_MAX];
717 # elif defined(_POSIX_TTY_NAME_MAX)
718 char buf[_POSIX_TTY_NAME_MAX];
719 # elif defined(_POSIX_PATH_MAX)
720 char buf[_POSIX_PATH_MAX];
726 # define _XGetlogin(p) (getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
727 # define _XTtyname(f,p) \
728 (ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
733 * extern char *getlogin_r(char *, size_t);
734 * extern char *ttyname_r(int, char *, size_t);
737 # if defined(MAXLOGNAME)
738 char buf[MAXLOGNAME];
739 # elif defined(LOGIN_NAME_MAX)
740 char buf[LOGIN_NAME_MAX];
747 char buf[TTY_NAME_MAX];
748 # elif defined(_POSIX_TTY_NAME_MAX)
749 char buf[_POSIX_TTY_NAME_MAX];
750 # elif defined(_POSIX_PATH_MAX)
751 char buf[_POSIX_PATH_MAX];
757 # define _XGetlogin(p) getlogin_r((p).buf, sizeof((p).buf))
758 # define _XTtyname(f,p) ttyname_r((f), (p).buf, sizeof((p).buf))
759 #endif /* X_INCLUDE_UNISTD_H */
761 #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
762 # define _XOS_INCLUDED_UNISTD_H
766 /***** <string.h> wrappers *****/
769 * Effective prototypes for <string.h> wrappers:
771 * #define X_INCLUDE_STRING_H
772 * #define XOS_USE_..._LOCKING
773 * #include <X11/Xos_r.h>
775 * typedef ... _Xstrtokparams;
777 * char *_XStrtok(char *, const char*, _Xstrtokparams);
780 #if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
781 /* <string.h> has already been included by <X11/Xos.h> */
782 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
783 # define XOS_USE_MTSAFE_STRINGAPI 1
787 #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
790 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
791 /* Use regular, unsafe API. */
792 typedef int _Xstrtokparams; /* dummy */
793 # define _XStrtok(s1,s2,p) \
794 ( p = 0, (void)p, strtok((s1),(s2)) )
796 #elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
797 /* Systems with thread support but no _r API. */
798 typedef char *_Xstrtokparams;
799 # define _XStrtok(s1,s2,p) \
800 ( (_Xos_processLock), \
801 ((p) = strtok((s1),(s2))), \
802 (_Xos_processUnlock), \
806 /* POSIX or pre-POSIX API. */
807 typedef char * _Xstrtokparams;
808 # define _XStrtok(s1,s2,p) strtok_r((s1),(s2),&(p))
809 #endif /* X_INCLUDE_STRING_H */
812 /***** <time.h> wrappers *****/
815 * Effective prototypes for <time.h> wrappers:
817 * #define X_INCLUDE_TIME_H
818 * #define XOS_USE_..._LOCKING
819 * #include <X11/Xos_r.h>
821 * typedef ... _Xatimeparams;
822 * typedef ... _Xctimeparams;
823 * typedef ... _Xgtimeparams;
824 * typedef ... _Xltimeparams;
826 * char *_XAsctime(const struct tm *, _Xatimeparams);
827 * char *_XCtime(const time_t *, _Xctimeparams);
828 * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
829 * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
832 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
834 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
835 # define XOS_USE_MTSAFE_TIMEAPI 1
839 #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
842 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
843 /* Use regular, unsafe API. */
844 typedef int _Xatimeparams; /* dummy */
845 # define _XAsctime(t,p) asctime((t))
846 typedef int _Xctimeparams; /* dummy */
847 # define _XCtime(t,p) ctime((t))
848 typedef int _Xgtimeparams; /* dummy */
849 # define _XGmtime(t,p) gmtime((t))
850 typedef int _Xltimeparams; /* dummy */
851 # define _XLocaltime(t,p) localtime((t))
853 #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
854 /* Systems with thread support but no _r API. */
862 } _Xctimeparams, _Xatimeparams;
866 } _Xgtimeparams, _Xltimeparams;
867 # define _XAsctime(t,p) \
868 ( (_Xos_processLock), \
869 (((p).result = asctime((t))) ? \
870 (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
872 (_Xos_processUnlock), \
874 # define _XCtime(t,p) \
875 ( (_Xos_processLock), \
876 (((p).result = ctime((t))) ? \
877 (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
879 (_Xos_processUnlock), \
881 # define _XGmtime(t,p) \
882 ( (_Xos_processLock), \
883 (((p).result = gmtime(t)) ? \
884 (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
886 (_Xos_processUnlock), \
888 # define _XLocaltime(t,p) \
889 ( (_Xos_processLock), \
890 (((p).result = localtime(t)) ? \
891 (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
893 (_Xos_processUnlock), \
896 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(hpV4)
897 /* Returns (int)0 on success.
899 * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
900 * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
901 * extern int gmtime_r(const time_t *timer, struct tm *result);
902 * extern int localtime_r(const time_t *timer, struct tm *result);
905 typedef char _Xatimeparams[TIMELEN];
906 typedef char _Xctimeparams[TIMELEN];
908 typedef char _Xatimeparams[26];
909 typedef char _Xctimeparams[26];
911 typedef struct tm _Xgtimeparams;
912 typedef struct tm _Xltimeparams;
913 # define _XAsctime(t,p) (asctime_r((t),(p),sizeof((p))) ? NULL : (p))
914 # define _XCtime(t,p) (ctime_r((t),(p),sizeof((p))) ? NULL : (p))
915 # define _XGmtime(t,p) (gmtime_r((t),&(p)) ? NULL : &(p))
916 # define _XLocaltime(t,p) (localtime_r((t),&(p)) ? NULL : &(p))
918 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
919 /* Returns NULL on failure. Solaris 2.5
921 * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
922 * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
923 * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
924 * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
927 typedef char _Xatimeparams[TIMELEN];
928 typedef char _Xctimeparams[TIMELEN];
930 typedef char _Xatimeparams[26];
931 typedef char _Xctimeparams[26];
933 typedef struct tm _Xgtimeparams;
934 typedef struct tm _Xltimeparams;
935 # define _XAsctime(t,p) asctime_r((t),(p),sizeof((p)))
936 # define _XCtime(t,p) ctime_r((t),(p),sizeof((p)))
937 # define _XGmtime(t,p) gmtime_r((t),&(p))
938 # define _XLocaltime(t,p) localtime_r((t),&(p))
940 #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
942 * extern char *asctime_r(const struct tm *timeptr, char *buffer);
943 * extern char *ctime_r(const time_t *timer, char *buffer);
944 * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
945 * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
948 typedef char _Xatimeparams[TIMELEN];
949 typedef char _Xctimeparams[TIMELEN];
951 typedef char _Xatimeparams[26];
952 typedef char _Xctimeparams[26];
954 typedef struct tm _Xgtimeparams;
955 typedef struct tm _Xltimeparams;
956 # define _XAsctime(t,p) asctime_r((t),(p))
957 # define _XCtime(t,p) ctime_r((t),(p))
958 # define _XGmtime(t,p) gmtime_r((t),&(p))
959 # define _XLocaltime(t,p) localtime_r((t),&(p))
960 #endif /* X_INCLUDE_TIME_H */
962 #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
963 # define _XOS_INCLUDED_TIME_H
967 /***** <grp.h> wrappers *****/
970 * Effective prototypes for <grp.h> wrappers:
972 * NOTE: On systems lacking appropriate _r functions Getgrgid() and
973 * Getgrnam() do NOT copy the list of group members!
975 * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
976 * are not included in POSIX.
978 * #define X_INCLUDE_GRP_H
979 * #define XOS_USE_..._LOCKING
980 * #include <X11/Xos_r.h>
982 * typedef ... _Xgetgrparams;
984 * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
985 * struct group *_XGetgrnam(const char *, _Xgetgrparams);
988 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
990 # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
991 # define XOS_USE_MTSAFE_GRPAPI 1
995 #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
998 #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
999 /* Use regular, unsafe API. */
1000 typedef int _Xgetgrparams; /* dummy */
1001 #define _XGetgrgid(g,p) getgrgid((g))
1002 #define _XGetgrnam(n,p) getgrnam((n))
1004 #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
1005 /* Systems with thread support but no _r API. UnixWare 2.0. */
1008 char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1013 /* Copy the gr_passwd field too. */
1014 # define _Xgrp_copyGroup(p) \
1015 ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1016 ((p).grp.gr_name = (p).buf), \
1017 ((p).len = strlen((p).pgrp->gr_name)), \
1018 strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1019 ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
1020 ((p).pgrp = &(p).grp), \
1023 # define _Xgrp_copyGroup(p) \
1024 ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
1025 ((p).grp.gr_name = (p).buf), \
1026 strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
1027 ((p).pgrp = &(p).grp), \
1030 #define _XGetgrgid(g,p) \
1031 ( (_Xos_processLock), \
1032 (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
1033 (_Xos_processUnlock), \
1035 #define _XGetgrnam(n,p) \
1036 ( (_Xos_processLock), \
1037 (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
1038 (_Xos_processUnlock), \
1041 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
1042 /* Non-POSIX API. Solaris.
1044 * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
1045 * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
1049 char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1051 #define _XGetgrgid(g,p) getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
1052 #define _XGetgrnam(n,p) getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
1054 #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1056 * extern int getgrgid_r(gid_t, struct group *, char *, int);
1057 * extern int getgrnam_r(const char *, struct group *, char *, int);
1061 char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1063 #define _XGetgrgid(g,p) \
1064 ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1065 #define _XGetgrnam(n,p) \
1066 ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
1071 * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
1072 * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
1076 char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
1077 struct group *result;
1080 #define _XGetgrgid(g,p) \
1081 ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1083 #define _XGetgrnam(n,p) \
1084 ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
1088 #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
1089 # define _XOS_INCLUDED_GRP_H
1094 } /* Close scope of 'extern "C"' declaration which encloses file. */