1*0351610fSriastradh /* $NetBSD: t_paths.c,v 1.19 2023/08/05 12:11:05 riastradh Exp $ */
28c6b9e26Sjruoho
38c6b9e26Sjruoho /*-
48c6b9e26Sjruoho * Copyright (c) 2011 The NetBSD Foundation, Inc.
58c6b9e26Sjruoho * All rights reserved.
68c6b9e26Sjruoho *
78c6b9e26Sjruoho * This code is derived from software contributed to The NetBSD Foundation
88c6b9e26Sjruoho * by Jukka Ruohonen.
98c6b9e26Sjruoho *
108c6b9e26Sjruoho * Redistribution and use in source and binary forms, with or without
118c6b9e26Sjruoho * modification, are permitted provided that the following conditions
128c6b9e26Sjruoho * are met:
138c6b9e26Sjruoho * 1. Redistributions of source code must retain the above copyright
148c6b9e26Sjruoho * notice, this list of conditions and the following disclaimer.
158c6b9e26Sjruoho * 2. Redistributions in binary form must reproduce the above copyright
168c6b9e26Sjruoho * notice, this list of conditions and the following disclaimer in the
178c6b9e26Sjruoho * documentation and/or other materials provided with the distribution.
188c6b9e26Sjruoho *
198c6b9e26Sjruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
208c6b9e26Sjruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
218c6b9e26Sjruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
228c6b9e26Sjruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
238c6b9e26Sjruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
248c6b9e26Sjruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
258c6b9e26Sjruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
268c6b9e26Sjruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
278c6b9e26Sjruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
288c6b9e26Sjruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
298c6b9e26Sjruoho * POSSIBILITY OF SUCH DAMAGE.
308c6b9e26Sjruoho */
318c6b9e26Sjruoho #include <sys/cdefs.h>
32*0351610fSriastradh __RCSID("$NetBSD: t_paths.c,v 1.19 2023/08/05 12:11:05 riastradh Exp $");
338c6b9e26Sjruoho
348c6b9e26Sjruoho #include <sys/param.h>
358c6b9e26Sjruoho #include <sys/stat.h>
368c6b9e26Sjruoho
378c6b9e26Sjruoho #include <errno.h>
388c6b9e26Sjruoho #include <fcntl.h>
398c6b9e26Sjruoho #include <paths.h>
40cc7aae5dSjruoho #include <stdio.h>
418c6b9e26Sjruoho #include <string.h>
428c6b9e26Sjruoho #include <unistd.h>
438c6b9e26Sjruoho
448c6b9e26Sjruoho #include <atf-c.h>
458c6b9e26Sjruoho
468c6b9e26Sjruoho #define PATH_DEV __BIT(0) /* A device node */
478c6b9e26Sjruoho #define PATH_DIR __BIT(1) /* A directory */
488c6b9e26Sjruoho #define PATH_FILE __BIT(2) /* A file */
498c6b9e26Sjruoho #define PATH_ROOT __BIT(3) /* Access for root only */
509f8be638Spgoyette #define PATH_OPT __BIT(3) /* Optional, ENODEV if not supported */
518c6b9e26Sjruoho
528c6b9e26Sjruoho static const struct {
538c6b9e26Sjruoho const char *path;
548c6b9e26Sjruoho int flags;
558c6b9e26Sjruoho } paths[] = {
568c6b9e26Sjruoho { _PATH_AUDIO, PATH_DEV },
578c6b9e26Sjruoho { _PATH_AUDIO0, PATH_DEV },
588c6b9e26Sjruoho { _PATH_AUDIOCTL, PATH_DEV },
598c6b9e26Sjruoho { _PATH_AUDIOCTL0, PATH_DEV },
608c6b9e26Sjruoho { _PATH_BPF, PATH_DEV | PATH_ROOT },
618c6b9e26Sjruoho { _PATH_CLOCKCTL, PATH_DEV | PATH_ROOT },
62e1bbe644Sjruoho { _PATH_CONSOLE, PATH_DEV | PATH_ROOT },
638c6b9e26Sjruoho { _PATH_CONSTTY, PATH_DEV | PATH_ROOT },
64be8b5eb2Sjruoho { _PATH_CPUCTL, PATH_DEV },
658c6b9e26Sjruoho { _PATH_CSMAPPER, PATH_DIR },
668c6b9e26Sjruoho { _PATH_DEFTAPE, PATH_DEV | PATH_ROOT },
671907ec3aSjoerg { _PATH_DEVCDB, PATH_FILE },
688c6b9e26Sjruoho { _PATH_DEVDB, PATH_FILE },
698c6b9e26Sjruoho { _PATH_DEVNULL, PATH_DEV },
708c6b9e26Sjruoho { _PATH_DRUM, PATH_DEV | PATH_ROOT },
718c6b9e26Sjruoho { _PATH_ESDB, PATH_DIR },
728c6b9e26Sjruoho { _PATH_FTPUSERS, PATH_FILE },
738c6b9e26Sjruoho { _PATH_GETTYTAB, PATH_FILE },
748c6b9e26Sjruoho { _PATH_I18NMODULE, PATH_DIR },
758c6b9e26Sjruoho { _PATH_ICONV, PATH_DIR },
768c6b9e26Sjruoho { _PATH_KMEM, PATH_DEV | PATH_ROOT },
773f8fc68fSriastradh { _PATH_KSYMS, PATH_DEV | PATH_ROOT },
788c6b9e26Sjruoho { _PATH_KVMDB, PATH_FILE },
798c6b9e26Sjruoho { _PATH_LOCALE, PATH_DIR },
808c6b9e26Sjruoho { _PATH_MAILDIR, PATH_DIR },
818c6b9e26Sjruoho { _PATH_MAN, PATH_DIR },
828c6b9e26Sjruoho { _PATH_MEM, PATH_DEV | PATH_ROOT },
838c6b9e26Sjruoho { _PATH_MIXER, PATH_DEV },
848c6b9e26Sjruoho { _PATH_MIXER0, PATH_DEV },
858c6b9e26Sjruoho { _PATH_NOLOGIN, PATH_FILE },
869f8be638Spgoyette { _PATH_POWER, PATH_DEV | PATH_ROOT | PATH_OPT },
878c6b9e26Sjruoho { _PATH_PRINTCAP, PATH_FILE },
888c6b9e26Sjruoho { _PATH_PUD, PATH_DEV | PATH_ROOT },
898c6b9e26Sjruoho { _PATH_PUFFS, PATH_DEV | PATH_ROOT },
908c6b9e26Sjruoho { _PATH_RANDOM, PATH_DEV },
918c6b9e26Sjruoho { _PATH_SENDMAIL, PATH_FILE },
928c6b9e26Sjruoho { _PATH_SHELLS, PATH_FILE },
938c6b9e26Sjruoho { _PATH_SKEYKEYS, PATH_FILE | PATH_ROOT },
948c6b9e26Sjruoho { _PATH_SOUND, PATH_DEV },
958c6b9e26Sjruoho { _PATH_SOUND0, PATH_DEV },
969f8be638Spgoyette { _PATH_SYSMON, PATH_DEV | PATH_OPT },
978c6b9e26Sjruoho { _PATH_TTY, PATH_DEV },
98be8b5eb2Sjruoho { _PATH_UNIX, PATH_FILE | PATH_ROOT },
998c6b9e26Sjruoho { _PATH_URANDOM, PATH_DEV },
1008c6b9e26Sjruoho { _PATH_VIDEO, PATH_DEV },
1018c6b9e26Sjruoho { _PATH_VIDEO0, PATH_DEV },
1029f8be638Spgoyette { _PATH_WATCHDOG, PATH_DEV | PATH_OPT },
1038c6b9e26Sjruoho
1048c6b9e26Sjruoho { _PATH_DEV, PATH_DIR },
1058c6b9e26Sjruoho { _PATH_DEV_PTS, PATH_DIR },
1068c6b9e26Sjruoho { _PATH_EMUL_AOUT, PATH_DIR },
1078c6b9e26Sjruoho { _PATH_TMP, PATH_DIR },
1088c6b9e26Sjruoho { _PATH_VARDB, PATH_DIR },
1098c6b9e26Sjruoho { _PATH_VARRUN, PATH_DIR },
1108c6b9e26Sjruoho { _PATH_VARTMP, PATH_DIR },
1118c6b9e26Sjruoho
1128c6b9e26Sjruoho { _PATH_BSHELL, PATH_FILE },
1138c6b9e26Sjruoho { _PATH_CSHELL, PATH_FILE },
1148c6b9e26Sjruoho { _PATH_VI, PATH_FILE },
1158c6b9e26Sjruoho };
1168c6b9e26Sjruoho
1178c6b9e26Sjruoho ATF_TC(paths);
ATF_TC_HEAD(paths,tc)1188c6b9e26Sjruoho ATF_TC_HEAD(paths, tc)
1198c6b9e26Sjruoho {
1208c6b9e26Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test for <paths.h>");
1218c6b9e26Sjruoho }
1228c6b9e26Sjruoho
ATF_TC_BODY(paths,tc)1238c6b9e26Sjruoho ATF_TC_BODY(paths, tc)
1248c6b9e26Sjruoho {
1258c6b9e26Sjruoho struct stat st;
1268c6b9e26Sjruoho uid_t uid;
1278c6b9e26Sjruoho mode_t m;
1288c6b9e26Sjruoho size_t i;
1298c6b9e26Sjruoho int fd;
1308c6b9e26Sjruoho
131e110dcc9Sjmmv #if defined(__sparc__)
1322f943d64Sjruoho atf_tc_skip("PR port-sparc/45580");
133e110dcc9Sjmmv #endif
1342f943d64Sjruoho
1358c6b9e26Sjruoho uid = getuid();
1368c6b9e26Sjruoho
1378c6b9e26Sjruoho for (i = 0; i < __arraycount(paths); i++) {
138cc7aae5dSjruoho (void)fprintf(stderr, "testing '%s'\n", paths[i].path);
139cc7aae5dSjruoho
1408c6b9e26Sjruoho errno = 0;
1418c6b9e26Sjruoho fd = open(paths[i].path, O_RDONLY);
1428c6b9e26Sjruoho if (fd < 0) {
1438c6b9e26Sjruoho switch (errno) {
1449f8be638Spgoyette case ENODEV:
1459f8be638Spgoyette if ((paths[i].flags & PATH_OPT) == 0) {
146*0351610fSriastradh atf_tc_fail_nonfatal("Required path %s"
147*0351610fSriastradh " does not exist", paths[i].path);
148*0351610fSriastradh continue;
1499f8be638Spgoyette }
1509f8be638Spgoyette break;
1518c6b9e26Sjruoho case EPERM: /* FALLTHROUGH */
1528c6b9e26Sjruoho case EACCES: /* FALLTHROUGH */
1538c6b9e26Sjruoho if ((paths[i].flags & PATH_ROOT) == 0) {
154*0351610fSriastradh atf_tc_fail_nonfatal("UID %u"
155*0351610fSriastradh " failed to open %s,"
156*0351610fSriastradh " error %d (%s)",
157*0351610fSriastradh (uint32_t)uid,
158*0351610fSriastradh paths[i].path,
159*0351610fSriastradh errno, strerror(errno));
160*0351610fSriastradh continue;
1618c6b9e26Sjruoho }
162fbffadb9Smrg /* FALLTHROUGH */
1638c6b9e26Sjruoho case EBUSY: /* FALLTHROUGH */
1648c6b9e26Sjruoho case ENXIO: /* FALLTHROUGH */
1658c6b9e26Sjruoho case ENOENT: /* FALLTHROUGH */
1668c6b9e26Sjruoho default:
1678c6b9e26Sjruoho continue;
1688c6b9e26Sjruoho }
1698c6b9e26Sjruoho }
1708c6b9e26Sjruoho
1718c6b9e26Sjruoho (void)memset(&st, 0, sizeof(struct stat));
1728c6b9e26Sjruoho
173*0351610fSriastradh if (fstat(fd, &st) == -1) {
174*0351610fSriastradh atf_tc_fail_nonfatal("fstat %s failed, error %d (%s)",
175*0351610fSriastradh paths[i].path, errno, strerror(errno));
176*0351610fSriastradh ATF_CHECK(close(fd) == 0);
177*0351610fSriastradh continue;
178*0351610fSriastradh }
1798c6b9e26Sjruoho
1808c6b9e26Sjruoho m = st.st_mode;
1818c6b9e26Sjruoho
1828c6b9e26Sjruoho if ((paths[i].flags & PATH_DEV) != 0) {
183730b47d6Snjoly ATF_CHECK(S_ISBLK(m) != 0 || S_ISCHR(m) != 0);
184730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_DIR) == 0);
185730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_FILE) == 0);
1868c6b9e26Sjruoho }
1878c6b9e26Sjruoho
1888c6b9e26Sjruoho if ((paths[i].flags & PATH_DIR) != 0) {
189730b47d6Snjoly ATF_CHECK(S_ISDIR(m) != 0);
190730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_DEV) == 0);
191730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_FILE) == 0);
1928c6b9e26Sjruoho }
1938c6b9e26Sjruoho
1948c6b9e26Sjruoho if ((paths[i].flags & PATH_FILE) != 0) {
195730b47d6Snjoly ATF_CHECK(S_ISREG(m) != 0);
196730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_DEV) == 0);
197730b47d6Snjoly ATF_CHECK((paths[i].flags & PATH_DIR) == 0);
1988c6b9e26Sjruoho }
1998c6b9e26Sjruoho
200*0351610fSriastradh ATF_CHECK(close(fd) == 0);
2018c6b9e26Sjruoho }
2028c6b9e26Sjruoho }
2038c6b9e26Sjruoho
ATF_TP_ADD_TCS(tp)2048c6b9e26Sjruoho ATF_TP_ADD_TCS(tp)
2058c6b9e26Sjruoho {
2068c6b9e26Sjruoho
2078c6b9e26Sjruoho ATF_TP_ADD_TC(tp, paths);
2088c6b9e26Sjruoho
2098c6b9e26Sjruoho return atf_no_error();
2108c6b9e26Sjruoho }
211