/*
Copyright 1996, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
/*
* Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
*
* Use this file in MT-safe code where you would have included
* <dirent.h> for readdir()
* <grp.h> for getgrgid() or getgrnam()
* <netdb.h> for gethostbyname(), gethostbyaddr(), or getservbyname()
* <pwd.h> for getpwnam() or getpwuid()
* <string.h> for strtok()
* <time.h> for asctime(), ctime(), localtime(), or gmtime()
* <unistd.h> for getlogin() or ttyname()
* or their thread-safe analogs.
*
* If you are on a platform that defines XTHREADS but does not have
* MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
* and _Xos_processUnlock macros before including this header.
*
* For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined
* to obtain either Xlib-only or Xt-based versions of these macros. These
* macros won't result in truly thread-safe calls, but they are better than
* nothing. If you do not want locking in this situation define
* XOS_USE_NO_LOCKING.
*
* NOTE: On systems lacking appropriate _r functions Gethostbyname(),
* Gethostbyaddr(), and Getservbyname() do NOT copy the host or
* protocol lists!
*
* NOTE: On systems lacking appropriate _r functions Getgrgid() and
* Getgrnam() do NOT copy the list of group members!
*
* This header is nominally intended to simplify porting X11, Motif, and
* CDE; it may be useful to other people too. The structure below is
* complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
* went through lots of drafts, and some vendors shipped systems based
* on draft API that were changed later. Unfortunately POSIX did not
* provide a feature-test macro for distinguishing each of the drafts.
*/
/*
* This header has several parts. Search for "Effective prototypes"
* to locate the beginning of a section.
*/
/* This header can be included multiple times with different defines! */
#ifndef _XOS_R_H_
# define _XOS_R_H_
# ifndef X_NOT_POSIX
# ifdef _POSIX_SOURCE
# include <limits.h>
# else
# define _POSIX_SOURCE
# include <limits.h>
# endif
# ifndef LINE_MAX
# else
# endif
# endif
#endif /* _XOS_R_H */
#ifndef WIN32
#ifdef __cplusplus
extern "C" {
#endif
# if defined(XOS_USE_XLIB_LOCKING)
extern LockInfoPtr _Xglobal_lock;
# endif
# ifndef _Xos_isThreadInitialized
# endif
# if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
extern void (*_XLockMutex_fn)(
# endif
);
extern void (*_XUnlockMutex_fn)(
# endif
);
# endif
# ifndef _Xos_processLock
# define _Xos_processLock \
# endif
# ifndef _Xos_processUnlock
# define _Xos_processUnlock \
# endif
# else
extern void (*_XLockMutex_fn)(
LockInfoPtr /* lock */
# endif
);
extern void (*_XUnlockMutex_fn)(
LockInfoPtr /* lock */
# endif
);
# endif
# ifndef _Xos_processLock
# define _Xos_processLock \
# endif
# ifndef _Xos_processUnlock
# define _Xos_processUnlock \
# endif
# endif
# elif defined(XOS_USE_XT_LOCKING)
# ifndef _XtThreadsI_h
extern void (*_XtProcessLock)(void);
# endif
# ifndef _XtintrinsicP_h
extern void XtProcessLock(
void
# endif
);
extern void XtProcessUnlock(
void
# endif
);
# endif
# ifndef _Xos_isThreadInitialized
# endif
# ifndef _Xos_processLock
# endif
# ifndef _Xos_processUnlock
# endif
# elif defined(XOS_USE_NO_LOCKING)
# ifndef _Xos_isThreadInitialized
# define _Xos_isThreadInitialized 0
# endif
# ifndef _Xos_processLock
# define _Xos_processLock 0
# endif
# ifndef _Xos_processUnlock
# define _Xos_processUnlock 0
# endif
# endif
#endif /* !defined WIN32 */
/*
* Solaris defines the POSIX thread-safe feature test macro, but
* uses the older SVR4 thread-safe functions unless the POSIX ones
* are specifically requested. Fix the feature test macro.
*/
#if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
#endif
/***** <pwd.h> wrappers *****/
/*
* Effective prototypes for <pwd.h> wrappers:
*
* #define X_INCLUDE_PWD_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xgetpwparams;
*
* struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
* struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
*/
#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
# include <pwd.h>
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
# endif
#endif
#if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
/* Do nothing */
/* Use regular, unsafe API. */
# endif
/* UnixWare 2.0, or other systems with thread support but no _r API. */
# define X_NEEDS_PWPARAMS
typedef struct {
/*
* NetBSD and FreeBSD, at least, are missing several of the unixware passwd
* fields.
*/
defined(__APPLE__) || defined(__DragonFly__)
{
}
#else
# define _Xpw_copyPasswd(p) \
0 )
#endif
# define _XGetpwuid(u,p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).pwp )
# define _XGetpwnam(u,p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).pwp )
# define X_NEEDS_PWPARAMS
typedef struct {
# if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4)
# define _XGetpwuid(u,p) \
# define _XGetpwnam(u,p) \
# else /* SVR4 */
# define _XGetpwuid(u,p) \
# define _XGetpwnam(u,p) \
# endif /* SVR4 */
#else /* _POSIX_THREAD_SAFE_FUNCTIONS */
# define X_NEEDS_PWPARAMS
typedef struct {
typedef int _Xgetpwret;
# define _XGetpwuid(u,p) \
# define _XGetpwnam(u,p) \
#endif /* X_INCLUDE_PWD_H */
#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
# define _XOS_INCLUDED_PWD_H
#endif
/***** <netdb.h> wrappers *****/
/*
* Effective prototypes for <netdb.h> wrappers:
*
* NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
* Gethostbyaddr(), and Getservbyname() do NOT copy the host or
* protocol lists!
*
* #define X_INCLUDE_NETDB_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xgethostbynameparams;
* typedef ... _Xgetservbynameparams;
*
* struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
* struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
* _Xgethostbynameparams);
* struct servent* _XGetservbyname(const char* name, const char* proto,
* _Xgetservbynameparams);
*/
#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
&& !defined(WIN32)
# include <netdb.h>
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
# endif
#endif
#if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* WARNING: The h_addr_list and s_aliases values are *not* copied! */
#endif
typedef struct {
typedef struct {
# define XTHREADS_NEEDS_BYNAMEPARAMS
0 )
0 )
((_Xos_processLock), \
(_Xos_processUnlock), \
((_Xos_processLock), \
(_Xos_processUnlock), \
((_Xos_processLock), \
(_Xos_processUnlock), \
#elif defined(XUSE_NETDB_R_API)
/*
* POSIX does not specify _r equivalents for <netdb.h> API, but some
* vendors provide them anyway. Use them only when explicitly asked.
*/
# ifdef _POSIX_REENTRANT_FUNCTIONS
# ifndef _POSIX_THREAD_SAFE_FUNCTIONS
# endif
# endif
# ifdef _POSIX_THREAD_SAFE_FUNCTIONS
# endif
# define XTHREADS_NEEDS_BYNAMEPARAMS
# ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
typedef struct {
int herr;
typedef struct {
# else
typedef struct {
typedef struct {
# endif
# ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
# endif
#else
/* The regular API is assumed to be MT-safe under POSIX. */
#endif /* X_INCLUDE_NETDB_H */
#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
# define _XOS_INCLUDED_NETDB_H
#endif
/***** <dirent.h> wrappers *****/
/*
* Effective prototypes for <dirent.h> wrappers:
*
* #define X_INCLUDE_DIRENT_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xreaddirparams;
*
* struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
*/
#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
# if !defined(X_NOT_POSIX) || defined(SYSV)
# include <dirent.h>
# else
# ifndef dirent
# endif
# endif
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
# endif
#endif
#if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* Systems with thread support but no _r API. */
typedef struct {
# ifdef _POSIX_PATH_MAX
# else
# endif
# define _XReaddir(d,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
#else
typedef struct {
# ifdef _POSIX_PATH_MAX
# else
# endif
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__)
/* POSIX final API, returns (int)0 on success. */
# define _XReaddir(d,p) \
# elif defined(_POSIX_REENTRANT_FUNCTIONS)
/* POSIX draft API, returns (int)0 on success. */
# define _XReaddir(d,p) \
/* Pre-POSIX API, returns non-NULL on success. */
# else
/* We have no idea what is going on. Fake it all using process locks. */
# define _XReaddir(d,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
# endif
#endif /* X_INCLUDE_DIRENT_H */
#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
# define _XOS_INCLUDED_DIRENT_H
#endif
/***** <unistd.h> wrappers *****/
/*
* Effective prototypes for <unistd.h> wrappers:
*
* #define X_INCLUDE_UNISTD_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xgetloginparams;
* typedef ... _Xttynameparams;
*
* char *_XGetlogin(_Xgetloginparams);
* char *_XTtyname(int, _Xttynameparams);
*/
#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
# endif
#endif
#if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* Systems with thread support but no _r API. */
typedef struct {
char *result;
# if defined(MAXLOGNAME)
# elif defined(LOGIN_NAME_MAX)
# else
# endif
typedef struct {
char *result;
# ifdef TTY_NAME_MAX
# elif defined(_POSIX_TTY_NAME_MAX)
# elif defined(_POSIX_PATH_MAX)
# else
# endif
# define _XGetlogin(p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).result )
#define _XTtyname(f,p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).result )
/* POSIX API.
*
* extern int getlogin_r(char *, size_t);
* extern int ttyname_r(int, char *, size_t);
*/
typedef struct {
# if defined(MAXLOGNAME)
# elif defined(LOGIN_NAME_MAX)
char buf[LOGIN_NAME_MAX];
# else
char buf[64];
# endif
typedef struct {
# ifdef TTY_NAME_MAX
# elif defined(_POSIX_TTY_NAME_MAX)
char buf[_POSIX_TTY_NAME_MAX];
# elif defined(_POSIX_PATH_MAX)
char buf[_POSIX_PATH_MAX];
# else
char buf[256];
# endif
# define _XTtyname(f,p) \
#else
/* Pre-POSIX API.
*
* extern char *getlogin_r(char *, size_t);
* extern char *ttyname_r(int, char *, size_t);
*/
typedef struct {
# if defined(MAXLOGNAME)
# elif defined(LOGIN_NAME_MAX)
char buf[LOGIN_NAME_MAX];
# else
char buf[64];
# endif
typedef struct {
# ifdef TTY_NAME_MAX
# elif defined(_POSIX_TTY_NAME_MAX)
char buf[_POSIX_TTY_NAME_MAX];
# elif defined(_POSIX_PATH_MAX)
char buf[_POSIX_PATH_MAX];
# else
char buf[256];
# endif
#endif /* X_INCLUDE_UNISTD_H */
#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
# define _XOS_INCLUDED_UNISTD_H
#endif
/***** <string.h> wrappers *****/
/*
* Effective prototypes for <string.h> wrappers:
*
* #define X_INCLUDE_STRING_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xstrtokparams;
*
* char *_XStrtok(char *, const char*, _Xstrtokparams);
*/
#if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
# endif
#endif
#if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* Systems with thread support but no _r API. */
typedef char *_Xstrtokparams;
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p) )
#else
/* POSIX or pre-POSIX API. */
typedef char * _Xstrtokparams;
#endif /* X_INCLUDE_STRING_H */
/***** <time.h> wrappers *****/
/*
* Effective prototypes for <time.h> wrappers:
*
* #define X_INCLUDE_TIME_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xatimeparams;
* typedef ... _Xctimeparams;
* typedef ... _Xgtimeparams;
* typedef ... _Xltimeparams;
*
* char *_XAsctime(const struct tm *, _Xatimeparams);
* char *_XCtime(const time_t *, _Xctimeparams);
* struct tm *_XGmtime(const time_t *, _Xgtimeparams);
* struct tm *_XLocaltime(const time_t *, _Xltimeparams);
*/
#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
# include <time.h>
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
# endif
#endif
#if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* Systems with thread support but no _r API. */
typedef struct {
# ifdef TIMELEN
# else
char buf[26];
# endif
char *result;
typedef struct {
# define _XAsctime(t,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
# define _XCtime(t,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
# define _XGmtime(t,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
# define _XLocaltime(t,p) \
( (_Xos_processLock), \
0), \
(_Xos_processUnlock), \
(p).result )
/* Returns (int)0 on success.
*
* extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
* extern int ctime_r(const time_t *timer, char *buffer, int buflen);
* extern int gmtime_r(const time_t *timer, struct tm *result);
* extern int localtime_r(const time_t *timer, struct tm *result);
*/
# ifdef TIMELEN
# else
# endif
/* Returns NULL on failure. Solaris 2.5
*
* extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
* extern char *ctime_r(const time_t *clock, char *buf, int buflen);
* extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
* extern struct tm *localtime_r(const time_t *clock, struct tm *res);
*/
# ifdef TIMELEN
# else
# endif
#else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
/* POSIX final API.
* extern char *asctime_r(const struct tm *timeptr, char *buffer);
* extern char *ctime_r(const time_t *timer, char *buffer);
* extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
* extern struct tm *localtime_r(const time_t *timer, struct tm *result);
*/
# ifdef TIMELEN
# else
# endif
#endif /* X_INCLUDE_TIME_H */
#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
# define _XOS_INCLUDED_TIME_H
#endif
/***** <grp.h> wrappers *****/
/*
* Effective prototypes for <grp.h> wrappers:
*
* NOTE: On systems lacking appropriate _r functions Getgrgid() and
* Getgrnam() do NOT copy the list of group members!
*
* Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
* are not included in POSIX.
*
* #define X_INCLUDE_GRP_H
* #define XOS_USE_..._LOCKING
*
* typedef ... _Xgetgrparams;
*
* struct group *_XGetgrgid(gid_t, _Xgetgrparams);
* struct group *_XGetgrnam(const char *, _Xgetgrparams);
*/
#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
# include <grp.h>
# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
# endif
#endif
#if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
/* Do nothing. */
/* Use regular, unsafe API. */
/* Systems with thread support but no _r API. UnixWare 2.0. */
typedef struct {
#ifdef SVR4
/* Copy the gr_passwd field too. */
# define _Xgrp_copyGroup(p) \
0 )
#else
# define _Xgrp_copyGroup(p) \
0 )
#endif
#define _XGetgrgid(g,p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).pgrp )
#define _XGetgrnam(n,p) \
( (_Xos_processLock), \
(_Xos_processUnlock), \
(p).pgrp )
/* Non-POSIX API. Solaris.
*
* extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
* extern struct group *getgrnam_r(const char *, struct group *, char *, int);
*/
typedef struct {
#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
/* Non-POSIX API.
* extern int getgrgid_r(gid_t, struct group *, char *, int);
* extern int getgrnam_r(const char *, struct group *, char *, int);
*/
typedef struct {
#define _XGetgrgid(g,p) \
#define _XGetgrnam(n,p) \
#else
/* POSIX final API.
*
* int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
* int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
*/
typedef struct {
#define _XGetgrgid(g,p) \
#define _XGetgrnam(n,p) \
#endif
#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
# define _XOS_INCLUDED_GRP_H
#endif
#ifdef __cplusplus
} /* Close scope of 'extern "C"' declaration which encloses file. */
#endif