summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/Symbol.map1
-rw-r--r--lib/libc/gen/scandir.311
-rw-r--r--lib/libc/gen/scandir.c23
-rw-r--r--lib/libc/gen/scandir_b.c29
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"
OpenPOWER on IntegriCloud