OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libcsupport/] [src/] [scandir.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  scandir() - POSIX 1003.1b - XXX
3
 *
4
 *  This was copied from Newlib 1.8.0.
5
 *
6
 *
7
 * Copyright (c) 1983 Regents of the University of California.
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. All advertising materials mentioning features or use of this software
19
 *    must display the following acknowledgement:
20
 *      This product includes software developed by the University of
21
 *      California, Berkeley and its contributors.
22
 * 4. Neither the name of the University nor the names of its contributors
23
 *    may be used to endorse or promote products derived from this software
24
 *    without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36
 * SUCH DAMAGE.
37
 */
38
 
39
#if defined(LIBC_SCCS) && !defined(lint)
40
static char sccsid[] = "@(#)scandir.c   5.10 (Berkeley) 2/23/91";
41
#endif /* LIBC_SCCS and not lint */
42
 
43
#if HAVE_CONFIG_H
44
#include "config.h"
45
#endif
46
 
47
/*
48
 * Scan the directory dirname calling select to make a list of selected
49
 * directory entries then sort using qsort and compare routine dcomp.
50
 * Returns the number of entries and a pointer to a list of pointers to
51
 * struct dirent (through namelist). Returns -1 if there were any errors.
52
 */
53
 
54
#include <sys/types.h>
55
#include <sys/stat.h>
56
#include <dirent.h>
57
#include <stdlib.h>
58
#include <string.h>
59
 
60
/*
61
 * The DIRSIZ macro gives the minimum record length which will hold
62
 * the directory entry.  This requires the amount of space in struct dirent
63
 * without the d_name field, plus enough space for the name with a terminating
64
 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
65
 */
66
#undef DIRSIZ
67
/*
68
#define DIRSIZ(dp) \
69
    ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
70
*/
71
 
72
#define DIRSIZ(dp) \
73
    ((sizeof (struct dirent) - (NAME_MAX+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
74
 
75
#ifndef __P
76
#define __P(args) ()
77
#endif
78
 
79
int
80
scandir(dirname, namelist, select, dcomp)
81
        const char *dirname;
82
        struct dirent ***namelist;
83
        int (*select) __P((struct dirent *));
84
        int (*dcomp) __P((const void *, const void *));
85
{
86
        register struct dirent *d = NULL;
87
        register struct dirent *p = NULL;
88
        register struct dirent **names = NULL;
89
        register size_t nitems = 0;
90
        struct stat stb;
91
        long arraysz;
92
        DIR *dirp = NULL;
93
        int i;
94
 
95
        if ((dirp = opendir(dirname)) == NULL)
96
                return(-1);
97
        if (fstat(dirp->dd_fd, &stb) < 0)
98
                goto cleanup_and_bail;
99
 
100
        /*
101
         * estimate the array size by taking the size of the directory file
102
         * and dividing it by a multiple of the minimum size entry.
103
         */
104
        arraysz = (stb.st_size / 24);
105
        names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
106
        if (names == NULL)
107
                goto  cleanup_and_bail;
108
 
109
        while ((d = readdir(dirp)) != NULL) {
110
                if (select != NULL && !(*select)(d))
111
                        continue;       /* just selected names */
112
                /*
113
                 * Make a minimum size copy of the data
114
                 */
115
                p = (struct dirent *)malloc(DIRSIZ(d));
116
                if (p == NULL)
117
                      goto  cleanup_and_bail;
118
                p->d_ino = d->d_ino;
119
                p->d_reclen = d->d_reclen;
120
                p->d_namlen = d->d_namlen;
121
                strncpy(p->d_name, d->d_name, p->d_namlen + 1);
122
                /*
123
                 * Check to make sure the array has space left and
124
                 * realloc the maximum size.
125
                 */
126
                if (++nitems >= arraysz) {
127
                        if (fstat(dirp->dd_fd, &stb) < 0)
128
                                goto  cleanup_and_bail; /* just might have grown */
129
                        arraysz = stb.st_size / 12;
130
                        names = (struct dirent **)realloc((char *)names,
131
                                arraysz * sizeof(struct dirent *));
132
                        if (names == NULL)
133
                      goto  cleanup_and_bail;
134
                }
135
                names[nitems-1] = p;
136
        }
137
        closedir(dirp);
138
        if (nitems && dcomp != NULL){
139
                qsort(names, nitems, sizeof(struct dirent *), dcomp);
140
        }
141
        *namelist = names;
142
        return(nitems);
143
 
144
cleanup_and_bail:
145
 
146
        if ( dirp )
147
                closedir( dirp );
148
 
149
        if ( names ) {
150
                for (i=0; i < nitems; i++ )
151
                        free( names[i] );
152
                free( names );
153
        }
154
 
155
        return(-1);
156
}
157
 
158
/*
159
 * Alphabetic order comparison routine for those who want it.
160
 */
161
int
162
alphasort(d1, d2)
163
        const void *d1;
164
        const void *d2;
165
{
166
        return(strcmp((*(struct dirent **)d1)->d_name,
167
            (*(struct dirent **)d2)->d_name));
168
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.