Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 05 Feb 2026 15:27:22 +0000
From:      Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 90c5d1b5f423 - stable/14 - scandir: Fix behavior when no entries match.
Message-ID:  <6984b6da.18324.3945b4d7@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/14 has been updated by des:

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

commit 90c5d1b5f4238823414a82b72e7f80d9e83a3de6
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-06-20 16:13:48 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-02-05 14:47:46 +0000

    scandir: Fix behavior when no entries match.
    
    In the previous commit, I removed the initial initialization of the
    `names` array, not realizing that `scandir()` is expected to return
    a non-null (but empty) array of entries if no entries matched.
    Restore the historical behavior, document it, and add a test.
    
    Fixes:          deeebfdecab5
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans, allanjude, markj
    Differential Revision:  https://reviews.freebsd.org/D50949
    
    (cherry picked from commit c187b673bb79905b5d5db1eb34d5a893c4464eeb)
---
 lib/libc/gen/scandir.3            |  5 +++--
 lib/libc/gen/scandir.c            |  6 +++++-
 lib/libc/tests/gen/scandir_test.c | 22 ++++++++++++++++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3
index d9ae8f687168..c55c69eeca24 100644
--- a/lib/libc/gen/scandir.3
+++ b/lib/libc/gen/scandir.3
@@ -27,7 +27,7 @@
 .\"
 .\"     @(#)scandir.3	8.1 (Berkeley) 6/4/93
 .\"
-.Dd June 19, 2025
+.Dd June 20, 2025
 .Dt SCANDIR 3
 .Os
 .Sh NAME
@@ -104,7 +104,8 @@ entries using
 It returns the number of entries in the array.
 A pointer to the array of directory entries is stored in the location
 referenced by
-.Fa namelist .
+.Fa namelist
+(even if no entries were selected).
 .Pp
 The
 .Fa select
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
index 54f92bafc115..36abe9f37047 100644
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -76,9 +76,13 @@ scandir_dirp(DIR *dirp, struct dirent ***namelist,
 #endif
 {
 	struct dirent *d, *p = NULL, **names = NULL, **names2;
-	size_t arraysz = 0, numitems = 0;
+	size_t arraysz = 32, numitems = 0;
 	int serrno;
 
+	names = malloc(arraysz * sizeof(*names));
+	if (names == NULL)
+		return (-1);
+
 	while ((d = readdir(dirp)) != NULL) {
 		if (select != NULL && !SELECT(d))
 			continue;	/* just selected names */
diff --git a/lib/libc/tests/gen/scandir_test.c b/lib/libc/tests/gen/scandir_test.c
index 54848c0572ca..dcd73fe94df5 100644
--- a/lib/libc/tests/gen/scandir_test.c
+++ b/lib/libc/tests/gen/scandir_test.c
@@ -103,10 +103,32 @@ ATF_TC_BODY(scandirat_test, tc)
 	ATF_REQUIRE_EQ(0, close(fd));
 }
 
+static int
+scandir_none(const struct dirent *ent __unused)
+{
+	return (0);
+}
+
+ATF_TC(scandir_none);
+ATF_TC_HEAD(scandir_none, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test scandir() when no entries are selected");
+}
+ATF_TC_BODY(scandir_none, tc)
+{
+	struct dirent **namelist = NULL;
+
+	ATF_REQUIRE_EQ(0, scandir(".", &namelist, scandir_none, alphasort));
+	ATF_REQUIRE(namelist);
+	free(namelist);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, scandir_test);
 	ATF_TP_ADD_TC(tp, fscandir_test);
 	ATF_TP_ADD_TC(tp, scandirat_test);
+	ATF_TP_ADD_TC(tp, scandir_none);
 	return (atf_no_error());
 }


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6984b6da.18324.3945b4d7>