Xos_r.h 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. /*
  2. Copyright 1996, 1998 The Open Group
  3. Permission to use, copy, modify, distribute, and sell this software and its
  4. documentation for any purpose is hereby granted without fee, provided that
  5. the above copyright notice appear in all copies and that both that
  6. copyright notice and this permission notice appear in supporting
  7. documentation.
  8. The above copyright notice and this permission notice shall be included in
  9. all copies or substantial portions of the Software.
  10. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  14. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  15. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. Except as contained in this notice, the name of The Open Group shall not be
  17. used in advertising or otherwise to promote the sale, use or other dealings
  18. in this Software without prior written authorization from The Open Group.
  19. */
  20. /*
  21. * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
  22. *
  23. * Use this file in MT-safe code where you would have included
  24. * <dirent.h> for readdir()
  25. * <grp.h> for getgrgid() or getgrnam()
  26. * <netdb.h> for gethostbyname(), gethostbyaddr(), or getservbyname()
  27. * <pwd.h> for getpwnam() or getpwuid()
  28. * <string.h> for strtok()
  29. * <time.h> for asctime(), ctime(), localtime(), or gmtime()
  30. * <unistd.h> for getlogin() or ttyname()
  31. * or their thread-safe analogs.
  32. *
  33. * If you are on a platform that defines XTHREADS but does not have
  34. * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
  35. * and _Xos_processUnlock macros before including this header.
  36. *
  37. * For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined
  38. * to obtain either Xlib-only or Xt-based versions of these macros. These
  39. * macros won't result in truly thread-safe calls, but they are better than
  40. * nothing. If you do not want locking in this situation define
  41. * XOS_USE_NO_LOCKING.
  42. *
  43. * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
  44. * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
  45. * protocol lists!
  46. *
  47. * NOTE: On systems lacking appropriate _r functions Getgrgid() and
  48. * Getgrnam() do NOT copy the list of group members!
  49. *
  50. * This header is nominally intended to simplify porting X11, Motif, and
  51. * CDE; it may be useful to other people too. The structure below is
  52. * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
  53. * went through lots of drafts, and some vendors shipped systems based
  54. * on draft API that were changed later. Unfortunately POSIX did not
  55. * provide a feature-test macro for distinguishing each of the drafts.
  56. */
  57. /*
  58. * This header has several parts. Search for "Effective prototypes"
  59. * to locate the beginning of a section.
  60. */
  61. /* This header can be included multiple times with different defines! */
  62. #ifndef _XOS_R_H_
  63. # define _XOS_R_H_
  64. # include <X11/Xos.h>
  65. # include <X11/Xfuncs.h>
  66. # ifndef X_NOT_POSIX
  67. # ifdef _POSIX_SOURCE
  68. # include <limits.h>
  69. # else
  70. # define _POSIX_SOURCE
  71. # include <limits.h>
  72. # undef _POSIX_SOURCE
  73. # endif
  74. # ifndef LINE_MAX
  75. # define X_LINE_MAX 2048
  76. # else
  77. # define X_LINE_MAX LINE_MAX
  78. # endif
  79. # endif
  80. #endif /* _XOS_R_H */
  81. #ifndef WIN32
  82. #ifdef __cplusplus
  83. extern "C" {
  84. #endif
  85. # if defined(XOS_USE_XLIB_LOCKING)
  86. # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
  87. typedef struct _LockInfoRec *LockInfoPtr;
  88. extern LockInfoPtr _Xglobal_lock;
  89. # endif
  90. # ifndef _Xos_isThreadInitialized
  91. # define _Xos_isThreadInitialized (_Xglobal_lock)
  92. # endif
  93. # if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
  94. # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
  95. # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
  96. extern void (*_XLockMutex_fn)(
  97. # if NeedFunctionPrototypes
  98. LockInfoPtr /* lock */, char * /* file */, int /* line */
  99. # endif
  100. );
  101. extern void (*_XUnlockMutex_fn)(
  102. # if NeedFunctionPrototypes
  103. LockInfoPtr /* lock */, char * /* file */, int /* line */
  104. # endif
  105. );
  106. # endif
  107. # ifndef _Xos_processLock
  108. # define _Xos_processLock \
  109. (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
  110. # endif
  111. # ifndef _Xos_processUnlock
  112. # define _Xos_processUnlock \
  113. (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
  114. # endif
  115. # else
  116. # ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
  117. # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
  118. extern void (*_XLockMutex_fn)(
  119. # if NeedFunctionPrototypes
  120. LockInfoPtr /* lock */
  121. # endif
  122. );
  123. extern void (*_XUnlockMutex_fn)(
  124. # if NeedFunctionPrototypes
  125. LockInfoPtr /* lock */
  126. # endif
  127. );
  128. # endif
  129. # ifndef _Xos_processLock
  130. # define _Xos_processLock \
  131. (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
  132. # endif
  133. # ifndef _Xos_processUnlock
  134. # define _Xos_processUnlock \
  135. (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
  136. # endif
  137. # endif
  138. # elif defined(XOS_USE_XT_LOCKING)
  139. # ifndef _XtThreadsI_h
  140. extern void (*_XtProcessLock)(void);
  141. # endif
  142. # ifndef _XtintrinsicP_h
  143. # include <X11/Xfuncproto.h> /* for NeedFunctionPrototypes */
  144. extern void XtProcessLock(
  145. # if NeedFunctionPrototypes
  146. void
  147. # endif
  148. );
  149. extern void XtProcessUnlock(
  150. # if NeedFunctionPrototypes
  151. void
  152. # endif
  153. );
  154. # endif
  155. # ifndef _Xos_isThreadInitialized
  156. # define _Xos_isThreadInitialized _XtProcessLock
  157. # endif
  158. # ifndef _Xos_processLock
  159. # define _Xos_processLock XtProcessLock()
  160. # endif
  161. # ifndef _Xos_processUnlock
  162. # define _Xos_processUnlock XtProcessUnlock()
  163. # endif
  164. # elif defined(XOS_USE_NO_LOCKING)
  165. # ifndef _Xos_isThreadInitialized
  166. # define _Xos_isThreadInitialized 0
  167. # endif
  168. # ifndef _Xos_processLock
  169. # define _Xos_processLock 0
  170. # endif
  171. # ifndef _Xos_processUnlock
  172. # define _Xos_processUnlock 0
  173. # endif
  174. # endif
  175. #endif /* !defined WIN32 */
  176. /*
  177. * Solaris defines the POSIX thread-safe feature test macro, but
  178. * uses the older SVR4 thread-safe functions unless the POSIX ones
  179. * are specifically requested. Fix the feature test macro.
  180. */
  181. #if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
  182. (_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS)
  183. # undef _POSIX_THREAD_SAFE_FUNCTIONS
  184. #endif
  185. /***** <pwd.h> wrappers *****/
  186. /*
  187. * Effective prototypes for <pwd.h> wrappers:
  188. *
  189. * #define X_INCLUDE_PWD_H
  190. * #define XOS_USE_..._LOCKING
  191. * #include <X11/Xos_r.h>
  192. *
  193. * typedef ... _Xgetpwparams;
  194. *
  195. * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
  196. * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
  197. */
  198. #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
  199. # include <pwd.h>
  200. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
  201. # define XOS_USE_MTSAFE_PWDAPI 1
  202. # endif
  203. #endif
  204. #undef X_NEEDS_PWPARAMS
  205. #if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
  206. /* Do nothing */
  207. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  208. /* Use regular, unsafe API. */
  209. # if defined(X_NOT_POSIX) && !defined(__i386__) && !defined(SYSV)
  210. extern struct passwd *getpwuid(), *getpwnam();
  211. # endif
  212. typedef int _Xgetpwparams; /* dummy */
  213. # define _XGetpwuid(u,p) getpwuid((u))
  214. # define _XGetpwnam(u,p) getpwnam((u))
  215. #elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
  216. /* UnixWare 2.0, or other systems with thread support but no _r API. */
  217. # define X_NEEDS_PWPARAMS
  218. typedef struct {
  219. struct passwd pws;
  220. char pwbuf[1024];
  221. struct passwd* pwp;
  222. size_t len;
  223. } _Xgetpwparams;
  224. /*
  225. * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
  226. * fields.
  227. */
  228. #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
  229. defined(__APPLE__) || defined(__DragonFly__)
  230. static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p)
  231. {
  232. memcpy(&(p).pws, (p).pwp, sizeof(struct passwd));
  233. (p).pws.pw_name = (p).pwbuf;
  234. (p).len = strlen((p).pwp->pw_name);
  235. strcpy((p).pws.pw_name, (p).pwp->pw_name);
  236. (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1;
  237. (p).len = strlen((p).pwp->pw_passwd);
  238. strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd);
  239. (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1;
  240. (p).len = strlen((p).pwp->pw_class);
  241. strcpy((p).pws.pw_class, (p).pwp->pw_class);
  242. (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1;
  243. (p).len = strlen((p).pwp->pw_gecos);
  244. strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos);
  245. (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1;
  246. (p).len = strlen((p).pwp->pw_dir);
  247. strcpy((p).pws.pw_dir, (p).pwp->pw_dir);
  248. (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1;
  249. (p).len = strlen((p).pwp->pw_shell);
  250. strcpy((p).pws.pw_shell, (p).pwp->pw_shell);
  251. (p).pwp = &(p).pws;
  252. }
  253. #else
  254. # define _Xpw_copyPasswd(p) \
  255. (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), \
  259. ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
  260. ((p).len = strlen((p).pwp->pw_passwd)), \
  261. strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
  262. ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
  263. ((p).len = strlen((p).pwp->pw_age)), \
  264. strcpy((p).pws.pw_age, (p).pwp->pw_age), \
  265. ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
  266. ((p).len = strlen((p).pwp->pw_comment)), \
  267. strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
  268. ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
  269. ((p).len = strlen((p).pwp->pw_gecos)), \
  270. strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
  271. ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
  272. ((p).len = strlen((p).pwp->pw_dir)), \
  273. strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
  274. ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
  275. ((p).len = strlen((p).pwp->pw_shell)), \
  276. strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
  277. ((p).pwp = &(p).pws), \
  278. 0 )
  279. #endif
  280. # define _XGetpwuid(u,p) \
  281. ( (_Xos_processLock), \
  282. (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
  283. (_Xos_processUnlock), \
  284. (p).pwp )
  285. # define _XGetpwnam(u,p) \
  286. ( (_Xos_processLock), \
  287. (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
  288. (_Xos_processUnlock), \
  289. (p).pwp )
  290. #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__)
  291. # define X_NEEDS_PWPARAMS
  292. typedef struct {
  293. struct passwd pws;
  294. char pwbuf[X_LINE_MAX];
  295. } _Xgetpwparams;
  296. # if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4)
  297. # define _XGetpwuid(u,p) \
  298. ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
  299. # define _XGetpwnam(u,p) \
  300. ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
  301. # else /* SVR4 */
  302. # define _XGetpwuid(u,p) \
  303. ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
  304. # define _XGetpwnam(u,p) \
  305. ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
  306. # endif /* SVR4 */
  307. #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
  308. # define X_NEEDS_PWPARAMS
  309. typedef struct {
  310. struct passwd pws;
  311. char pwbuf[X_LINE_MAX];
  312. struct passwd* pwp;
  313. } _Xgetpwparams;
  314. typedef int _Xgetpwret;
  315. # define _XGetpwuid(u,p) \
  316. ((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
  317. (p).pwp : NULL)
  318. # define _XGetpwnam(u,p) \
  319. ((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
  320. (p).pwp : NULL)
  321. #endif /* X_INCLUDE_PWD_H */
  322. #if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
  323. # define _XOS_INCLUDED_PWD_H
  324. #endif
  325. /***** <netdb.h> wrappers *****/
  326. /*
  327. * Effective prototypes for <netdb.h> wrappers:
  328. *
  329. * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
  330. * Gethostbyaddr(), and Getservbyname() do NOT copy the host or
  331. * protocol lists!
  332. *
  333. * #define X_INCLUDE_NETDB_H
  334. * #define XOS_USE_..._LOCKING
  335. * #include <X11/Xos_r.h>
  336. *
  337. * typedef ... _Xgethostbynameparams;
  338. * typedef ... _Xgetservbynameparams;
  339. *
  340. * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
  341. * struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
  342. * _Xgethostbynameparams);
  343. * struct servent* _XGetservbyname(const char* name, const char* proto,
  344. * _Xgetservbynameparams);
  345. */
  346. #undef XTHREADS_NEEDS_BYNAMEPARAMS
  347. #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
  348. && !defined(WIN32)
  349. # include <netdb.h>
  350. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
  351. # define XOS_USE_MTSAFE_NETDBAPI 1
  352. # endif
  353. #endif
  354. #if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
  355. /* Do nothing. */
  356. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  357. /* Use regular, unsafe API. */
  358. typedef int _Xgethostbynameparams; /* dummy */
  359. typedef int _Xgetservbynameparams; /* dummy */
  360. # define _XGethostbyname(h,hp) gethostbyname((h))
  361. # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
  362. # define _XGetservbyname(s,p,sp) getservbyname((s),(p))
  363. #elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
  364. /* WARNING: The h_addr_list and s_aliases values are *not* copied! */
  365. #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
  366. #include <sys/param.h>
  367. #endif
  368. typedef struct {
  369. struct hostent hent;
  370. char h_name[MAXHOSTNAMELEN];
  371. struct hostent *hptr;
  372. } _Xgethostbynameparams;
  373. typedef struct {
  374. struct servent sent;
  375. char s_name[255];
  376. char s_proto[255];
  377. struct servent *sptr;
  378. } _Xgetservbynameparams;
  379. # define XTHREADS_NEEDS_BYNAMEPARAMS
  380. # define _Xg_copyHostent(hp) \
  381. (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
  382. strcpy((hp).h_name, (hp).hptr->h_name), \
  383. ((hp).hent.h_name = (hp).h_name), \
  384. ((hp).hptr = &(hp).hent), \
  385. 0 )
  386. # define _Xg_copyServent(sp) \
  387. (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
  388. strcpy((sp).s_name, (sp).sptr->s_name), \
  389. ((sp).sent.s_name = (sp).s_name), \
  390. strcpy((sp).s_proto, (sp).sptr->s_proto), \
  391. ((sp).sent.s_proto = (sp).s_proto), \
  392. ((sp).sptr = &(sp).sent), \
  393. 0 )
  394. # define _XGethostbyname(h,hp) \
  395. ((_Xos_processLock), \
  396. (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
  397. (_Xos_processUnlock), \
  398. (hp).hptr )
  399. # define _XGethostbyaddr(a,al,t,hp) \
  400. ((_Xos_processLock), \
  401. (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
  402. (_Xos_processUnlock), \
  403. (hp).hptr )
  404. # define _XGetservbyname(s,p,sp) \
  405. ((_Xos_processLock), \
  406. (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
  407. (_Xos_processUnlock), \
  408. (sp).sptr )
  409. #elif defined(XUSE_NETDB_R_API)
  410. /*
  411. * POSIX does not specify _r equivalents for <netdb.h> API, but some
  412. * vendors provide them anyway. Use them only when explicitly asked.
  413. */
  414. # ifdef _POSIX_REENTRANT_FUNCTIONS
  415. # ifndef _POSIX_THREAD_SAFE_FUNCTIONS
  416. # endif
  417. # endif
  418. # ifdef _POSIX_THREAD_SAFE_FUNCTIONS
  419. # define X_POSIX_THREAD_SAFE_FUNCTIONS 1
  420. # endif
  421. # define XTHREADS_NEEDS_BYNAMEPARAMS
  422. # ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
  423. typedef struct {
  424. struct hostent hent;
  425. char hbuf[X_LINE_MAX];
  426. int herr;
  427. } _Xgethostbynameparams;
  428. typedef struct {
  429. struct servent sent;
  430. char sbuf[X_LINE_MAX];
  431. } _Xgetservbynameparams;
  432. # define _XGethostbyname(h,hp) \
  433. gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
  434. # define _XGethostbyaddr(a,al,t,hp) \
  435. gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
  436. # define _XGetservbyname(s,p,sp) \
  437. getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
  438. # else
  439. typedef struct {
  440. struct hostent hent;
  441. struct hostent_data hdata;
  442. } _Xgethostbynameparams;
  443. typedef struct {
  444. struct servent sent;
  445. struct servent_data sdata;
  446. } _Xgetservbynameparams;
  447. # define _XGethostbyname(h,hp) \
  448. (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \
  449. ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
  450. # define _XGethostbyaddr(a,al,t,hp) \
  451. (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \
  452. ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
  453. # define _XGetservbyname(s,p,sp) \
  454. (bzero((char*)&(sp).sdata,sizeof((sp).sdata)), \
  455. ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
  456. # endif
  457. # ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
  458. # undef X_POSIX_THREAD_SAFE_FUNCTIONS
  459. # endif
  460. #else
  461. /* The regular API is assumed to be MT-safe under POSIX. */
  462. typedef int _Xgethostbynameparams; /* dummy */
  463. typedef int _Xgetservbynameparams; /* dummy */
  464. # define _XGethostbyname(h,hp) gethostbyname((h))
  465. # define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t))
  466. # define _XGetservbyname(s,p,sp) getservbyname((s),(p))
  467. #endif /* X_INCLUDE_NETDB_H */
  468. #if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
  469. # define _XOS_INCLUDED_NETDB_H
  470. #endif
  471. /***** <dirent.h> wrappers *****/
  472. /*
  473. * Effective prototypes for <dirent.h> wrappers:
  474. *
  475. * #define X_INCLUDE_DIRENT_H
  476. * #define XOS_USE_..._LOCKING
  477. * #include <X11/Xos_r.h>
  478. *
  479. * typedef ... _Xreaddirparams;
  480. *
  481. * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
  482. */
  483. #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
  484. # include <sys/types.h>
  485. # if !defined(X_NOT_POSIX) || defined(SYSV)
  486. # include <dirent.h>
  487. # else
  488. # include <sys/dir.h>
  489. # ifndef dirent
  490. # define dirent direct
  491. # endif
  492. # endif
  493. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
  494. # define XOS_USE_MTSAFE_DIRENTAPI 1
  495. # endif
  496. #endif
  497. #if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
  498. /* Do nothing. */
  499. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  500. /* Use regular, unsafe API. */
  501. typedef int _Xreaddirparams; /* dummy */
  502. # define _XReaddir(d,p) readdir(d)
  503. #elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
  504. /* Systems with thread support but no _r API. */
  505. typedef struct {
  506. struct dirent *result;
  507. struct dirent dir_entry;
  508. # ifdef _POSIX_PATH_MAX
  509. char buf[_POSIX_PATH_MAX];
  510. # elif defined(NAME_MAX)
  511. char buf[NAME_MAX];
  512. # else
  513. char buf[255];
  514. # endif
  515. } _Xreaddirparams;
  516. # define _XReaddir(d,p) \
  517. ( (_Xos_processLock), \
  518. (((p).result = readdir((d))) ? \
  519. (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
  520. ((p).result = &(p).dir_entry), 0) : \
  521. 0), \
  522. (_Xos_processUnlock), \
  523. (p).result )
  524. #else
  525. typedef struct {
  526. struct dirent *result;
  527. struct dirent dir_entry;
  528. # ifdef _POSIX_PATH_MAX
  529. char buf[_POSIX_PATH_MAX];
  530. # elif defined(NAME_MAX)
  531. char buf[NAME_MAX];
  532. # else
  533. char buf[255];
  534. # endif
  535. } _Xreaddirparams;
  536. # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__)
  537. /* POSIX final API, returns (int)0 on success. */
  538. # define _XReaddir(d,p) \
  539. (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
  540. # elif defined(_POSIX_REENTRANT_FUNCTIONS)
  541. /* POSIX draft API, returns (int)0 on success. */
  542. # define _XReaddir(d,p) \
  543. (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
  544. # elif defined(SVR4)
  545. /* Pre-POSIX API, returns non-NULL on success. */
  546. # define _XReaddir(d,p) (readdir_r((d), &(p).dir_entry))
  547. # else
  548. /* We have no idea what is going on. Fake it all using process locks. */
  549. # define _XReaddir(d,p) \
  550. ( (_Xos_processLock), \
  551. (((p).result = readdir((d))) ? \
  552. (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
  553. ((p).result = &(p).dir_entry), 0) : \
  554. 0), \
  555. (_Xos_processUnlock), \
  556. (p).result )
  557. # endif
  558. #endif /* X_INCLUDE_DIRENT_H */
  559. #if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
  560. # define _XOS_INCLUDED_DIRENT_H
  561. #endif
  562. /***** <unistd.h> wrappers *****/
  563. /*
  564. * Effective prototypes for <unistd.h> wrappers:
  565. *
  566. * #define X_INCLUDE_UNISTD_H
  567. * #define XOS_USE_..._LOCKING
  568. * #include <X11/Xos_r.h>
  569. *
  570. * typedef ... _Xgetloginparams;
  571. * typedef ... _Xttynameparams;
  572. *
  573. * char *_XGetlogin(_Xgetloginparams);
  574. * char *_XTtyname(int, _Xttynameparams);
  575. */
  576. #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
  577. /* <unistd.h> already included by <X11/Xos.h> */
  578. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
  579. # define XOS_USE_MTSAFE_UNISTDAPI 1
  580. # endif
  581. #endif
  582. #if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
  583. /* Do nothing. */
  584. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  585. /* Use regular, unsafe API. */
  586. typedef int _Xgetloginparams; /* dummy */
  587. typedef int _Xttynameparams; /* dummy */
  588. # define _XGetlogin(p) getlogin()
  589. # define _XTtyname(f) ttyname((f))
  590. #elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
  591. /* Systems with thread support but no _r API. */
  592. typedef struct {
  593. char *result;
  594. # if defined(MAXLOGNAME)
  595. char buf[MAXLOGNAME];
  596. # elif defined(LOGIN_NAME_MAX)
  597. char buf[LOGIN_NAME_MAX];
  598. # else
  599. char buf[64];
  600. # endif
  601. } _Xgetloginparams;
  602. typedef struct {
  603. char *result;
  604. # ifdef TTY_NAME_MAX
  605. char buf[TTY_NAME_MAX];
  606. # elif defined(_POSIX_TTY_NAME_MAX)
  607. char buf[_POSIX_TTY_NAME_MAX];
  608. # elif defined(_POSIX_PATH_MAX)
  609. char buf[_POSIX_PATH_MAX];
  610. # else
  611. char buf[256];
  612. # endif
  613. } _Xttynameparams;
  614. # define _XGetlogin(p) \
  615. ( (_Xos_processLock), \
  616. (((p).result = getlogin()) ? \
  617. (strncpy((p).buf, (p).result, sizeof((p).buf)), \
  618. ((p).buf[sizeof((p).buf)-1] = '\0'), \
  619. ((p).result = (p).buf), 0) : 0), \
  620. (_Xos_processUnlock), \
  621. (p).result )
  622. #define _XTtyname(f,p) \
  623. ( (_Xos_processLock), \
  624. (((p).result = ttyname(f)) ? \
  625. (strncpy((p).buf, (p).result, sizeof((p).buf)), \
  626. ((p).buf[sizeof((p).buf)-1] = '\0'), \
  627. ((p).result = (p).buf), 0) : 0), \
  628. (_Xos_processUnlock), \
  629. (p).result )
  630. #elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
  631. /* POSIX API.
  632. *
  633. * extern int getlogin_r(char *, size_t);
  634. * extern int ttyname_r(int, char *, size_t);
  635. */
  636. typedef struct {
  637. # if defined(MAXLOGNAME)
  638. char buf[MAXLOGNAME];
  639. # elif defined(LOGIN_NAME_MAX)
  640. char buf[LOGIN_NAME_MAX];
  641. # else
  642. char buf[64];
  643. # endif
  644. } _Xgetloginparams;
  645. typedef struct {
  646. # ifdef TTY_NAME_MAX
  647. char buf[TTY_NAME_MAX];
  648. # elif defined(_POSIX_TTY_NAME_MAX)
  649. char buf[_POSIX_TTY_NAME_MAX];
  650. # elif defined(_POSIX_PATH_MAX)
  651. char buf[_POSIX_PATH_MAX];
  652. # else
  653. char buf[256];
  654. # endif
  655. } _Xttynameparams;
  656. # define _XGetlogin(p) (getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
  657. # define _XTtyname(f,p) \
  658. (ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
  659. #else
  660. /* Pre-POSIX API.
  661. *
  662. * extern char *getlogin_r(char *, size_t);
  663. * extern char *ttyname_r(int, char *, size_t);
  664. */
  665. typedef struct {
  666. # if defined(MAXLOGNAME)
  667. char buf[MAXLOGNAME];
  668. # elif defined(LOGIN_NAME_MAX)
  669. char buf[LOGIN_NAME_MAX];
  670. # else
  671. char buf[64];
  672. # endif
  673. } _Xgetloginparams;
  674. typedef struct {
  675. # ifdef TTY_NAME_MAX
  676. char buf[TTY_NAME_MAX];
  677. # elif defined(_POSIX_TTY_NAME_MAX)
  678. char buf[_POSIX_TTY_NAME_MAX];
  679. # elif defined(_POSIX_PATH_MAX)
  680. char buf[_POSIX_PATH_MAX];
  681. # else
  682. char buf[256];
  683. # endif
  684. } _Xttynameparams;
  685. # define _XGetlogin(p) getlogin_r((p).buf, sizeof((p).buf))
  686. # define _XTtyname(f,p) ttyname_r((f), (p).buf, sizeof((p).buf))
  687. #endif /* X_INCLUDE_UNISTD_H */
  688. #if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
  689. # define _XOS_INCLUDED_UNISTD_H
  690. #endif
  691. /***** <string.h> wrappers *****/
  692. /*
  693. * Effective prototypes for <string.h> wrappers:
  694. *
  695. * #define X_INCLUDE_STRING_H
  696. * #define XOS_USE_..._LOCKING
  697. * #include <X11/Xos_r.h>
  698. *
  699. * typedef ... _Xstrtokparams;
  700. *
  701. * char *_XStrtok(char *, const char*, _Xstrtokparams);
  702. */
  703. #if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
  704. /* <string.h> has already been included by <X11/Xos.h> */
  705. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
  706. # define XOS_USE_MTSAFE_STRINGAPI 1
  707. # endif
  708. #endif
  709. #if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
  710. /* Do nothing. */
  711. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  712. /* Use regular, unsafe API. */
  713. typedef int _Xstrtokparams; /* dummy */
  714. # define _XStrtok(s1,s2,p) \
  715. ( p = 0, (void)p, strtok((s1),(s2)) )
  716. #elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
  717. /* Systems with thread support but no _r API. */
  718. typedef char *_Xstrtokparams;
  719. # define _XStrtok(s1,s2,p) \
  720. ( (_Xos_processLock), \
  721. ((p) = strtok((s1),(s2))), \
  722. (_Xos_processUnlock), \
  723. (p) )
  724. #else
  725. /* POSIX or pre-POSIX API. */
  726. typedef char * _Xstrtokparams;
  727. # define _XStrtok(s1,s2,p) strtok_r((s1),(s2),&(p))
  728. #endif /* X_INCLUDE_STRING_H */
  729. /***** <time.h> wrappers *****/
  730. /*
  731. * Effective prototypes for <time.h> wrappers:
  732. *
  733. * #define X_INCLUDE_TIME_H
  734. * #define XOS_USE_..._LOCKING
  735. * #include <X11/Xos_r.h>
  736. *
  737. * typedef ... _Xatimeparams;
  738. * typedef ... _Xctimeparams;
  739. * typedef ... _Xgtimeparams;
  740. * typedef ... _Xltimeparams;
  741. *
  742. * char *_XAsctime(const struct tm *, _Xatimeparams);
  743. * char *_XCtime(const time_t *, _Xctimeparams);
  744. * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
  745. * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
  746. */
  747. #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
  748. # include <time.h>
  749. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
  750. # define XOS_USE_MTSAFE_TIMEAPI 1
  751. # endif
  752. #endif
  753. #if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
  754. /* Do nothing. */
  755. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  756. /* Use regular, unsafe API. */
  757. typedef int _Xatimeparams; /* dummy */
  758. # define _XAsctime(t,p) asctime((t))
  759. typedef int _Xctimeparams; /* dummy */
  760. # define _XCtime(t,p) ctime((t))
  761. typedef int _Xgtimeparams; /* dummy */
  762. # define _XGmtime(t,p) gmtime((t))
  763. typedef int _Xltimeparams; /* dummy */
  764. # define _XLocaltime(t,p) localtime((t))
  765. #elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
  766. /* Systems with thread support but no _r API. */
  767. typedef struct {
  768. # ifdef TIMELEN
  769. char buf[TIMELEN];
  770. # else
  771. char buf[26];
  772. # endif
  773. char *result;
  774. } _Xctimeparams, _Xatimeparams;
  775. typedef struct {
  776. struct tm buf;
  777. struct tm *result;
  778. } _Xgtimeparams, _Xltimeparams;
  779. # define _XAsctime(t,p) \
  780. ( (_Xos_processLock), \
  781. (((p).result = asctime((t))) ? \
  782. (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
  783. 0), \
  784. (_Xos_processUnlock), \
  785. (p).result )
  786. # define _XCtime(t,p) \
  787. ( (_Xos_processLock), \
  788. (((p).result = ctime((t))) ? \
  789. (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
  790. 0), \
  791. (_Xos_processUnlock), \
  792. (p).result )
  793. # define _XGmtime(t,p) \
  794. ( (_Xos_processLock), \
  795. (((p).result = gmtime(t)) ? \
  796. (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
  797. 0), \
  798. (_Xos_processUnlock), \
  799. (p).result )
  800. # define _XLocaltime(t,p) \
  801. ( (_Xos_processLock), \
  802. (((p).result = localtime(t)) ? \
  803. (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
  804. 0), \
  805. (_Xos_processUnlock), \
  806. (p).result )
  807. #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(hpV4)
  808. /* Returns (int)0 on success.
  809. *
  810. * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
  811. * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
  812. * extern int gmtime_r(const time_t *timer, struct tm *result);
  813. * extern int localtime_r(const time_t *timer, struct tm *result);
  814. */
  815. # ifdef TIMELEN
  816. typedef char _Xatimeparams[TIMELEN];
  817. typedef char _Xctimeparams[TIMELEN];
  818. # else
  819. typedef char _Xatimeparams[26];
  820. typedef char _Xctimeparams[26];
  821. # endif
  822. typedef struct tm _Xgtimeparams;
  823. typedef struct tm _Xltimeparams;
  824. # define _XAsctime(t,p) (asctime_r((t),(p),sizeof((p))) ? NULL : (p))
  825. # define _XCtime(t,p) (ctime_r((t),(p),sizeof((p))) ? NULL : (p))
  826. # define _XGmtime(t,p) (gmtime_r((t),&(p)) ? NULL : &(p))
  827. # define _XLocaltime(t,p) (localtime_r((t),&(p)) ? NULL : &(p))
  828. #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
  829. /* Returns NULL on failure. Solaris 2.5
  830. *
  831. * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
  832. * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
  833. * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
  834. * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
  835. */
  836. # ifdef TIMELEN
  837. typedef char _Xatimeparams[TIMELEN];
  838. typedef char _Xctimeparams[TIMELEN];
  839. # else
  840. typedef char _Xatimeparams[26];
  841. typedef char _Xctimeparams[26];
  842. # endif
  843. typedef struct tm _Xgtimeparams;
  844. typedef struct tm _Xltimeparams;
  845. # define _XAsctime(t,p) asctime_r((t),(p),sizeof((p)))
  846. # define _XCtime(t,p) ctime_r((t),(p),sizeof((p)))
  847. # define _XGmtime(t,p) gmtime_r((t),&(p))
  848. # define _XLocaltime(t,p) localtime_r((t),&(p))
  849. #else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
  850. /* POSIX final API.
  851. * extern char *asctime_r(const struct tm *timeptr, char *buffer);
  852. * extern char *ctime_r(const time_t *timer, char *buffer);
  853. * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
  854. * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
  855. */
  856. # ifdef TIMELEN
  857. typedef char _Xatimeparams[TIMELEN];
  858. typedef char _Xctimeparams[TIMELEN];
  859. # else
  860. typedef char _Xatimeparams[26];
  861. typedef char _Xctimeparams[26];
  862. # endif
  863. typedef struct tm _Xgtimeparams;
  864. typedef struct tm _Xltimeparams;
  865. # define _XAsctime(t,p) asctime_r((t),(p))
  866. # define _XCtime(t,p) ctime_r((t),(p))
  867. # define _XGmtime(t,p) gmtime_r((t),&(p))
  868. # define _XLocaltime(t,p) localtime_r((t),&(p))
  869. #endif /* X_INCLUDE_TIME_H */
  870. #if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
  871. # define _XOS_INCLUDED_TIME_H
  872. #endif
  873. /***** <grp.h> wrappers *****/
  874. /*
  875. * Effective prototypes for <grp.h> wrappers:
  876. *
  877. * NOTE: On systems lacking appropriate _r functions Getgrgid() and
  878. * Getgrnam() do NOT copy the list of group members!
  879. *
  880. * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
  881. * are not included in POSIX.
  882. *
  883. * #define X_INCLUDE_GRP_H
  884. * #define XOS_USE_..._LOCKING
  885. * #include <X11/Xos_r.h>
  886. *
  887. * typedef ... _Xgetgrparams;
  888. *
  889. * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
  890. * struct group *_XGetgrnam(const char *, _Xgetgrparams);
  891. */
  892. #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
  893. # include <grp.h>
  894. # if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
  895. # define XOS_USE_MTSAFE_GRPAPI 1
  896. # endif
  897. #endif
  898. #if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
  899. /* Do nothing. */
  900. #elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
  901. /* Use regular, unsafe API. */
  902. typedef int _Xgetgrparams; /* dummy */
  903. #define _XGetgrgid(g,p) getgrgid((g))
  904. #define _XGetgrnam(n,p) getgrnam((n))
  905. #elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
  906. /* Systems with thread support but no _r API. UnixWare 2.0. */
  907. typedef struct {
  908. struct group grp;
  909. char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
  910. struct group *pgrp;
  911. size_t len;
  912. } _Xgetgrparams;
  913. #ifdef SVR4
  914. /* Copy the gr_passwd field too. */
  915. # define _Xgrp_copyGroup(p) \
  916. ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
  917. ((p).grp.gr_name = (p).buf), \
  918. ((p).len = strlen((p).pgrp->gr_name)), \
  919. strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
  920. ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
  921. ((p).pgrp = &(p).grp), \
  922. 0 )
  923. #else
  924. # define _Xgrp_copyGroup(p) \
  925. ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
  926. ((p).grp.gr_name = (p).buf), \
  927. strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
  928. ((p).pgrp = &(p).grp), \
  929. 0 )
  930. #endif
  931. #define _XGetgrgid(g,p) \
  932. ( (_Xos_processLock), \
  933. (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
  934. (_Xos_processUnlock), \
  935. (p).pgrp )
  936. #define _XGetgrnam(n,p) \
  937. ( (_Xos_processLock), \
  938. (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
  939. (_Xos_processUnlock), \
  940. (p).pgrp )
  941. #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
  942. /* Non-POSIX API. Solaris.
  943. *
  944. * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
  945. * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
  946. */
  947. typedef struct {
  948. struct group grp;
  949. char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
  950. } _Xgetgrparams;
  951. #define _XGetgrgid(g,p) getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
  952. #define _XGetgrnam(n,p) getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
  953. #elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
  954. /* Non-POSIX API.
  955. * extern int getgrgid_r(gid_t, struct group *, char *, int);
  956. * extern int getgrnam_r(const char *, struct group *, char *, int);
  957. */
  958. typedef struct {
  959. struct group grp;
  960. char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
  961. } _Xgetgrparams;
  962. #define _XGetgrgid(g,p) \
  963. ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
  964. #define _XGetgrnam(n,p) \
  965. ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
  966. #else
  967. /* POSIX final API.
  968. *
  969. * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
  970. * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
  971. */
  972. typedef struct {
  973. struct group grp;
  974. char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
  975. struct group *result;
  976. } _Xgetgrparams;
  977. #define _XGetgrgid(g,p) \
  978. ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
  979. NULL : (p).result))
  980. #define _XGetgrnam(n,p) \
  981. ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
  982. NULL : (p).result))
  983. #endif
  984. #if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
  985. # define _XOS_INCLUDED_GRP_H
  986. #endif
  987. #ifdef __cplusplus
  988. } /* Close scope of 'extern "C"' declaration which encloses file. */
  989. #endif