Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146126521
D36301.id109721.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D36301.id109721.diff
View Options
diff --git a/include/dirent.h b/include/dirent.h
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -131,6 +131,11 @@
int (^)(const struct dirent **, const struct dirent **));
#endif
#endif
+#if __BSD_VISIBLE
+int scandirat(int, const char *, struct dirent ***,
+ int (*)(const struct dirent *), int (*)(const struct dirent **,
+ const struct dirent **));
+#endif
#if __XSI_VISIBLE
void seekdir(DIR *, long);
long telldir(DIR *);
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -493,7 +493,9 @@
rand48.3 seed48.3 \
rand48.3 srand48.3
MLINKS+=recv.2 recvmmsg.2
-MLINKS+=scandir.3 alphasort.3
+MLINKS+=scandir.3 alphasort.3 \
+ scandir.3 scandirat.3 \
+ scandir.3 scandir_b.3
MLINKS+=sem_open.3 sem_close.3 \
sem_open.3 sem_unlink.3
MLINKS+=sem_wait.3 sem_trywait.3
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -439,6 +439,7 @@
posix_spawn_file_actions_addchdir_np;
posix_spawn_file_actions_addclosefrom_np;
posix_spawn_file_actions_addfchdir_np;
+ scandirat;
sched_getaffinity;
sched_setaffinity;
sched_getcpu;
diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3
--- a/lib/libc/gen/scandir.3
+++ b/lib/libc/gen/scandir.3
@@ -28,7 +28,7 @@
.\" @(#)scandir.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd January 3, 2010
+.Dd August 23, 2022
.Dt SCANDIR 3
.Os
.Sh NAME
@@ -40,9 +40,27 @@
.Sh SYNOPSIS
.In dirent.h
.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"
+.Fo scandir
+.Fa "const char *dirname"
+.Fa "struct dirent ***namelist"
+.Fa "int \*(lp*select\*(rp\*(lpconst struct dirent *\*(rp"
+.Fa "int \*(lp*compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp"
+.Fc
+.Ft
+.Fo scandirat
+.Fa int dirfd
+.Fa "const char *dirname"
+.Fa "struct dirent ***namelist"
+.Fa "int \*(lp*select\*(rp\*(lpconst struct dirent *\*(rp"
+.Fa "int \*(lp*compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp"
+.Fc
.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"
+.Fo scandir_b
+.Fa "const char *dirname"
+.Fa "struct dirent ***namelist"
+.Fa "int \*(lp*select\^(rp\*(lpconst struct dirent *\*(rp"
+.Fa "int \*(lp^compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp"
+.Fc
.Ft int
.Fn alphasort "const struct dirent **d1" "const struct dirent **d2"
.Sh DESCRIPTION
@@ -91,6 +109,36 @@
by freeing each pointer in the array and then the array itself.
.Pp
The
+.Fn scandirat
+function is similar to
+.Fn scandir ,
+but takes additional
+.Fa dirfd
+argument.
+If the supplied
+.Fa dirname
+is absolute, the function behavior is identical to that of
+.Fn scandir .
+It
+.Fa dirname
+is relative,
+.Fa dirfd
+must be a valid file descriptor referencing a directory, in
+which case the
+.Fa dirname
+lookup is relative to the directory referenced by
+.Fa dirfd .
+If
+.Fa dirfd
+has the special value
+.Va AT_FDCWD ,
+then the current process directory is used as the base for
+relative lookups.
+See
+.Xr openat 2
+for additional details.
+.Pp
+The
.Fn scandir_b
function behaves in the same way as
.Fn scandir ,
@@ -103,6 +151,7 @@
.Xr malloc 3
cannot allocate enough memory to hold all the data structures.
.Sh SEE ALSO
+.Xr openat 2 ,
.Xr directory 3 ,
.Xr malloc 3 ,
.Xr qsort 3 ,
@@ -115,3 +164,7 @@
.Fn alphasort
functions appeared in
.Bx 4.2 .
+The
+.Fn scandirat
+function was added in
+.Fx 14.0 .
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -42,8 +42,10 @@
#include "namespace.h"
#include <dirent.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "un-namespace.h"
#ifdef I_AM_SCANDIR_B
@@ -64,22 +66,18 @@
static int alphasort_thunk(void *thunk, const void *p1, const void *p2);
#endif
-int
+static int
#ifdef I_AM_SCANDIR_B
-scandir_b(const char *dirname, struct dirent ***namelist, select_block select,
+scandir_b_dirp(DIR *dirp, struct dirent ***namelist, select_block select,
dcomp_block dcomp)
#else
-scandir(const char *dirname, struct dirent ***namelist,
+scandir_dirp(DIR *dirp, struct dirent ***namelist,
int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **,
- const struct dirent **))
+ const struct dirent **))
#endif
{
struct dirent *d, *p, **names = NULL;
size_t arraysz, numitems;
- DIR *dirp;
-
- if ((dirp = opendir(dirname)) == NULL)
- return(-1);
numitems = 0;
arraysz = 32; /* initial estimate of the array size */
@@ -138,7 +136,50 @@
return (-1);
}
+int
+#ifdef I_AM_SCANDIR_B
+scandir_b(const char *dirname, struct dirent ***namelist, select_block select,
+ dcomp_block dcomp)
+#else
+scandir(const char *dirname, struct dirent ***namelist,
+ int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **,
+ const struct dirent **))
+#endif
+{
+ DIR *dirp;
+
+ dirp = opendir(dirname);
+ if (dirp == NULL)
+ return (-1);
+ return (
+#ifdef I_AM_SCANDIR_B
+ scandir_b_dirp
+#else
+ scandir_dirp
+#endif
+ (dirp, namelist, select, dcomp));
+}
+
#ifndef I_AM_SCANDIR_B
+int
+scandirat(int dirfd, const char *dirname, struct dirent ***namelist,
+ int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **,
+ const struct dirent **))
+{
+ DIR *dirp;
+ int fd;
+
+ fd = _openat(dirfd, dirname, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
+ if (fd == -1)
+ return (-1);
+ dirp = fdopendir(fd);
+ if (dirp == NULL) {
+ _close(fd);
+ return (-1);
+ }
+ return (scandir_dirp(dirp, namelist, select, dcomp));
+}
+
/*
* Alphabetic order comparison routine for those who want it.
* POSIX 2008 requires that alphasort() uses strcoll().
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 1, 1:13 AM (2 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29089591
Default Alt Text
D36301.id109721.diff (5 KB)
Attached To
Mode
D36301: Add scandirat(3)
Attached
Detach File
Event Timeline
Log In to Comment