usr/src/lib/libc/port/gen/scandir.c
author Jon Tibble <meths@btinternet.com>
Thu, 09 Dec 2010 22:32:39 +0100
changeset 13255 4afa820d78b9
parent 6812 febeba71273d
permissions -rw-r--r--
298 SPARC build fails in smt_pause.o 478 Build needs fixing for pkgdepend flag day Reviewed by: [email protected] Reviewed by: [email protected] Reviewed by: [email protected] Approved by: [email protected]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    23
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * University Copyright- Copyright (c) 1982, 1986, 1988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * The Regents of the University of California
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 * All Rights Reserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * University Acknowledgment- Portions of this document are derived from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * software developed by the University of California, Berkeley, and its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * contributors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 * Based on usr/src/ucblib/libucb/port/gen/scandir.c
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 * Scan the directory dirname calling select to make a list of selected
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 * directory entries then sort using qsort and compare routine dcomp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * Returns the number of entries and a pointer to a list of pointers to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 * struct direct (through namelist). Returns -1 if there were any errors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/feature_tests.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    55
#pragma weak _scandir = scandir
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    56
#pragma weak _alphasort = alphasort
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#if !defined(_LP64)
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    58
#pragma weak _scandir64 = scandir64
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    59
#pragma weak _alphasort64 = alphasort64
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    62
#include "lint.h"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <dirent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <stdlib.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <string.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#include <limits.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#if !defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
scandir64(const char *dirname, struct dirent64 *(*namelist[]),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
    int (*select)(const struct dirent64 *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
    int (*dcomp)(const struct dirent64 **, const struct dirent64 **))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
	struct dirent64	*d, *p, **names = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
	size_t	nitems = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
	size_t	arraysz, entlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
	struct stat64	stb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
	DIR	*dirp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
	u_longlong_t	tmp_arraysz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
	if ((dirp = opendir(dirname)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	if (fstat64(dirp->dd_fd, &stb) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	 * estimate the array size by taking the size of the directory file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	 * and dividing it by a multiple of the minimum size entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
	tmp_arraysz = stb.st_size / 24;	/* 24 bytes on a 64-bit system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
	if (tmp_arraysz > INT_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
		arraysz = INT_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
		arraysz = (size_t)tmp_arraysz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
	names = malloc(arraysz * sizeof (struct dirent64 *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	if (names == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
	while ((d = readdir64(dirp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
		if (select != NULL && !(*select)(d))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
			continue;	/* just selected names */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
		entlen = d->d_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
		 * Make a minimum size copy of the data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
		p = malloc(entlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
		if (p == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
			goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
		(void) memcpy(p, d, entlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
		 * Check to make sure the array has space left and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
		 * realloc the maximum size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
		if (nitems >= arraysz) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
			struct dirent64	**tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
			if (nitems == INT_MAX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
				/* overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
				free(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
				errno = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
				goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
			arraysz += 512;		/* no science here */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
			tmp = realloc(names,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
			    arraysz * sizeof (struct dirent64 *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
			if (tmp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
				free(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
				goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
			names = tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		names[nitems++] = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	(void) closedir(dirp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	if (nitems && dcomp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
		qsort(names, nitems, sizeof (struct dirent64 *),
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   141
		    (int(*)(const void *, const void *))dcomp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	*namelist = names;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	return ((int)nitems);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
fail:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	while (nitems != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
		free(names[--nitems]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	if (names)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
		free(names);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	(void) closedir(dirp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
scandir(const char *dirname, struct dirent *(*namelist[]),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
    int (*select)(const struct dirent *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
    int (*dcomp)(const struct dirent **, const struct dirent **))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	struct dirent	*d, *p, **names = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	size_t	nitems = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	size_t	arraysz, entlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	struct stat64	stb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	DIR	*dirp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	u_longlong_t	tmp_arraysz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	if ((dirp = opendir(dirname)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	if (fstat64(dirp->dd_fd, &stb) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	 * estimate the array size by taking the size of the directory file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	 * and dividing it by a multiple of the minimum size entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	tmp_arraysz = stb.st_size / 24;	/* 24 bytes on a 64-bit system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	if (tmp_arraysz > INT_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
		arraysz = INT_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
		arraysz = (size_t)tmp_arraysz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	names = malloc(arraysz * sizeof (struct dirent *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	if (names == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
		goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	while ((d = readdir(dirp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
		if (select != NULL && !(*select)(d))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
			continue;	/* just selected names */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
		entlen = d->d_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
		 * Make a minimum size copy of the data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
		p = malloc(entlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
		if (p == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
			goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		(void) memcpy(p, d, entlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
		 * Check to make sure the array has space left and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		 * realloc the maximum size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		if (nitems >= arraysz) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
			struct dirent **tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
			if (nitems == INT_MAX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
				/* overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
				free(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
				errno = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
				goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
			arraysz += 512;		/* no science here */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
			tmp = realloc(names,
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   214
			    arraysz * sizeof (struct dirent *));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
			if (tmp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
				free(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
				goto fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
			names = tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
		names[nitems++] = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	(void) closedir(dirp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	if (nitems && dcomp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
		qsort(names, nitems, sizeof (struct dirent *),
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   226
		    (int(*)(const void *, const void *))dcomp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	*namelist = names;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	return ((int)nitems);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
fail:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	while (nitems != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		free(names[--nitems]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	if (names)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		free(names);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	(void) closedir(dirp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
 * Alphabetic order comparison routine for those who want it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
alphasort(const struct dirent **d1, const struct dirent **d2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	return (strcoll((*d1)->d_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	    (*d2)->d_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
#if !defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
alphasort64(const struct dirent64 **d1, const struct dirent64 **d2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	return (strcoll((*d1)->d_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	    (*d2)->d_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
#endif