xref: /freebsd/lib/libc/tests/gen/glob_blocks_test.c (revision 7fe39bec801a08f541d0111219fe8701a6a20cf1)
14d7c31bcSBojan Novković /*-
24d7c31bcSBojan Novković  * Copyright (c) 2025 Klara, Inc.
34d7c31bcSBojan Novković  *
44d7c31bcSBojan Novković  * SPDX-License-Identifier: BSD-2-Clause
54d7c31bcSBojan Novković  */
64d7c31bcSBojan Novković 
74d7c31bcSBojan Novković #include <sys/stat.h>
84d7c31bcSBojan Novković 
94d7c31bcSBojan Novković #include <errno.h>
104d7c31bcSBojan Novković #include <glob.h>
11*7fe39becSDag-Erling Smørgrav #include <stdbool.h>
124d7c31bcSBojan Novković 
134d7c31bcSBojan Novković #include <atf-c.h>
144d7c31bcSBojan Novković 
15*7fe39becSDag-Erling Smørgrav ATF_TC(glob_b_callback);
ATF_TC_HEAD(glob_b_callback,tc)16*7fe39becSDag-Erling Smørgrav ATF_TC_HEAD(glob_b_callback, tc)
174d7c31bcSBojan Novković {
18*7fe39becSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr",
19*7fe39becSDag-Erling Smørgrav 	    "Test ability of callback block to suppress errors");
20*7fe39becSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "require.user", "unprivileged");
21*7fe39becSDag-Erling Smørgrav }
ATF_TC_BODY(glob_b_callback,tc)22*7fe39becSDag-Erling Smørgrav ATF_TC_BODY(glob_b_callback, tc)
23*7fe39becSDag-Erling Smørgrav {
24*7fe39becSDag-Erling Smørgrav 	static bool glob_callback_invoked;
25*7fe39becSDag-Erling Smørgrav 	static int (^errblk)(const char *, int) =
264d7c31bcSBojan Novković 	    ^(const char *path, int err) {
27*7fe39becSDag-Erling Smørgrav 		ATF_CHECK_STREQ(path, "test/");
28*7fe39becSDag-Erling Smørgrav 		ATF_CHECK(err == EACCES);
29*7fe39becSDag-Erling Smørgrav 		glob_callback_invoked = true;
304d7c31bcSBojan Novković 		/* Suppress EACCES errors. */
314d7c31bcSBojan Novković 		return (0);
324d7c31bcSBojan Novković 	};
33*7fe39becSDag-Erling Smørgrav 	glob_t g;
34*7fe39becSDag-Erling Smørgrav 	int rv;
354d7c31bcSBojan Novković 
36*7fe39becSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, mkdir("test", 0755));
37*7fe39becSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("foo", "test/foo"));
38*7fe39becSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, chmod("test", 0));
39*7fe39becSDag-Erling Smørgrav 
40*7fe39becSDag-Erling Smørgrav 	glob_callback_invoked = false;
414d7c31bcSBojan Novković 	rv = glob_b("test/*", 0, errblk, &g);
42*7fe39becSDag-Erling Smørgrav 	ATF_CHECK_MSG(glob_callback_invoked,
434d7c31bcSBojan Novković 	    "glob(3) failed to invoke callback block");
44*7fe39becSDag-Erling Smørgrav 	ATF_CHECK_EQ_MSG(GLOB_NOMATCH, rv,
45*7fe39becSDag-Erling Smørgrav 	    "callback function failed to suppress EACCES");
46*7fe39becSDag-Erling Smørgrav 	globfree(&g);
474d7c31bcSBojan Novković 
484d7c31bcSBojan Novković 	/* GLOB_ERR should ignore the suppressed error. */
49*7fe39becSDag-Erling Smørgrav 	glob_callback_invoked = false;
504d7c31bcSBojan Novković 	rv = glob_b("test/*", GLOB_ERR, errblk, &g);
51*7fe39becSDag-Erling Smørgrav 	ATF_CHECK_MSG(glob_callback_invoked,
52*7fe39becSDag-Erling Smørgrav 	    "glob(3) failed to invoke callback block");
53*7fe39becSDag-Erling Smørgrav 	ATF_CHECK_EQ_MSG(GLOB_ABORTED, rv,
54*7fe39becSDag-Erling Smørgrav 	    "GLOB_ERR didn't override callback block");
55*7fe39becSDag-Erling Smørgrav 	globfree(&g);
564d7c31bcSBojan Novković }
574d7c31bcSBojan Novković 
ATF_TP_ADD_TCS(tp)584d7c31bcSBojan Novković ATF_TP_ADD_TCS(tp)
594d7c31bcSBojan Novković {
60*7fe39becSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, glob_b_callback);
614d7c31bcSBojan Novković 	return (atf_no_error());
624d7c31bcSBojan Novković }
63