aboutsummaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorBojan Novković <bnovkov@FreeBSD.org>2025-05-23 13:26:34 +0000
committerBojan Novković <bnovkov@FreeBSD.org>2025-06-02 09:32:55 +0000
commit4d7c31bca252fbbd0808875cf0ad87fc0d91278f (patch)
treecde982c7fb89bed5931add54b0a658db43a058a0 /lib/libc
parent1e0743f54d2d3624cd4de2167d373aa38597778e (diff)
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/tests/gen/Makefile5
-rw-r--r--lib/libc/tests/gen/glob2_test.c60
-rw-r--r--lib/libc/tests/gen/glob_blocks_test.c49
3 files changed, 112 insertions, 2 deletions
diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile
index 2aff14f078bc..006512d30dc4 100644
--- a/lib/libc/tests/gen/Makefile
+++ b/lib/libc/tests/gen/Makefile
@@ -15,6 +15,9 @@ ATF_TESTS_C+= ftw_test
ATF_TESTS_C+= getentropy_test
ATF_TESTS_C+= getmntinfo_test
ATF_TESTS_C+= glob2_test
+.if ${COMPILER_FEATURES:Mblocks}
+ATF_TESTS_C+= glob_blocks_test
+.endif
ATF_TESTS_C+= makecontext_test
ATF_TESTS_C+= popen_test
ATF_TESTS_C+= posix_spawn_test
@@ -97,7 +100,7 @@ TESTS_SUBDIRS= execve
TESTS_SUBDIRS+= posix_spawn
# Tests that require blocks support
-.for t in fts_blocks_test
+.for t in fts_blocks_test glob_blocks_test
CFLAGS.${t}.c+= -fblocks
LIBADD.${t}+= BlocksRuntime
.endfor
diff --git a/lib/libc/tests/gen/glob2_test.c b/lib/libc/tests/gen/glob2_test.c
index 8f69c36fece7..45d17b063593 100644
--- a/lib/libc/tests/gen/glob2_test.c
+++ b/lib/libc/tests/gen/glob2_test.c
@@ -25,6 +25,8 @@
*/
#include <sys/param.h>
+#include <sys/stat.h>
+
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
@@ -36,6 +38,8 @@
#include <atf-c.h>
+static int glob_callback_invoked;
+
/*
* Derived from Russ Cox' pathological case test program used for the
* https://research.swtch.com/glob article.
@@ -102,10 +106,64 @@ ATF_TC_BODY(glob_pathological_test, tc)
}
}
+ATF_TC(glob_period);
+ATF_TC_HEAD(glob_period, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test behaviour when matching files that start with a period"
+ "(documented in the glob(3) CAVEATS section).");
+}
+ATF_TC_BODY(glob_period, tc)
+{
+ int i;
+ glob_t g;
+
+ atf_utils_create_file(".test", "");
+ glob(".", 0, NULL, &g);
+ ATF_REQUIRE_MSG(g.gl_matchc == 1,
+ "glob(3) shouldn't match files starting with a period when using '.'");
+ for (i = 0; i < g.gl_matchc; i++)
+ printf("%s\n", g.gl_pathv[i]);
+ glob(".*", 0, NULL, &g);
+ ATF_REQUIRE_MSG(g.gl_matchc == 3 && strcmp(g.gl_pathv[2], ".test") == 0,
+ "glob(3) should match files starting with a period when using '.*'");
+}
+
+static int
+errfunc(const char *path, int err)
+{
+ ATF_REQUIRE_STREQ(path, "test/");
+ ATF_REQUIRE(err == EACCES);
+ glob_callback_invoked = 1;
+ /* Suppress EACCES errors. */
+ return (0);
+}
+
+ATF_TC_WITHOUT_HEAD(glob_callback_test);
+ATF_TC_BODY(glob_callback_test, tc)
+{
+ int rv;
+ glob_t g;
+
+ glob_callback_invoked = 0;
+ ATF_REQUIRE_EQ(0, mkdir("test", 0007));
+ rv = glob("test/*", 0, errfunc, &g);
+ ATF_REQUIRE_MSG(glob_callback_invoked == 1,
+ "glob(3) failed to invoke callback function");
+ ATF_REQUIRE_MSG(rv == GLOB_NOMATCH,
+ "error callback function failed to suppress EACCES");
+
+ /* GLOB_ERR should ignore the suppressed error. */
+ rv = glob("test/*", GLOB_ERR, errfunc, &g);
+ ATF_REQUIRE_MSG(rv == GLOB_ABORTED,
+ "GLOB_ERR didn't override error callback function");
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, glob_pathological_test);
-
+ ATF_TP_ADD_TC(tp, glob_period);
+ ATF_TP_ADD_TC(tp, glob_callback_test);
return (atf_no_error());
}
diff --git a/lib/libc/tests/gen/glob_blocks_test.c b/lib/libc/tests/gen/glob_blocks_test.c
new file mode 100644
index 000000000000..a20aad17ce31
--- /dev/null
+++ b/lib/libc/tests/gen/glob_blocks_test.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2025 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <glob.h>
+
+#include <atf-c.h>
+
+static int glob_callback_invoked;
+
+ATF_TC_WITHOUT_HEAD(glob_b_callback_test);
+ATF_TC_BODY(glob_b_callback_test, tc)
+{
+ int rv;
+ glob_t g;
+
+ glob_callback_invoked = 0;
+ ATF_REQUIRE_EQ(0, mkdir("test", 0007));
+ int (^errblk)(const char *, int) =
+ ^(const char *path, int err) {
+ ATF_REQUIRE_STREQ(path, "test/");
+ ATF_REQUIRE(err == EACCES);
+ glob_callback_invoked = 1;
+ /* Suppress EACCES errors. */
+ return (0);
+ };
+
+ rv = glob_b("test/*", 0, errblk, &g);
+ ATF_REQUIRE_MSG(glob_callback_invoked == 1,
+ "glob(3) failed to invoke callback block");
+ ATF_REQUIRE_MSG(rv == GLOB_NOMATCH,
+ "error callback function failed to suppress EACCES");
+
+ /* GLOB_ERR should ignore the suppressed error. */
+ rv = glob_b("test/*", GLOB_ERR, errblk, &g);
+ ATF_REQUIRE_MSG(rv == GLOB_ABORTED,
+ "GLOB_ERR didn't override error callback block");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, glob_b_callback_test);
+ return (atf_no_error());
+}