git: f8a926bebe81 - stable/13 - libc: add scandirat(3)

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 31 Aug 2022 01:32:24 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=f8a926bebe819c09e04261fb212cacbf3b1adca0

commit f8a926bebe819c09e04261fb212cacbf3b1adca0
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-08-23 03:30:06 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-08-31 01:20:28 +0000

    libc: add scandirat(3)
    
    (cherry picked from commit 9fb8e8eede5b48eda7dc39f61d815595c14e5752)
---
 include/dirent.h        |  5 +++++
 lib/libc/gen/Symbol.map |  1 +
 lib/libc/gen/scandir.c  | 21 +++++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/include/dirent.h b/include/dirent.h
index 702153e28fc0..047206258471 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -131,6 +131,11 @@ int	 scandir_b(const char *, struct dirent ***,
 	    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/Symbol.map b/lib/libc/gen/Symbol.map
index 012c9ff11f04..74676ffe2270 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -439,6 +439,7 @@ FBSD_1.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.c b/lib/libc/gen/scandir.c
index 4cfc823e4f94..3a891b0ad3f2 100644
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -42,8 +42,10 @@ __FBSDID("$FreeBSD$");
 
 #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
@@ -159,6 +161,25 @@ scandir(const char *dirname, struct dirent ***namelist,
 }
 
 #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().