4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1997 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"
45 * Scan the directory dirname calling select to make a list of selected
46 * directory entries then sort using qsort and compare routine dcomp.
47 * Returns the number of entries and a pointer to a list of pointers to
48 * struct direct (through namelist). Returns -1 if there were any errors.
51 #include <sys/types.h>
60 * The macro DIRSIZ(dp) gives an amount of space required to represent
61 * a directory entry. For any directory entry dp->d_reclen >= DIRSIZ(dp).
62 * Specific filesystem types may use this use this macro to construct the value
67 ((sizeof (struct direct) - sizeof ((dp)->d_name) + \
68 (strlen((dp)->d_name)+1) + 3) & ~3)
72 scandir64(char *dirname
, struct direct64
*(*namelist
[]),
73 int (*select
)(struct direct64
*),
74 int (*dcomp
)(struct direct64
**, struct direct64
**))
76 struct direct64
*d
, *p
, **names
;
83 if ((dirp
= opendir(dirname
)) == NULL
)
85 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
89 * estimate the array size by taking the size of the directory file
90 * and dividing it by a multiple of the minimum size entry.
92 arraysz
= (stb
.st_size
/ 24);
93 names
= (struct direct64
**)malloc(arraysz
*
94 sizeof (struct direct64
*));
99 while ((d
= readdir64(dirp
)) != NULL
) {
100 if (select
!= NULL
&& !(*select
)(d
))
101 continue; /* just selected names */
103 * Make a minimum size copy of the data
105 p
= (struct direct64
*)malloc(DIRSIZ64(d
));
109 p
->d_reclen
= d
->d_reclen
;
110 p
->d_namlen
= d
->d_namlen
;
111 for (cp1
= p
->d_name
, cp2
= d
->d_name
; *cp1
++ = *cp2
++; )
114 * Check to make sure the array has space left and
115 * realloc the maximum size.
117 if (++nitems
>= arraysz
) {
118 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
119 return (-1); /* just might have grown */
120 arraysz
= stb
.st_size
/ 12;
121 names
= (struct direct64
**)realloc((char *)names
,
122 arraysz
* sizeof (struct direct64
*));
128 (void) closedir(dirp
);
129 if (nitems
&& dcomp
!= NULL
)
130 qsort(names
, nitems
, sizeof (struct direct64
*),
131 (int(*)(const void *, const void *)) dcomp
);
139 scandir(char *dirname
, struct direct
*(*namelist
[]),
140 int (*select
)(struct direct
*),
141 int (*dcomp
)(struct direct
**, struct direct
**))
143 struct direct
*d
, *p
, **names
;
150 if ((dirp
= opendir(dirname
)) == NULL
)
152 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
155 * estimate the array size by taking the size of the directory file
156 * and dividing it by a multiple of the minimum size entry.
158 if (stb
.st_size
> SSIZE_MAX
) {
162 arraysz
= (stb
.st_size
/ 24);
164 names
= (struct direct
**)malloc(arraysz
* sizeof (struct direct
*));
169 while ((d
= readdir(dirp
)) != NULL
) {
170 if (select
!= NULL
&& !(*select
)(d
))
171 continue; /* just selected names */
173 * Make a minimum size copy of the data
175 p
= (struct direct
*)malloc(DIRSIZ(d
));
179 p
->d_reclen
= d
->d_reclen
;
180 p
->d_namlen
= d
->d_namlen
;
181 for (cp1
= p
->d_name
, cp2
= d
->d_name
; *cp1
++ = *cp2
++; )
184 * Check to make sure the array has space left and
185 * realloc the maximum size.
187 if (++nitems
>= arraysz
) {
188 if (fstat64(dirp
->dd_fd
, &stb
) < 0)
189 return (-1); /* just might have grown */
190 arraysz
= stb
.st_size
/ 12;
191 names
= (struct direct
**)realloc((char *)names
,
192 arraysz
* sizeof (struct direct
*));
198 (void) closedir(dirp
);
199 if (nitems
&& dcomp
!= NULL
)
200 qsort(names
, nitems
, sizeof (struct direct
*),
201 (int(*)(const void *, const void *)) dcomp
);
207 * Alphabetic order comparison routine for those who want it.
210 alphasort(struct direct
**d1
, struct direct
**d2
)
212 return (strcmp((*d1
)->d_name
, (*d2
)->d_name
));
217 alphasort64(struct direct64
**d1
, struct direct64
**d2
)
219 return (strcmp((*d1
)->d_name
, (*d2
)->d_name
));