Files
erofs-freebsd-out-tree/tests/stat_special.c
T
2026-08-13 10:44:59 +02:00

71 lines
2.1 KiB
C

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static unsigned int
parse_number(const char *text)
{
char *end;
unsigned long value;
errno = 0;
value = strtoul(text, &end, 0);
if (errno != 0 || *end != '\0' || value > UINT_MAX)
errx(2, "invalid number: %s", text);
return ((unsigned int)value);
}
int
main(int argc, char **argv)
{
struct stat sb;
unsigned int expected_major, expected_minor;
bool is_device;
if (argc != 3 && argc != 5)
errx(2, "usage: stat_special char|block path major minor | "
"stat_special fifo path");
if (lstat(argv[2], &sb) != 0)
err(1, "lstat %s", argv[2]);
is_device = strcmp(argv[1], "char") == 0 || strcmp(argv[1], "block") == 0;
if (is_device) {
if (argc != 5)
errx(2, "device checks require major and minor");
expected_major = parse_number(argv[3]);
expected_minor = parse_number(argv[4]);
if ((strcmp(argv[1], "char") == 0 && !S_ISCHR(sb.st_mode)) ||
(strcmp(argv[1], "block") == 0 && !S_ISBLK(sb.st_mode)))
errx(1, "%s has the wrong file type", argv[2]);
if ((unsigned int)major(sb.st_rdev) != expected_major ||
(unsigned int)minor(sb.st_rdev) != expected_minor)
errx(1, "%s rdev=%#jx major=%u minor=%u, expected %u:%u",
argv[2], (uintmax_t)sb.st_rdev,
(unsigned int)major(sb.st_rdev),
(unsigned int)minor(sb.st_rdev), expected_major,
expected_minor);
} else if (strcmp(argv[1], "fifo") == 0) {
if (argc != 3)
errx(2, "FIFO checks do not take major and minor");
if (!S_ISFIFO(sb.st_mode))
errx(1, "%s is not a FIFO", argv[2]);
if (sb.st_rdev != NODEV)
errx(1, "%s FIFO st_rdev=%#jx, expected NODEV", argv[2],
(uintmax_t)sb.st_rdev);
} else {
errx(2, "unknown type: %s", argv[1]);
}
printf("PASS path=%s type=%s rdev=%#jx major=%u minor=%u\n", argv[2],
argv[1], (uintmax_t)sb.st_rdev, (unsigned int)major(sb.st_rdev),
(unsigned int)minor(sb.st_rdev));
return (0);
}