xref: /freebsd/lib/libutil/tests/getlocalbase_test.c (revision d15f2551b25f79ddcbe289faa95e655100b952da)
1 /*-
2  * Copyright (c) 2026 Dag-Erling Smørgrav
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <sys/param.h>
8 #include <sys/wait.h>
9 
10 #include <libutil.h>
11 #include <paths.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #include <atf-c.h>
17 
18 #define INVALID_PREFIX "/dev/null/"
19 
20 #define X31 "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
21 #define X32 "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
22 #define X64 X32 X32
23 #define X128 X64 X64
24 #define X256 X128 X128
25 #define X512 X256 X256
26 #define X1024 X512 X512
27 #define X1023 X512 X256 X128 X64 X32 X31
28 
29 static struct {
30 	const char *in, *out;
31 } tests[] = {
32 	{ "", _PATH_LOCALBASE },
33 	{ "/", "/" },
34 	{ "//", "/" },
35 	{ "///", "/" },
36 	{ "foo", INVALID_PREFIX },
37 	{ "/foo", "/foo" },
38 	{ "//foo", "/foo" },
39 	{ "/foo/", "/foo" },
40 	{ "/foo//", "/foo" },
41 	{ "//foo//", "/foo" },
42 	{ "/foo/bar", "/foo/bar" },
43 	{ "/foo/bar/", "/foo/bar" },
44 	{ "/foo//bar", "/foo/bar" },
45 	{ "/foo//bar/", "/foo/bar" },
46 	{ "//foo/bar", "/foo/bar" },
47 	{ "//foo/bar/", "/foo/bar" },
48 	{ "//foo//bar", "/foo/bar" },
49 	{ "//foo//bar/", "/foo/bar" },
50 	{ _PATH_LOCALBASE, _PATH_LOCALBASE },
51 	{ X31, X31 },
52 	{ X32, X32 },
53 	{ X64, X64 },
54 	{ X128, X128 },
55 	{ X256, X256 },
56 	{ X512, X512 },
57 	{ X1023, X1023 },
58 	{ X1024, INVALID_PREFIX },
59 	{ 0 }
60 };
61 _Static_assert(sizeof(X1023) == MAXPATHLEN, "Unexpected MAXPATHLEN value");
62 
63 ATF_TC(environment);
64 ATF_TC_HEAD(environment, tc)
65 {
66 	atf_tc_set_md_var(tc, "descr", "Tests getting the local base from the "
67 	    "environment and path normalization");
68 }
69 
70 ATF_TC_BODY(environment, tc)
71 {
72 	pid_t pid;
73 	int i, wstatus;
74 
75 	for (i = 0; tests[i].in != NULL; i++) {
76 		ATF_REQUIRE((pid = fork()) >= 0);
77 		if (pid == 0) {
78 			ATF_REQUIRE_EQ(setenv("LOCALBASE", tests[i].in, 1), 0);
79 			ATF_REQUIRE_STREQ(getlocalbase(), tests[i].out);
80 			_exit(0);
81 		}
82 		ATF_REQUIRE_EQ(waitpid(0, &wstatus, 0), pid);
83 		ATF_CHECK(WIFEXITED(wstatus));
84 		ATF_CHECK_EQ(WEXITSTATUS(wstatus), 0);
85 	}
86 }
87 
88 ATF_TP_ADD_TCS(tp)
89 {
90 	ATF_TP_ADD_TC(tp, environment);
91 	return (atf_no_error());
92 }
93