readdir.c revision 69656
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 69656 2000-12-06 03:15:49Z 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 411573Srgrimes#include <sys/param.h> 421573Srgrimes#include <dirent.h> 4353812Salfred#include <errno.h> 4461193Skris#include <string.h> 4553812Salfred#ifdef _THREAD_SAFE 4653812Salfred#include <pthread.h> 4753812Salfred#include "pthread_private.h" 4853812Salfred#endif _THREAD_SAFE 491573Srgrimes 501573Srgrimes/* 511573Srgrimes * get next entry in a directory. 521573Srgrimes */ 531573Srgrimesstruct dirent * 541573Srgrimesreaddir(dirp) 5569656Sdeischen DIR *dirp; 561573Srgrimes{ 5769656Sdeischen struct dirent *dp; 581573Srgrimes 591573Srgrimes for (;;) { 6023658Speter if (dirp->dd_loc >= dirp->dd_size) { 6123658Speter if (dirp->dd_flags & __DTF_READALL) 6223658Speter return (NULL); 6323658Speter dirp->dd_loc = 0; 6423658Speter } 6523658Speter if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { 661573Srgrimes dirp->dd_size = getdirentries(dirp->dd_fd, 671573Srgrimes dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); 681573Srgrimes if (dirp->dd_size <= 0) 6923658Speter return (NULL); 701573Srgrimes } 711573Srgrimes dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); 7233665Sjb if ((long)dp & 03L) /* bogus pointer check */ 7323658Speter return (NULL); 741573Srgrimes if (dp->d_reclen <= 0 || 751573Srgrimes dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) 7623658Speter return (NULL); 771573Srgrimes dirp->dd_loc += dp->d_reclen; 781573Srgrimes if (dp->d_ino == 0) 791573Srgrimes continue; 8023658Speter if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) 8123658Speter continue; 821573Srgrimes return (dp); 831573Srgrimes } 841573Srgrimes} 8553812Salfred 8653812Salfredint 8753812Salfredreaddir_r(dirp, entry, result) 8853812Salfred DIR *dirp; 8953812Salfred struct dirent *entry; 9053812Salfred struct dirent **result; 9153812Salfred{ 9253812Salfred struct dirent *dp; 9369656Sdeischen int saved_errno; 9469656Sdeischen#ifdef _THREAD_SAFE 9569656Sdeischen int ret; 9653812Salfred 9753892Salfred if ((ret = _FD_LOCK(dirp->dd_fd, FD_READ, NULL)) != 0) 9853892Salfred return (ret); 9953812Salfred#endif 10053892Salfred 10153892Salfred saved_errno = errno; 10253812Salfred errno = 0; 10353812Salfred dp = readdir(dirp); 10453892Salfred if (errno != 0) { 10553892Salfred if (dp == NULL) { 10653812Salfred#ifdef _THREAD_SAFE 10753892Salfred _FD_UNLOCK(dirp->dd_fd, FD_READ); 10853812Salfred#endif 10953892Salfred return (errno); 11053892Salfred } 11153892Salfred } else 11253892Salfred errno = saved_errno; 11353892Salfred 11453892Salfred if (dp != NULL) 11553812Salfred memcpy(entry, dp, sizeof *entry); 11653892Salfred 11753812Salfred#ifdef _THREAD_SAFE 11853812Salfred _FD_UNLOCK(dirp->dd_fd, FD_READ); 11953812Salfred#endif 12053892Salfred 12153892Salfred if (dp != NULL) 12253872Swes *result = entry; 12353892Salfred else 12453812Salfred *result = NULL; 12553892Salfred 12653892Salfred return (0); 12753812Salfred} 128