diff options
Diffstat (limited to 'lib/libc/gen')
-rw-r--r-- | lib/libc/gen/Symbol.map | 1 | ||||
-rw-r--r-- | lib/libc/gen/scandir.3 | 11 | ||||
-rw-r--r-- | lib/libc/gen/scandir.c | 23 | ||||
-rw-r--r-- | lib/libc/gen/scandir_b.c | 29 |
4 files changed, 63 insertions, 1 deletions
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 5885420..ff5162a 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -349,6 +349,7 @@ FBSD_1.1 { posix_spawnattr_setsigdefault; posix_spawnattr_setsigmask; posix_spawnp; + scandir_b; semctl; tcgetsid; tcsetsid; diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3 index b3e0a7e..eaba754 100644 --- a/lib/libc/gen/scandir.3 +++ b/lib/libc/gen/scandir.3 @@ -42,6 +42,8 @@ .Ft int .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 scandir_b "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 struct dirent **d1" "const struct dirent **d2" .Sh DESCRIPTION The @@ -87,6 +89,15 @@ argument to sort the array alphabetically using The memory allocated for the array can be deallocated with .Xr free 3 , by freeing each pointer in the array and then the array itself. +.Pp +The +.Fn scandir_b +function behaves in the same way as +.Fn scandir , +but takes blocks as arguments instead of function pointers and calls +.Fn qsort_b +rather than +.Fn qsort . .Sh DIAGNOSTICS Returns \-1 if the directory cannot be opened for reading or if .Xr malloc 3 diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c index 93bc852..d81acc8 100644 --- a/lib/libc/gen/scandir.c +++ b/lib/libc/gen/scandir.c @@ -46,6 +46,17 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include "un-namespace.h" +#ifdef I_AM_SCANDIR_B +#include "block_abi.h" +#define SELECT(x) CALL_BLOCK(select, x) +#ifndef __BLOCKS__ +void +qsort_b(void *, size_t, size_t, void*); +#endif +#else +#define SELECT(x) select(x) +#endif + static int alphasort_thunk(void *thunk, const void *p1, const void *p2); /* @@ -60,9 +71,15 @@ static int alphasort_thunk(void *thunk, const void *p1, const void *p2); (((dp)->d_namlen + 1 + 3) &~ 3)) int +#ifdef I_AM_SCANDIR_B +scandir_b(const char *dirname, struct dirent ***namelist, + DECLARE_BLOCK(int, select, const struct dirent *), + DECLARE_BLOCK(int, dcomp, const struct dirent **, const struct dirent **)) +#else scandir(const char *dirname, struct dirent ***namelist, int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **, const struct dirent **)) +#endif { struct dirent *d, *p, **names = NULL; size_t nitems = 0; @@ -78,7 +95,7 @@ scandir(const char *dirname, struct dirent ***namelist, goto fail; while ((d = readdir(dirp)) != NULL) { - if (select != NULL && !(*select)(d)) + if (select != NULL && !SELECT(d)) continue; /* just selected names */ /* * Make a minimum size copy of the data @@ -111,8 +128,12 @@ scandir(const char *dirname, struct dirent ***namelist, } closedir(dirp); if (nitems && dcomp != NULL) +#ifdef I_AM_SCANDIR_B + qsort_b(names, nitems, sizeof(struct dirent *), (void*)dcomp); +#else qsort_r(names, nitems, sizeof(struct dirent *), &dcomp, alphasort_thunk); +#endif *namelist = names; return (nitems); diff --git a/lib/libc/gen/scandir_b.c b/lib/libc/gen/scandir_b.c new file mode 100644 index 0000000..6310a91 --- /dev/null +++ b/lib/libc/gen/scandir_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#define I_AM_SCANDIR_B +#include "scandir.c" |