readdir.c revision 71579
11573Srgrimes/* 21573Srgrimes * Copyright (c) 1983, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311573Srgrimes * SUCH DAMAGE. 3253812Salfred * 3353812Salfred * $FreeBSD: head/lib/libc/gen/readdir.c 71579 2001-01-24 13:01:12Z deischen $ 3453812Salfred * 351573Srgrimes */ 361573Srgrimes 371573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 3823658Speterstatic char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; 391573Srgrimes#endif /* LIBC_SCCS and not lint */ 401573Srgrimes 4171579Sdeischen#include "namespace.h" 421573Srgrimes#include <sys/param.h> 431573Srgrimes#include <dirent.h> 4453812Salfred#include <errno.h> 4561193Skris#include <string.h> 4653812Salfred#include <pthread.h> 4771579Sdeischen#include "un-namespace.h" 481573Srgrimes 4971579Sdeischen#include "libc_private.h" 5071579Sdeischen 511573Srgrimes/* 521573Srgrimes * get next entry in a directory. 531573Srgrimes */ 541573Srgrimesstruct dirent * 5571579Sdeischen_readdir_unlocked(dirp) 5669656Sdeischen DIR *dirp; 571573Srgrimes{ 5869656Sdeischen struct dirent *dp; 591573Srgrimes 601573Srgrimes for (;;) { 6123658Speter if (dirp->dd_loc >= dirp->dd_size) { 6223658Speter if (dirp->dd_flags & __DTF_READALL) 6323658Speter return (NULL); 6423658Speter dirp->dd_loc = 0; 6523658Speter } 6623658Speter if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { 6771579Sdeischen dirp->dd_size = _getdirentries(dirp->dd_fd, 681573Srgrimes dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); 691573Srgrimes if (dirp->dd_size <= 0) 7023658Speter return (NULL); 711573Srgrimes } 721573Srgrimes dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); 7333665Sjb if ((long)dp & 03L) /* bogus pointer check */ 7423658Speter return (NULL); 751573Srgrimes if (dp->d_reclen <= 0 || 761573Srgrimes dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) 7723658Speter return (NULL); 781573Srgrimes dirp->dd_loc += dp->d_reclen; 791573Srgrimes if (dp->d_ino == 0) 801573Srgrimes continue; 8123658Speter if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) 8223658Speter continue; 831573Srgrimes return (dp); 841573Srgrimes } 851573Srgrimes} 8653812Salfred 8771579Sdeischenstruct dirent * 8871579Sdeischenreaddir(dirp) 8971579Sdeischen DIR *dirp; 9071579Sdeischen{ 9171579Sdeischen struct dirent *dp; 9271579Sdeischen 9371579Sdeischen if (__isthreaded) { 9471579Sdeischen _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); 9571579Sdeischen dp = _readdir_unlocked(dirp); 9671579Sdeischen _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); 9771579Sdeischen } 9871579Sdeischen else 9971579Sdeischen dp = _readdir_unlocked(dirp); 10071579Sdeischen return (dp); 10171579Sdeischen} 10271579Sdeischen 10353812Salfredint 10453812Salfredreaddir_r(dirp, entry, result) 10553812Salfred DIR *dirp; 10653812Salfred struct dirent *entry; 10753812Salfred struct dirent **result; 10853812Salfred{ 10953812Salfred struct dirent *dp; 11069656Sdeischen int saved_errno; 11153812Salfred 11253892Salfred saved_errno = errno; 11353812Salfred errno = 0; 11471579Sdeischen if (__isthreaded) { 11571579Sdeischen _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); 11671579Sdeischen if ((dp = _readdir_unlocked(dirp)) != NULL) 11771579Sdeischen memcpy(entry, dp, sizeof *entry); 11871579Sdeischen _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); 11971579Sdeischen } 12071579Sdeischen else if ((dp = _readdir_unlocked(dirp)) != NULL) 12171579Sdeischen memcpy(entry, dp, sizeof *entry); 12271579Sdeischen 12353892Salfred if (errno != 0) { 12471579Sdeischen if (dp == NULL) 12553892Salfred return (errno); 12653892Salfred } else 12753892Salfred errno = saved_errno; 12853892Salfred 12953892Salfred if (dp != NULL) 13053872Swes *result = entry; 13153892Salfred else 13253812Salfred *result = NULL; 13353892Salfred 13453892Salfred return (0); 13553812Salfred} 136