int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { struct dirent *dp; int saved_errno; saved_errno = errno; errno = 0; #ifdef _REENTRANT if (__isthreaded) { mutex_lock((mutex_t *)dirp->dd_lock); if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp)); mutex_unlock((mutex_t *)dirp->dd_lock); } else #endif if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp)); if (errno != 0) { if (dp == NULL) return (errno); } else errno = saved_errno; if (dp != NULL) *result = entry; else *result = NULL; return (0); }
struct dirent * readdir(DIR *dirp) { struct dirent *dp; #ifdef _REENTRANT if (__isthreaded) { mutex_lock((mutex_t *)dirp->dd_lock); dp = _readdir_unlocked(dirp, 1); mutex_unlock((mutex_t *)dirp->dd_lock); } else #endif dp = _readdir_unlocked(dirp, 1); return (dp); }
/* * seek to an entry in a directory. * Only values returned by "telldir" should be passed to seekdir. */ void _seekdir(DIR *dirp, long loc) { struct ddloc *lp; struct dirent *dp; if (__isthreaded) _pthread_mutex_lock(&dd_hash_lock); for (lp = dd_hash[LOCHASH(loc)]; lp; lp = lp->loc_next) { if (lp->loc_dirp == dirp && lp->loc_index == loc) break; } if (__isthreaded) _pthread_mutex_unlock(&dd_hash_lock); if (lp == NULL) return; if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) return; lseek(dirp->dd_fd, lp->loc_seek, SEEK_SET); dirp->dd_seek = lp->loc_seek; dirp->dd_loc = 0; dirp->dd_lastseek = loc; /* * Scan the buffer until we find dd_loc. If the directory * changed between the tell and seek it is possible to * load a new buffer or for dd_loc to not match directly. */ while (dirp->dd_loc < lp->loc_loc && dirp->dd_seek == lp->loc_seek) { dp = _readdir_unlocked(dirp, 0); if (dp == NULL) break; } }
struct dirent * readdir(DIR *dirp) { struct dirent *dp; _MUTEX_LOCK(&dirp->dd_lock); _readdir_unlocked(dirp, &dp, 1); _MUTEX_UNLOCK(&dirp->dd_lock); return (dp); }
/* * seek to an entry in a directory. * Only values returned by "telldir" should be passed to seekdir. */ void _seekdir_unlocked(DIR *dirp, long loc) { struct dirpos *lp; _DIAGASSERT(dirp != NULL); for (lp = dirp->dd_internal; lp; lp = lp->dp_next) if ((intptr_t)lp == loc) break; if (lp == NULL) return; if (lp->dp_loc == dirp->dd_loc && lp->dp_seek == dirp->dd_seek) return; dirp->dd_seek = lseek(dirp->dd_fd, lp->dp_seek, SEEK_SET); dirp->dd_loc = 0; while (dirp->dd_loc < lp->dp_loc) if (_readdir_unlocked(dirp, 0) == NULL) break; }