Merge scandir(3) interface update to stable/8.
MFC r201512: Modernize scandir(3) and alphasort(3) interfaces according to the IEEE Std 1003.1-2008. MFC r201602: Move scandir(3) and alphasort(3) into XSI namespace. MFC r201604: Use thunks to adapt alphasort-like interface to the comparision function required by qsort() and qsort_r(). MFC r202556 (by ache): Use strcoll() in opendir() and alphasort(). Remove some comments. MFC r202572 (by ache): Revert to using strcmp() for opendir(). MFC r202677 (by ache): Style. MFC r202679 (by ache): Style: rename internal function to opendir_compar(). MFC r202691 (by ache): For alphasort(3) add reference to strcoll(3). MFC r202693 (by ache): Style: reword comment.
This commit is contained in:
parent
be6797dde8
commit
b3c4be736e
@ -93,9 +93,11 @@ typedef void * DIR;
|
||||
#ifndef _KERNEL
|
||||
|
||||
__BEGIN_DECLS
|
||||
#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700
|
||||
int alphasort(const struct dirent **, const struct dirent **);
|
||||
#endif
|
||||
#if __BSD_VISIBLE
|
||||
DIR *__opendir2(const char *, int);
|
||||
int alphasort(const void *, const void *);
|
||||
int getdents(int, char *, int);
|
||||
int getdirentries(int, char *, int, long *);
|
||||
#endif
|
||||
@ -107,9 +109,10 @@ struct dirent *
|
||||
int readdir_r(DIR *, struct dirent *, struct dirent **);
|
||||
#endif
|
||||
void rewinddir(DIR *);
|
||||
#if __BSD_VISIBLE
|
||||
#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700
|
||||
int scandir(const char *, struct dirent ***,
|
||||
int (*)(struct dirent *), int (*)(const void *, const void *));
|
||||
int (*)(const struct dirent *), int (*)(const struct dirent **,
|
||||
const struct dirent **));
|
||||
#endif
|
||||
#if __XSI_VISIBLE
|
||||
void seekdir(DIR *, long);
|
||||
|
@ -92,6 +92,14 @@ __opendir2(const char *name, int flags)
|
||||
return __opendir_common(fd, name, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
opendir_compar(const void *p1, const void *p2)
|
||||
{
|
||||
|
||||
return (strcmp((*(const struct dirent **)p1)->d_name,
|
||||
(*(const struct dirent **)p2)->d_name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routine for opendir(3), __opendir2(3) and fdopendir(3).
|
||||
*/
|
||||
@ -240,7 +248,8 @@ __opendir_common(int fd, const char *name, int flags)
|
||||
/*
|
||||
* This sort must be stable.
|
||||
*/
|
||||
mergesort(dpv, n, sizeof(*dpv), alphasort);
|
||||
mergesort(dpv, n, sizeof(*dpv),
|
||||
opendir_compar);
|
||||
|
||||
dpv[n] = NULL;
|
||||
xp = NULL;
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)scandir.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dd January 3, 2010
|
||||
.Dt SCANDIR 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -38,12 +38,11 @@
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In dirent.h
|
||||
.Ft int
|
||||
.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpstruct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst void *, const void *\\*(rp"
|
||||
.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpconst struct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst struct dirent **, const struct dirent **\\*(rp"
|
||||
.Ft int
|
||||
.Fn alphasort "const void *d1" "const void *d2"
|
||||
.Fn alphasort "const struct dirent **d1" "const struct dirent **d2"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn scandir
|
||||
@ -82,7 +81,8 @@ The
|
||||
function
|
||||
is a routine which can be used for the
|
||||
.Fa compar
|
||||
argument to sort the array alphabetically.
|
||||
argument to sort the array alphabetically using
|
||||
.Xr strcoll 3 .
|
||||
.Pp
|
||||
The memory allocated for the array can be deallocated with
|
||||
.Xr free 3 ,
|
||||
@ -95,7 +95,8 @@ cannot allocate enough memory to hold all the data structures.
|
||||
.Xr directory 3 ,
|
||||
.Xr malloc 3 ,
|
||||
.Xr qsort 3 ,
|
||||
.Xr dir 5
|
||||
.Xr dir 5 ,
|
||||
.Xr strcoll 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn scandir
|
||||
|
@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static int alphasort_thunk(void *thunk, const void *p1, const void *p2);
|
||||
|
||||
/*
|
||||
* The DIRSIZ macro is the minimum record length which will hold the directory
|
||||
* entry. This requires the amount of space in struct dirent without the
|
||||
@ -58,11 +60,9 @@ __FBSDID("$FreeBSD$");
|
||||
(((dp)->d_namlen + 1 + 3) &~ 3))
|
||||
|
||||
int
|
||||
scandir(dirname, namelist, select, dcomp)
|
||||
const char *dirname;
|
||||
struct dirent ***namelist;
|
||||
int (*select)(struct dirent *);
|
||||
int (*dcomp)(const void *, const void *);
|
||||
scandir(const char *dirname, struct dirent ***namelist,
|
||||
int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **,
|
||||
const struct dirent **))
|
||||
{
|
||||
struct dirent *d, *p, **names = NULL;
|
||||
size_t nitems = 0;
|
||||
@ -111,26 +111,35 @@ scandir(dirname, namelist, select, dcomp)
|
||||
}
|
||||
closedir(dirp);
|
||||
if (nitems && dcomp != NULL)
|
||||
qsort(names, nitems, sizeof(struct dirent *), dcomp);
|
||||
qsort_r(names, nitems, sizeof(struct dirent *),
|
||||
&dcomp, alphasort_thunk);
|
||||
*namelist = names;
|
||||
return(nitems);
|
||||
return (nitems);
|
||||
|
||||
fail:
|
||||
while (nitems > 0)
|
||||
free(names[--nitems]);
|
||||
free(names);
|
||||
closedir(dirp);
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alphabetic order comparison routine for those who want it.
|
||||
* POSIX 2008 requires that alphasort() uses strcoll().
|
||||
*/
|
||||
int
|
||||
alphasort(d1, d2)
|
||||
const void *d1;
|
||||
const void *d2;
|
||||
alphasort(const struct dirent **d1, const struct dirent **d2)
|
||||
{
|
||||
return(strcmp((*(struct dirent **)d1)->d_name,
|
||||
(*(struct dirent **)d2)->d_name));
|
||||
|
||||
return (strcoll((*d1)->d_name, (*d2)->d_name));
|
||||
}
|
||||
|
||||
static int
|
||||
alphasort_thunk(void *thunk, const void *p1, const void *p2)
|
||||
{
|
||||
int (*dc)(const struct dirent **, const struct dirent **);
|
||||
|
||||
dc = *(int (**)(const struct dirent **, const struct dirent **))thunk;
|
||||
return (dc((const struct dirent **)p1, (const struct dirent **)p2));
|
||||
}
|
||||
|
@ -589,9 +589,15 @@ process_section(char *mandir, char *section)
|
||||
}
|
||||
|
||||
static int
|
||||
select_sections(struct dirent *entry)
|
||||
select_sections(const struct dirent *entry)
|
||||
{
|
||||
return directory_type(entry->d_name) == MAN_SECTION_DIR;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
name = strdup(entry->d_name);
|
||||
ret = directory_type(name) == MAN_SECTION_DIR;
|
||||
free(name);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -879,9 +879,9 @@ process_section(char *section_dir)
|
||||
* Returns whether the directory entry is a man page section.
|
||||
*/
|
||||
static int
|
||||
select_sections(struct dirent *entry)
|
||||
select_sections(const struct dirent *entry)
|
||||
{
|
||||
char *p = &entry->d_name[3];
|
||||
const char *p = &entry->d_name[3];
|
||||
|
||||
if (strncmp(entry->d_name, "man", 3) != 0)
|
||||
return 0;
|
||||
|
@ -280,7 +280,7 @@ void inform(const struct printer *_pp, char *_cf);
|
||||
void init_printer(struct printer *_pp);
|
||||
void init_request(struct request *_rp);
|
||||
int inlist(char *_uname, char *_cfile);
|
||||
int iscf(struct dirent *_d);
|
||||
int iscf(const struct dirent *_d);
|
||||
void ldump(const char *_nfile, const char *_datafile, int _copies);
|
||||
void lastprinter(void);
|
||||
int lockchk(struct printer *_pp, char *_slockf);
|
||||
|
@ -384,7 +384,7 @@ rmremote(const struct printer *pp)
|
||||
* Return 1 if the filename begins with 'cf'
|
||||
*/
|
||||
int
|
||||
iscf(struct dirent *d)
|
||||
iscf(const struct dirent *d)
|
||||
{
|
||||
return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user