4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
43 * Based on usr/src/ucblib/libucb/port/gen/scandir.c
47 * Scan the directory dirname calling select to make a list of selected
48 * directory entries then sort using qsort and compare routine dcomp.
49 * Returns the number of entries and a pointer to a list of pointers to
50 * struct direct (through namelist). Returns -1 if there were any errors.
53 #include <sys/feature_tests.h>
55 #pragma weak _scandir = scandir
56 #pragma weak _alphasort = alphasort
58 #pragma weak _scandir64 = scandir64
59 #pragma weak _alphasort64 = alphasort64
65 #include <sys/types.h>
74 scandir64(const char *dirname
, struct dirent64
*(*namelist
[]),
75 int (*select
)(const struct dirent64
*),
76 int (*dcomp
)(const struct dirent64
**, const struct dirent64
**))
78 struct dirent64
*d
, *p
, **names
= NULL
;
80 size_t arraysz
, entlen
;
83 u_longlong_t tmp_arraysz
;
85 if ((dirp
= opendir(dirname
)) == NULL
)
87 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
91 * estimate the array size by taking the size of the directory file
92 * and dividing it by a multiple of the minimum size entry.
94 tmp_arraysz
= stb
.st_size
/ 24; /* 24 bytes on a 64-bit system */
95 if (tmp_arraysz
> INT_MAX
)
98 arraysz
= (size_t)tmp_arraysz
;
99 names
= malloc(arraysz
* sizeof (struct dirent64
*));
103 while ((d
= readdir64(dirp
)) != NULL
) {
104 if (select
!= NULL
&& !(*select
)(d
))
105 continue; /* just selected names */
107 entlen
= d
->d_reclen
;
109 * Make a minimum size copy of the data
114 (void) memcpy(p
, d
, entlen
);
116 * Check to make sure the array has space left and
117 * realloc the maximum size.
119 if (nitems
>= arraysz
) {
120 struct dirent64
**tmp
;
121 if (nitems
== INT_MAX
) {
127 arraysz
+= 512; /* no science here */
129 arraysz
* sizeof (struct dirent64
*));
138 (void) closedir(dirp
);
139 if (nitems
&& dcomp
!= NULL
)
140 qsort(names
, nitems
, sizeof (struct dirent64
*),
141 (int(*)(const void *, const void *))dcomp
);
144 return ((int)nitems
);
147 while (nitems
!= 0) {
148 free(names
[--nitems
]);
152 (void) closedir(dirp
);
159 scandir(const char *dirname
, struct dirent
*(*namelist
[]),
160 int (*select
)(const struct dirent
*),
161 int (*dcomp
)(const struct dirent
**, const struct dirent
**))
163 struct dirent
*d
, *p
, **names
= NULL
;
165 size_t arraysz
, entlen
;
168 u_longlong_t tmp_arraysz
;
170 if ((dirp
= opendir(dirname
)) == NULL
)
172 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
176 * estimate the array size by taking the size of the directory file
177 * and dividing it by a multiple of the minimum size entry.
179 tmp_arraysz
= stb
.st_size
/ 24; /* 24 bytes on a 64-bit system */
180 if (tmp_arraysz
> INT_MAX
)
183 arraysz
= (size_t)tmp_arraysz
;
184 names
= malloc(arraysz
* sizeof (struct dirent
*));
188 while ((d
= readdir(dirp
)) != NULL
) {
189 if (select
!= NULL
&& !(*select
)(d
))
190 continue; /* just selected names */
192 entlen
= d
->d_reclen
;
194 * Make a minimum size copy of the data
199 (void) memcpy(p
, d
, entlen
);
201 * Check to make sure the array has space left and
202 * realloc the maximum size.
204 if (nitems
>= arraysz
) {
206 if (nitems
== INT_MAX
) {
212 arraysz
+= 512; /* no science here */
214 arraysz
* sizeof (struct dirent
*));
223 (void) closedir(dirp
);
224 if (nitems
&& dcomp
!= NULL
)
225 qsort(names
, nitems
, sizeof (struct dirent
*),
226 (int(*)(const void *, const void *))dcomp
);
229 return ((int)nitems
);
232 while (nitems
!= 0) {
233 free(names
[--nitems
]);
237 (void) closedir(dirp
);
242 * Alphabetic order comparison routine for those who want it.
245 alphasort(const struct dirent
**d1
, const struct dirent
**d2
)
247 return (strcoll((*d1
)->d_name
,
253 alphasort64(const struct dirent64
**d1
, const struct dirent64
**d2
)
255 return (strcoll((*d1
)->d_name
,