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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libc/] [scandir.c] - Blame information for rev 228

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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
/*
44
 * Scan the directory dirname calling select to make a list of selected
45
 * directory entries then sort using qsort and compare routine dcomp.
46
 * Returns the number of entries and a pointer to a list of pointers to
47
 * struct dirent (through namelist). Returns -1 if there were any errors.
48
 */
49
 
50
#include <sys/types.h>
51
#include <sys/stat.h>
52
#include <dirent.h>
53
#include <stdlib.h>
54
#include <string.h>
55
 
56
/*
57
 * The DIRSIZ macro gives the minimum record length which will hold
58
 * the directory entry.  This requires the amount of space in struct dirent
59
 * without the d_name field, plus enough space for the name with a terminating
60
 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
61
 */
62
#undef DIRSIZ
63
/*
64
#define DIRSIZ(dp) \
65
    ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
66
*/
67
 
68
#define DIRSIZ(dp) \
69
    ((sizeof (struct dirent) - (NAME_MAX+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
70
 
71
#ifndef __P
72
#define __P(args) ()
73
#endif
74
 
75
int
76
scandir(dirname, namelist, select, dcomp)
77
        const char *dirname;
78
        struct dirent ***namelist;
79
        int (*select) __P((struct dirent *));
80
        int (*dcomp) __P((const void *, const void *));
81
{
82
        register struct dirent *d, *p, **names;
83
        register size_t nitems;
84
        struct stat stb;
85
        long arraysz;
86
        DIR *dirp;
87
 
88
        if ((dirp = opendir(dirname)) == NULL)
89
                return(-1);
90
        if (fstat(dirp->dd_fd, &stb) < 0)
91
                return(-1);
92
 
93
        /*
94
         * estimate the array size by taking the size of the directory file
95
         * and dividing it by a multiple of the minimum size entry.
96
         */
97
        arraysz = (stb.st_size / 24);
98
        names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
99
        if (names == NULL)
100
                return(-1);
101
 
102
        nitems = 0;
103
        while ((d = readdir(dirp)) != NULL) {
104
                if (select != NULL && !(*select)(d))
105
                        continue;       /* just selected names */
106
                /*
107
                 * Make a minimum size copy of the data
108
                 */
109
                p = (struct dirent *)malloc(DIRSIZ(d));
110
                if (p == NULL)
111
                        return(-1);
112
                p->d_ino = d->d_ino;
113
                p->d_reclen = d->d_reclen;
114
                p->d_namlen = d->d_namlen;
115
                strncpy(d->d_name, p->d_name, p->d_namlen + 1);
116
                /*
117
                 * Check to make sure the array has space left and
118
                 * realloc the maximum size.
119
                 */
120
                if (++nitems >= arraysz) {
121
                        if (fstat(dirp->dd_fd, &stb) < 0)
122
                                return(-1);     /* just might have grown */
123
                        arraysz = stb.st_size / 12;
124
                        names = (struct dirent **)realloc((char *)names,
125
                                arraysz * sizeof(struct dirent *));
126
                        if (names == NULL)
127
                                return(-1);
128
                }
129
                names[nitems-1] = p;
130
        }
131
        closedir(dirp);
132
        if (nitems && dcomp != NULL){
133
                qsort(names, nitems, sizeof(struct dirent *), dcomp);
134
        }
135
        *namelist = names;
136
        return(nitems);
137
}
138
 
139
/*
140
 * Alphabetic order comparison routine for those who want it.
141
 */
142
int
143
alphasort(d1, d2)
144
        const void *d1;
145
        const void *d2;
146
{
147
        return(strcmp((*(struct dirent **)d1)->d_name,
148
            (*(struct dirent **)d2)->d_name));
149
}

powered by: WebSVN 2.1.0

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