readdir.c revision 69656
1167465Smp/* 259243Sobrien * Copyright (c) 1983, 1993 359243Sobrien * The Regents of the University of California. All rights reserved. 459243Sobrien * 559243Sobrien * Redistribution and use in source and binary forms, with or without 659243Sobrien * modification, are permitted provided that the following conditions 759243Sobrien * are met: 859243Sobrien * 1. Redistributions of source code must retain the above copyright 959243Sobrien * notice, this list of conditions and the following disclaimer. 1059243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1159243Sobrien * notice, this list of conditions and the following disclaimer in the 1259243Sobrien * documentation and/or other materials provided with the distribution. 1359243Sobrien * 3. All advertising materials mentioning features or use of this software 1459243Sobrien * must display the following acknowledgement: 1559243Sobrien * This product includes software developed by the University of 1659243Sobrien * California, Berkeley and its contributors. 1759243Sobrien * 4. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 19100616Smp * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien * 3359243Sobrien * $FreeBSD: head/lib/libc/gen/readdir.c 69656 2000-12-06 03:15:49Z deischen $ 3459243Sobrien * 3559243Sobrien */ 3659243Sobrien 37167465Smp#if defined(LIBC_SCCS) && !defined(lint) 3859243Sobrienstatic char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; 3959243Sobrien#endif /* LIBC_SCCS and not lint */ 4059243Sobrien 4159243Sobrien#include <sys/param.h> 4259243Sobrien#include <dirent.h> 4359243Sobrien#include <errno.h> 44167465Smp#include <string.h> 4559243Sobrien#ifdef _THREAD_SAFE 46145479Smp#include <pthread.h> 4759243Sobrien#include "pthread_private.h" 48167465Smp#endif _THREAD_SAFE 49167465Smp 5059243Sobrien/* 5159243Sobrien * get next entry in a directory. 52167465Smp */ 5359243Sobrienstruct dirent * 54100616Smpreaddir(dirp) 55100616Smp DIR *dirp; 5659243Sobrien{ 57167465Smp struct dirent *dp; 5859243Sobrien 59145479Smp for (;;) { 60100616Smp if (dirp->dd_loc >= dirp->dd_size) { 61100616Smp if (dirp->dd_flags & __DTF_READALL) 62100616Smp return (NULL); 63100616Smp dirp->dd_loc = 0; 64100616Smp } 65100616Smp if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { 66167465Smp dirp->dd_size = getdirentries(dirp->dd_fd, 67100616Smp dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); 68100616Smp if (dirp->dd_size <= 0) 69100616Smp return (NULL); 70167465Smp } 71167465Smp dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); 7259243Sobrien if ((long)dp & 03L) /* bogus pointer check */ 7359243Sobrien return (NULL); 7459243Sobrien if (dp->d_reclen <= 0 || 7559243Sobrien dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) 7659243Sobrien return (NULL); 7759243Sobrien dirp->dd_loc += dp->d_reclen; 7859243Sobrien if (dp->d_ino == 0) 79167465Smp continue; 8059243Sobrien if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) 8159243Sobrien continue; 8259243Sobrien return (dp); 8359243Sobrien } 8459243Sobrien} 8559243Sobrien 8659243Sobrienint 8759243Sobrienreaddir_r(dirp, entry, result) 8859243Sobrien DIR *dirp; 8959243Sobrien struct dirent *entry; 9059243Sobrien struct dirent **result; 9159243Sobrien{ 9259243Sobrien struct dirent *dp; 9359243Sobrien int saved_errno; 9459243Sobrien#ifdef _THREAD_SAFE 9559243Sobrien int ret; 9659243Sobrien 9759243Sobrien if ((ret = _FD_LOCK(dirp->dd_fd, FD_READ, NULL)) != 0) 98145479Smp return (ret); 9959243Sobrien#endif 100145479Smp 10159243Sobrien saved_errno = errno; 10259243Sobrien errno = 0; 10359243Sobrien dp = readdir(dirp); 10459243Sobrien if (errno != 0) { 10559243Sobrien if (dp == NULL) { 10659243Sobrien#ifdef _THREAD_SAFE 10759243Sobrien _FD_UNLOCK(dirp->dd_fd, FD_READ); 10859243Sobrien#endif 10959243Sobrien return (errno); 110145479Smp } 111145479Smp } else 112145479Smp errno = saved_errno; 11359243Sobrien 11459243Sobrien if (dp != NULL) 11559243Sobrien memcpy(entry, dp, sizeof *entry); 11659243Sobrien 11759243Sobrien#ifdef _THREAD_SAFE 11859243Sobrien _FD_UNLOCK(dirp->dd_fd, FD_READ); 11959243Sobrien#endif 12059243Sobrien 12159243Sobrien if (dp != NULL) 12259243Sobrien *result = entry; 123100616Smp else 12459243Sobrien *result = NULL; 125100616Smp 126100616Smp return (0); 127100616Smp} 128100616Smp