os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/unix/tclUnixCompat.c
Update contrib.
4 * Written by: Zoran Vasiljevic (vasiljevic@users.sourceforge.net).
6 * See the file "license.terms" for information on usage and redistribution
7 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 * RCS: @(#) $Id: tclUnixCompat.c,v 1.1.2.10 2006/09/12 22:05:03 andreas_kupries Exp $
21 * Used to pad structures at size'd boundaries
23 * This macro assumes that the pointer 'buffer' was created from an
24 * aligned pointer by adding the 'length'. If this 'length' was not a
25 * multiple of the 'size' the result is unaligned and PadBuffer
26 * corrects both the pointer, _and_ the 'length'. The latter means
27 * that future increments of 'buffer' by 'length' stay aligned.
30 #define PadBuffer(buffer, length, size) \
31 if (((length) % (size))) { \
32 (buffer) += ((size) - ((length) % (size))); \
33 (length) += ((size) - ((length) % (size))); \
37 * Per-thread private storage used to store values
38 * returned from MT-unsafe library calls.
43 typedef struct ThreadSpecificData {
51 #if !defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR)
58 static Tcl_ThreadDataKey dataKey;
60 #if ((!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \
61 (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))) || \
62 !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R) || \
63 !defined(HAVE_GETGRNAM_R) || !defined(HAVE_GETGRGID_R)
66 * Mutex to lock access to MT-unsafe calls. This is just to protect
67 * our own usage. It does not protect us from others calling the
68 * same functions without (or using some different) lock.
71 static Tcl_Mutex compatLock;
74 *---------------------------------------------------------------------------
78 * Copies array of NULL-terminated or fixed-length strings
79 * to the private buffer, honouring the size of the buffer.
82 * Number of bytes copied on success or -1 on error (errno = ERANGE)
87 *---------------------------------------------------------------------------
91 CopyArray(char **src, int elsize, char *buf, int buflen)
99 for (i = 0; src[i] != NULL; i++) {
100 /* Empty loop to count howmany */
102 if ((sizeof(char *)*(i + 1)) > buflen) {
105 len = (sizeof(char *)*(i + 1)); /* Leave place for the array */
107 p = buf + (sizeof(char *)*(i + 1));
108 for (j = 0; j < i; j++) {
110 len += strlen(src[j]) + 1;
120 memcpy(p, src[j], elsize);
132 *---------------------------------------------------------------------------
136 * Copies a NULL-terminated string to the private buffer,
137 * honouring the size of the buffer
140 * 0 success or -1 on error (errno = ERANGE)
145 *---------------------------------------------------------------------------
150 CopyString(char *src, char *buf, int buflen)
155 len += strlen(src) + 1;
164 #endif /* ((!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \
165 (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))) || \
166 !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R) || \
167 !defined(HAVE_GETGRNAM_R) || !defined(HAVE_GETGRGID_R) */
169 #if (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \
170 (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))
173 *---------------------------------------------------------------------------
177 * Copies string fields of the hostnent structure to the
178 * private buffer, honouring the size of the buffer.
181 * Number of bytes copied on success or -1 on error (errno = ERANGE)
186 *---------------------------------------------------------------------------
190 CopyHostent(struct hostent *tgtPtr, char *buf, int buflen)
195 copied = CopyString(tgtPtr->h_name, p, buflen - len);
201 tgtPtr->h_name = (copied > 0) ? p : NULL;
205 PadBuffer(p, len, sizeof(char *));
206 copied = CopyArray(tgtPtr->h_aliases, -1, p, buflen - len);
210 tgtPtr->h_aliases = (copied > 0) ? (char **)p : NULL;
214 PadBuffer(p, len, sizeof(char *));
215 copied = CopyArray(tgtPtr->h_addr_list, tgtPtr->h_length, p, buflen - len);
219 tgtPtr->h_addr_list = (copied > 0) ? (char **)p : NULL;
223 #endif /* (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \
224 (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR)) */
226 #if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R)
229 *---------------------------------------------------------------------------
233 * Copies string fields of the passwd structure to the
234 * private buffer, honouring the size of the buffer.
237 * 0 on success or -1 on error (errno = ERANGE)
240 * We are not copying the gecos field as it may not be supported
243 *---------------------------------------------------------------------------
247 CopyPwd(struct passwd *tgtPtr, char *buf, int buflen)
252 copied = CopyString(tgtPtr->pw_name, p, buflen - len);
258 tgtPtr->pw_name = (copied > 0) ? p : NULL;
262 copied = CopyString(tgtPtr->pw_passwd, p, buflen - len);
266 tgtPtr->pw_passwd = (copied > 0) ? p : NULL;
270 copied = CopyString(tgtPtr->pw_dir, p, buflen - len);
274 tgtPtr->pw_dir = (copied > 0) ? p : NULL;
278 copied = CopyString(tgtPtr->pw_shell, p, buflen - len);
282 tgtPtr->pw_shell = (copied > 0) ? p : NULL;
286 #endif /* !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R) */
288 #if !defined(HAVE_GETGRNAM_R) || !defined(HAVE_GETGRGID_R)
291 *---------------------------------------------------------------------------
295 * Copies string fields of the group structure to the
296 * private buffer, honouring the size of the buffer.
299 * 0 on success or -1 on error (errno = ERANGE)
304 *---------------------------------------------------------------------------
308 CopyGrp(struct group *tgtPtr, char *buf, int buflen)
310 register char *p = buf;
311 register int copied, len = 0;
314 copied = CopyString(tgtPtr->gr_name, p, buflen - len);
320 tgtPtr->gr_name = (copied > 0) ? p : NULL;
325 copied = CopyString(tgtPtr->gr_passwd, p, buflen - len);
329 tgtPtr->gr_passwd = (copied > 0) ? p : NULL;
333 /* Copy group members */
334 PadBuffer(p, len, sizeof(char *));
335 copied = CopyArray((char **)tgtPtr->gr_mem, -1, p, buflen - len);
339 tgtPtr->gr_mem = (copied > 0) ? (char **)p : NULL;
343 #endif /* !defined(HAVE_GETGRNAM_R) || !defined(HAVE_GETGRGID_R) */
345 #endif /* TCL_THREADS */
349 *---------------------------------------------------------------------------
353 * Thread-safe wrappers for getpwnam().
354 * See "man getpwnam" for more details.
357 * Pointer to struct passwd on success or NULL on error.
362 *---------------------------------------------------------------------------
366 TclpGetPwNam(const char *name)
368 #if !defined(TCL_THREADS)
369 return getpwnam(name);
371 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
373 #if defined(HAVE_GETPWNAM_R_5)
374 struct passwd *pwPtr = NULL;
375 return (getpwnam_r(name, &tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf),
376 &pwPtr) == 0 && pwPtr != NULL) ? &tsdPtr->pwd : NULL;
378 #elif defined(HAVE_GETPWNAM_R_4)
379 return getpwnam_r(name, &tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf));
382 struct passwd *pwPtr;
383 Tcl_MutexLock(&compatLock);
384 pwPtr = getpwnam(name);
386 tsdPtr->pwd = *pwPtr;
387 pwPtr = &tsdPtr->pwd;
388 if (CopyPwd(&tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf)) == -1) {
392 Tcl_MutexUnlock(&compatLock);
395 return NULL; /* Not reached */
396 #endif /* TCL_THREADS */
401 *---------------------------------------------------------------------------
405 * Thread-safe wrappers for getpwuid().
406 * See "man getpwuid" for more details.
409 * Pointer to struct passwd on success or NULL on error.
414 *---------------------------------------------------------------------------
418 TclpGetPwUid(uid_t uid)
420 #if !defined(TCL_THREADS)
421 return getpwuid(uid);
423 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
425 #if defined(HAVE_GETPWUID_R_5)
426 struct passwd *pwPtr = NULL;
427 return (getpwuid_r(uid, &tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf),
428 &pwPtr) == 0 && pwPtr != NULL) ? &tsdPtr->pwd : NULL;
430 #elif defined(HAVE_GETPWUID_R_4)
431 return getpwuid_r(uid, &tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf));
434 struct passwd *pwPtr;
435 Tcl_MutexLock(&compatLock);
436 pwPtr = getpwuid(uid);
438 tsdPtr->pwd = *pwPtr;
439 pwPtr = &tsdPtr->pwd;
440 if (CopyPwd(&tsdPtr->pwd, tsdPtr->pbuf, sizeof(tsdPtr->pbuf)) == -1) {
444 Tcl_MutexUnlock(&compatLock);
447 return NULL; /* Not reached */
448 #endif /* TCL_THREADS */
453 *---------------------------------------------------------------------------
457 * Thread-safe wrappers for getgrnam().
458 * See "man getgrnam" for more details.
461 * Pointer to struct group on success or NULL on error.
466 *---------------------------------------------------------------------------
470 TclpGetGrNam(const char *name)
472 #if !defined(TCL_THREADS)
473 return getgrnam(name);
475 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
477 #if defined(HAVE_GETGRNAM_R_5)
478 struct group *grPtr = NULL;
479 return (getgrnam_r(name, &tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf),
480 &grPtr) == 0 && grPtr != NULL) ? &tsdPtr->grp : NULL;
482 #elif defined(HAVE_GETGRNAM_R_4)
483 return getgrnam_r(name, &tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf));
487 Tcl_MutexLock(&compatLock);
488 grPtr = getgrnam(name);
490 tsdPtr->grp = *grPtr;
491 grPtr = &tsdPtr->grp;
492 if (CopyGrp(&tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf)) == -1) {
496 Tcl_MutexUnlock(&compatLock);
499 return NULL; /* Not reached */
500 #endif /* TCL_THREADS */
505 *---------------------------------------------------------------------------
509 * Thread-safe wrappers for getgrgid().
510 * See "man getgrgid" for more details.
513 * Pointer to struct group on success or NULL on error.
518 *---------------------------------------------------------------------------
522 TclpGetGrGid(gid_t gid)
524 #if !defined(TCL_THREADS)
525 return getgrgid(gid);
527 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
529 #if defined(HAVE_GETGRGID_R_5)
530 struct group *grPtr = NULL;
531 return (getgrgid_r(gid, &tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf),
532 &grPtr) == 0 && grPtr != NULL) ? &tsdPtr->grp : NULL;
534 #elif defined(HAVE_GETGRGID_R_4)
535 return getgrgid_r(gid, &tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf));
539 Tcl_MutexLock(&compatLock);
540 grPtr = getgrgid(gid);
542 tsdPtr->grp = *grPtr;
543 grPtr = &tsdPtr->grp;
544 if (CopyGrp(&tsdPtr->grp, tsdPtr->gbuf, sizeof(tsdPtr->gbuf)) == -1) {
548 Tcl_MutexUnlock(&compatLock);
551 return NULL; /* Not reached */
552 #endif /* TCL_THREADS */
557 *---------------------------------------------------------------------------
559 * TclpGetHostByName --
561 * Thread-safe wrappers for gethostbyname().
562 * See "man gethostbyname" for more details.
565 * Pointer to struct hostent on success or NULL on error.
570 *---------------------------------------------------------------------------
574 TclpGetHostByName(const char *name)
576 #if !defined(TCL_THREADS) || defined(HAVE_MTSAFE_GETHOSTBYNAME)
577 return gethostbyname(name);
579 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
581 #if defined(HAVE_GETHOSTBYNAME_R_5)
583 return gethostbyname_r(name, &tsdPtr->hent, tsdPtr->hbuf,
584 sizeof(tsdPtr->hbuf), &h_errno);
586 #elif defined(HAVE_GETHOSTBYNAME_R_6)
587 struct hostent *hePtr;
589 return (gethostbyname_r(name, &tsdPtr->hent, tsdPtr->hbuf,
590 sizeof(tsdPtr->hbuf), &hePtr, &h_errno) == 0) ?
591 &tsdPtr->hent : NULL;
593 #elif defined(HAVE_GETHOSTBYNAME_R_3)
594 struct hostent_data data;
595 return (gethostbyname_r(name, &tsdPtr->hent, &data) == 0) ?
596 &tsdPtr->hent : NULL;
598 struct hostent *hePtr;
599 Tcl_MutexLock(&compatLock);
600 hePtr = gethostbyname(name);
602 tsdPtr->hent = *hePtr;
603 hePtr = &tsdPtr->hent;
604 if (CopyHostent(&tsdPtr->hent, tsdPtr->hbuf,
605 sizeof(tsdPtr->hbuf)) == -1) {
609 Tcl_MutexUnlock(&compatLock);
612 return NULL; /* Not reached */
613 #endif /* TCL_THREADS */
618 *---------------------------------------------------------------------------
620 * TclpGetHostByAddr --
622 * Thread-safe wrappers for gethostbyaddr().
623 * See "man gethostbyaddr" for more details.
626 * Pointer to struct hostent on success or NULL on error.
631 *---------------------------------------------------------------------------
635 TclpGetHostByAddr(const char *addr, int length, int type)
637 #if !defined(TCL_THREADS) || defined(HAVE_MTSAFE_GETHOSTBYADDR)
638 return gethostbyaddr(addr, length, type);
640 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
642 #if defined(HAVE_GETHOSTBYADDR_R_7)
644 return gethostbyaddr_r(addr, length, type, &tsdPtr->hent, tsdPtr->hbuf,
645 sizeof(tsdPtr->hbuf), &h_errno);
647 #elif defined(HAVE_GETHOSTBYADDR_R_8)
648 struct hostent *hePtr;
650 return (gethostbyaddr_r(addr, length, type, &tsdPtr->hent, tsdPtr->hbuf,
651 sizeof(tsdPtr->hbuf), &hePtr, &h_errno) == 0) ?
652 &tsdPtr->hent : NULL;
654 struct hostent *hePtr;
655 Tcl_MutexLock(&compatLock);
656 hePtr = gethostbyaddr(addr, length, type);
658 tsdPtr->hent = *hePtr;
659 hePtr = &tsdPtr->hent;
660 if (CopyHostent(&tsdPtr->hent, tsdPtr->hbuf,
661 sizeof(tsdPtr->hbuf)) == -1) {
665 Tcl_MutexUnlock(&compatLock);
668 return NULL; /* Not reached */
669 #endif /* TCL_THREADS */