dirent.c

Go to the documentation of this file.
00001 /*-
00002  * Copyright (c) 1991 The Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * This code is derived from software contributed to Berkeley by
00006  * Kenneth Almquist.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036 
00037 #ifndef lint
00038 static char sccsid[] = "@(#)dirent.c    5.1 (Berkeley) 3/7/91";
00039 #endif /* not lint */
00040 
00041 #include "shell.h"      /* definitions for pointer, NULL, DIRENT, and BSD */
00042 
00043 #if ! DIRENT
00044 
00045 #include <errno.h>
00046 #include <sys/types.h>
00047 #include <sys/stat.h>
00048 #include <fcntl.h>
00049 #include <dirent.h>
00050 
00051 #ifndef S_ISDIR                         /* macro to test for directory file */
00052 #define S_ISDIR(mode)           (((mode) & S_IFMT) == S_IFDIR)
00053 #endif
00054 
00055 #ifdef BSD
00056 
00057 #ifdef __STDC__
00058 int stat(char *, struct stat *);
00059 #else
00060 int stat();
00061 #endif
00062 
00063 
00064 /*
00065  * The BSD opendir routine doesn't check that what is being opened is a
00066  * directory, so we have to include the check in a wrapper routine.
00067  */
00068 
00069 #undef opendir
00070 
00071 DIR *
00072 myopendir(dirname)
00073         char *dirname;                  /* name of directory */
00074         {
00075         struct stat statb;
00076 
00077         if (stat(dirname, &statb) != 0 || ! S_ISDIR(statb.st_mode)) {
00078                 errno = ENOTDIR;
00079                 return NULL;            /* not a directory */
00080         }
00081         return opendir(dirname);
00082 }
00083 
00084 #else /* not BSD */
00085 
00086 /*
00087  * Dirent routines for old style file systems.
00088  */
00089 
00090 #ifdef __STDC__
00091 pointer malloc(unsigned);
00092 void free(pointer);
00093 int open(char *, int, ...);
00094 int close(int);
00095 int fstat(int, struct stat *);
00096 #else
00097 pointer malloc();
00098 void free();
00099 int open();
00100 int close();
00101 int fstat();
00102 #endif
00103 
00104 
00105 DIR *
00106 opendir(dirname)
00107         char            *dirname;       /* name of directory */
00108         {
00109         register DIR    *dirp;          /* -> malloc'ed storage */
00110         register int    fd;             /* file descriptor for read */
00111         struct stat     statb;          /* result of fstat() */
00112 
00113 #ifdef O_NDELAY
00114         fd = open(dirname, O_RDONLY|O_NDELAY);
00115 #else
00116         fd = open(dirname, O_RDONLY);
00117 #endif
00118         if (fd < 0)
00119                 return NULL;            /* errno set by open() */
00120 
00121         if (fstat(fd, &statb) != 0 || !S_ISDIR(statb.st_mode)) {
00122                 (void)close(fd);
00123                 errno = ENOTDIR;
00124                 return NULL;            /* not a directory */
00125         }
00126 
00127         if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
00128                 (void)close(fd);
00129                 errno = ENOMEM;
00130                 return NULL;            /* not enough memory */
00131         }
00132 
00133         dirp->dd_fd = fd;
00134         dirp->dd_nleft = 0;             /* refill needed */
00135 
00136         return dirp;
00137 }
00138 
00139 
00140 
00141 int
00142 closedir(dirp)
00143         register DIR *dirp;             /* stream from opendir() */
00144         {
00145         register int fd;
00146 
00147         if (dirp == NULL) {
00148                 errno = EFAULT;
00149                 return -1;                      /* invalid pointer */
00150         }
00151 
00152         fd = dirp->dd_fd;
00153         free((pointer)dirp);
00154         return close(fd);
00155 }
00156 
00157 
00158 
00159 struct dirent *
00160 readdir(dirp)
00161         register DIR *dirp;             /* stream from opendir() */
00162         {
00163         register struct direct *dp;
00164         register char *p, *q;
00165         register int i;
00166 
00167         do {
00168                 if ((dirp->dd_nleft -= sizeof (struct direct)) < 0) {
00169                         if ((i = read(dirp->dd_fd,
00170                                            (char *)dirp->dd_buf,
00171                                            DIRBUFENT*sizeof(struct direct))) <= 0) {
00172                                 if (i == 0)
00173                                         errno = 0;      /* unnecessary */
00174                                 return NULL;            /* EOF or error */
00175                         }
00176                         dirp->dd_loc = dirp->dd_buf;
00177                         dirp->dd_nleft = i - sizeof (struct direct);
00178                 }
00179                 dp = dirp->dd_loc++;
00180         } while (dp->d_ino == 0);
00181         dirp->dd_entry.d_ino = dp->d_ino;
00182 
00183         /* now copy the name, nul terminating it */
00184         p = dp->d_name;
00185         q = dirp->dd_entry.d_name;
00186         i = DIRSIZ;
00187         while (--i >= 0 && *p != '\0')
00188                 *q++ = *p++;
00189         *q = '\0';
00190         return &dirp->dd_entry;
00191 }
00192 
00193 #endif /* BSD */
00194 #endif /* DIRENT */

Generated on Fri Apr 14 22:56:40 2006 for minix by  doxygen 1.4.6