int parse_devnum(const char *s, dev_t *ret);
+#define DEVNUM_MAJOR_MAX ((UINT32_C(1) << 12) - 1U)
+#define DEVNUM_MINOR_MAX ((UINT32_C(1) << 20) - 1U)
+
/* glibc and the Linux kernel have different ideas about the major/minor size. These calls will check whether the
* specified major is valid by the Linux kernel's standards, not by glibc's. Linux has 20bits of minor, and 12 bits of
* major space. See MINORBITS in linux/kdev_t.h in the kernel sources. (If you wonder why we define _y here, instead of
#define DEVICE_MAJOR_VALID(x) \
({ \
typeof(x) _x = (x), _y = 0; \
- _x >= _y && _x < (UINT32_C(1) << 12); \
+ _x >= _y && _x <= DEVNUM_MAJOR_MAX; \
\
})
#define DEVICE_MINOR_VALID(x) \
({ \
typeof(x) _x = (x), _y = 0; \
- _x >= _y && _x < (UINT32_C(1) << 20); \
+ _x >= _y && _x <= DEVNUM_MINOR_MAX; \
})
int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret);
static inline bool devnum_is_zero(dev_t d) {
return major(d) == 0 && minor(d) == 0;
}
+
+#define DEVNUM_TO_PTR(u) ((void*) (uintptr_t) (u))
+#define PTR_TO_DEVNUM(p) ((dev_t) ((uintptr_t) (p)))
test_devnum_format_str_one(makedev(4095, 1048575), "4095:1048575");
}
+TEST(devnum_to_ptr) {
+ dev_t m = makedev(0, 0);
+ ASSERT_EQ(major(m), 0U);
+ ASSERT_EQ(minor(m), 0U);
+ ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m)));
+
+ m = makedev(DEVNUM_MAJOR_MAX, DEVNUM_MINOR_MAX);
+ ASSERT_EQ(major(m), DEVNUM_MAJOR_MAX);
+ ASSERT_EQ(minor(m), DEVNUM_MINOR_MAX);
+ ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m)));
+
+ m = makedev(5, 8);
+ ASSERT_EQ(major(m), 5U);
+ ASSERT_EQ(minor(m), 8U);
+ ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m)));
+}
+
DEFINE_TEST_MAIN(LOG_INFO);