/* * __sinit() is called whenever stdio's internal variables must be set up. */ void __sinit(void) { _THREAD_PRIVATE_MUTEX(__sinit_mutex); _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex); if (__sdidinit) { /* bail out if caller lost the race */ _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); return; } /* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */ for (size_t i = 0; i < 3; ++i) { _FILEEXT_SETUP(__sF+i, __sFext+i); } /* Initialize the pre-allocated (but initially unused) streams. */ for (size_t i = 0; i < FOPEN_MAX - 3; ++i) { _FILEEXT_SETUP(usual+i, usualext+i); } /* make sure we clean up on exit */ __atexit_register_cleanup(_cleanup); /* conservative */ __sdidinit = 1; _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); }
void endgrent(void) { _THREAD_PRIVATE_MUTEX_LOCK(gr); endgrent_basic(); _THREAD_PRIVATE_MUTEX_UNLOCK(gr); }
int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t buflen, struct passwd **pwretp) { struct passwd *pwret = NULL; int flags = 0, *flagsp; _THREAD_PRIVATE_MUTEX_LOCK(pw); if (!_pw_db && !__initdb()) goto fail; if (pw == &_pw_passwd) flagsp = &_pw_flags; else flagsp = &flags; #ifdef YP if (__has_yppw()) pwret = __yppwlookup(LOOKUP_BYUID, NULL, uid, pw, buf, buflen, flagsp); #endif /* YP */ if (!pwret) pwret = _pwhashbyuid(uid, buf, buflen, pw, flagsp); if (!_pw_stayopen) { (void)(_pw_db->close)(_pw_db); _pw_db = NULL; } fail: if (pwretp) *pwretp = pwret; _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (pwret ? 0 : 1); }
/* * Find a free FILE for fopen et al. */ FILE * __sfp(void) { FILE *fp; int n; struct glue *g; if (!__sdidinit) __sinit(); _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex); for (g = &__sglue; g != NULL; g = g->next) { for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) if (fp->_flags == 0) goto found; } /* release lock while mallocing */ _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex); if ((g = moreglue(NDYNAMIC)) == NULL) return (NULL); _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex); lastglue->next = g; lastglue = g; fp = g->iobs; found: fp->_flags = 1; /* reserve this slot; caller sets real flags */ _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex); fp->_p = NULL; /* no current pointer */ fp->_w = 0; /* nothing to read or write */ fp->_r = 0; fp->_bf._base = NULL; /* no buffer */ fp->_bf._size = 0; fp->_lbfsize = 0; /* not line buffered */ fp->_file = -1; /* no file */ /* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */ fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; _FILEEXT_INIT(fp); return (fp); }
int setlogin(const char *name) { int ret; _THREAD_PRIVATE_MUTEX_LOCK(logname); ret = _setlogin(name); if (ret == 0) logname_valid = 0; _THREAD_PRIVATE_MUTEX_UNLOCK(logname); return ret; }
struct group * _getgrent_yp(int *foundyp) { struct group *p_gr = (struct group*)_THREAD_PRIVATE(gr, _gr_group, NULL); struct group_storage *gs = (struct group_storage *)_THREAD_PRIVATE(gr_storage, gr_storage, NULL); _THREAD_PRIVATE_MUTEX_LOCK(gr); if ((!_gr_fp && !start_gr()) || !grscan(0, 0, NULL, p_gr, gs, foundyp)) p_gr = NULL; _THREAD_PRIVATE_MUTEX_UNLOCK(gr); return (p_gr); }
int getlogin_r(char *name, size_t namelen) { int logname_size; _THREAD_PRIVATE_MUTEX_LOCK(logname); if (!logname_valid) { if (_getlogin(logname, sizeof(logname) - 1) < 0) { _THREAD_PRIVATE_MUTEX_UNLOCK(logname); return errno; } logname_valid = 1; logname[MAXLOGNAME] = '\0'; /* paranoia */ } logname_size = strlen(logname) + 1; if (namelen < logname_size) { _THREAD_PRIVATE_MUTEX_UNLOCK(logname); return ERANGE; } memcpy(name, logname, logname_size); _THREAD_PRIVATE_MUTEX_UNLOCK(logname); return 0; }
int setgroupent(int stayopen) { int retval; _THREAD_PRIVATE_MUTEX_LOCK(gr); if (!start_gr()) retval = 0; else { _gr_stayopen = stayopen; retval = 1; } _THREAD_PRIVATE_MUTEX_UNLOCK(gr); return (retval); }
static struct group * getgrgid_gs(gid_t gid, struct group *p_gr, struct group_storage *gs) { int rval; _THREAD_PRIVATE_MUTEX_LOCK(gr); if (!start_gr()) rval = 0; else { rval = grscan(1, gid, NULL, p_gr, gs, NULL); if (!_gr_stayopen) endgrent_basic(); } _THREAD_PRIVATE_MUTEX_UNLOCK(gr); return(rval ? p_gr : NULL); }
/* * XXX. Force immediate allocation of internal memory. Not used by stdio, * but documented historically for certain applications. Bad applications. */ void f_prealloc(void) { struct glue *g; int n; n = getdtablesize() - FOPEN_MAX + 20; /* 20 for slop. */ for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next) /* void */; if (n > 0 && ((g = moreglue(n)) != NULL)) { _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex); lastglue->next = g; lastglue = g; _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex); } }
int setpassent(int stayopen) { _THREAD_PRIVATE_MUTEX_LOCK(pw); _pw_keynum = 0; _pw_stayopen = stayopen; #ifdef YP __ypmode = YPMODE_NONE; free(__ypcurrent); __ypcurrent = NULL; __ypexclude_free(&__ypexhead); __ypproto = NULL; #endif _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (1); }
/* * __sinit() is called whenever stdio's internal variables must be set up. */ void __sinit(void) { _THREAD_PRIVATE_MUTEX(__sinit_mutex); int i; _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex); if (__sdidinit) goto out; /* bail out if caller lost the race */ for (i = 0; i < FOPEN_MAX - 3; i++) { _FILEEXT_SETUP(usual+i, usualext+i); } /* make sure we clean up on exit */ __atexit_register_cleanup(_cleanup); /* conservative */ __sdidinit = 1; out: _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); }
void endpwent(void) { _THREAD_PRIVATE_MUTEX_LOCK(pw); _pw_keynum = 0; if (_pw_db) { (void)(_pw_db->close)(_pw_db); _pw_db = NULL; } #ifdef YP __ypmode = YPMODE_NONE; if (__ypcurrent) free(__ypcurrent); __ypcurrent = NULL; __ypexclude_free(&__ypexhead); __ypproto = NULL; #endif _THREAD_PRIVATE_MUTEX_UNLOCK(pw); }
static int getpwuid_internal(uid_t uid, struct passwd *pw, char *buf, size_t buflen, struct passwd **pwretp, int shadow) { struct passwd *pwret = NULL; int flags = 0, *flagsp; int my_errno = 0; int saved_errno, tmp_errno; _THREAD_PRIVATE_MUTEX_LOCK(pw); saved_errno = errno; errno = 0; if (!_pw_db && !__initdb(shadow)) goto fail; if (pw == &_pw_passwd) flagsp = &_pw_flags; else flagsp = &flags; #ifdef YP if (__has_yppw()) pwret = __yppwlookup(LOOKUP_BYUID, NULL, uid, pw, buf, buflen, flagsp); #endif /* YP */ if (!pwret) pwret = _pwhashbyuid(uid, buf, buflen, pw, flagsp); if (!_pw_stayopen) { tmp_errno = errno; (void)(_pw_db->close)(_pw_db); _pw_db = NULL; errno = tmp_errno; } fail: if (pwretp) *pwretp = pwret; if (pwret == NULL) my_errno = errno; errno = saved_errno; _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (my_errno); }
int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t buflen, struct passwd **pwretp) { struct passwd *pwret = NULL; int flags = 0, *flagsp; DB *savedb; _THREAD_PRIVATE_MUTEX_LOCK(pw); savedb = _pw_db; if (!_pw_db && !__initdb()) goto fail; if (pw == &_pw_passwd) flagsp = &_pw_flags; else flagsp = &flags; #ifdef YP if (__has_yppw()) pwret = __yppwlookup(LOOKUP_BYNAME, (char *)name, 0, pw, buf, buflen, flagsp); #endif /* YP */ if (!pwret) pwret = _pwhashbyname(name, buf, buflen, pw, flagsp); if (savedb != _pw_db || !_pw_stayopen) { (void)(_pw_db->close)(_pw_db); _pw_db = NULL; } fail: if (pwretp) *pwretp = pwret; _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (pwret ? 0 : 1); }
struct passwd * getpwent(void) { #ifdef YP static char *name = NULL; char *map; #endif char bf[1 + sizeof(_pw_keynum)]; struct passwd *pw = NULL; DBT key; _THREAD_PRIVATE_MUTEX_LOCK(pw); if (!_pw_db && !__initdb()) goto done; #ifdef YP map = PASSWD_BYNAME; if (__getpwent_has_yppw == -1) __getpwent_has_yppw = __has_yppw(); again: if (__getpwent_has_yppw && (__ypmode != YPMODE_NONE)) { const char *user, *host, *dom; int keylen, datalen, r, s; char *key, *data = NULL; if (!__ypdomain) { if (_yp_check(&__ypdomain) == 0) { __ypmode = YPMODE_NONE; goto again; } } switch (__ypmode) { case YPMODE_FULL: if (__ypcurrent) { r = yp_next(__ypdomain, map, __ypcurrent, __ypcurrentlen, &key, &keylen, &data, &datalen); free(__ypcurrent); __ypcurrent = NULL; if (r != 0) { __ypmode = YPMODE_NONE; if (data) free(data); goto again; } __ypcurrent = key; __ypcurrentlen = keylen; } else { r = yp_first(__ypdomain, map, &__ypcurrent, &__ypcurrentlen, &data, &datalen); if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { __ypmode = YPMODE_NONE; if (data) free(data); goto again; } } bcopy(data, __ypline, datalen); free(data); break; case YPMODE_NETGRP: s = getnetgrent(&host, &user, &dom); if (s == 0) { /* end of group */ endnetgrent(); __ypmode = YPMODE_NONE; goto again; } if (user && *user) { r = yp_match(__ypdomain, map, user, strlen(user), &data, &datalen); } else goto again; if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { /* * if the netgroup is invalid, keep looking * as there may be valid users later on. */ if (data) free(data); goto again; } bcopy(data, __ypline, datalen); free(data); break; case YPMODE_USER: if (name) { r = yp_match(__ypdomain, map, name, strlen(name), &data, &datalen); __ypmode = YPMODE_NONE; free(name); name = NULL; if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { if (data) free(data); goto again; } bcopy(data, __ypline, datalen); free(data); } else { /* XXX */ __ypmode = YPMODE_NONE; goto again; } break; case YPMODE_NONE: /* NOTREACHED */ break; } __ypline[datalen] = '\0'; if (__ypparse(&_pw_passwd, __ypline, __yp_pw_flags)) goto again; pw = &_pw_passwd; goto done; } #endif ++_pw_keynum; bf[0] = _PW_KEYBYNUM; bcopy((char *)&_pw_keynum, &bf[1], sizeof(_pw_keynum)); key.data = (u_char *)bf; key.size = 1 + sizeof(_pw_keynum); if (__hashpw(&key, _pw_string, sizeof _pw_string, &_pw_passwd, &_pw_flags)) { #ifdef YP static long long __yppbuf[_PW_BUF_LEN / sizeof(long long)]; const char *user, *host, *dom; /* if we don't have YP at all, don't bother. */ if (__getpwent_has_yppw) { if (_pw_passwd.pw_name[0] == '+') { /* set the mode */ switch (_pw_passwd.pw_name[1]) { case '\0': __ypmode = YPMODE_FULL; break; case '@': __ypmode = YPMODE_NETGRP; setnetgrent(_pw_passwd.pw_name + 2); break; default: __ypmode = YPMODE_USER; name = strdup(_pw_passwd.pw_name + 1); break; } __ypproto_set(&_pw_passwd, __yppbuf, _pw_flags, &__yp_pw_flags); goto again; } else if (_pw_passwd.pw_name[0] == '-') { /* an attempted exclusion */ switch (_pw_passwd.pw_name[1]) { case '\0': break; case '@': setnetgrent(_pw_passwd.pw_name + 2); while (getnetgrent(&host, &user, &dom)) { if (user && *user) __ypexclude_add(&__ypexhead, user); } endnetgrent(); break; default: __ypexclude_add(&__ypexhead, _pw_passwd.pw_name + 1); break; } goto again; } } #endif pw = &_pw_passwd; goto done; } done: _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (pw); }