Page MenuHomeFreeBSD

D36301.id109721.diff
No OneTemporary

D36301.id109721.diff

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

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)

Event Timeline