1//! Compare libc's makdev function against the actual C macros, for various
2//! inputs.
3
4extern crate libc;
5
6#[cfg(any(
7    target_os = "android",
8    target_os = "dragonfly",
9    target_os = "emscripten",
10    target_os = "freebsd",
11    target_os = "fuchsia",
12    target_os = "linux",
13    target_os = "netbsd",
14    target_os = "openbsd",
15))]
16mod t {
17    use libc::{self, c_uint, dev_t};
18
19    extern "C" {
20        pub fn makedev_ffi(major: c_uint, minor: c_uint) -> dev_t;
21    }
22
23    fn compare(major: c_uint, minor: c_uint) {
24        let expected = unsafe { makedev_ffi(major, minor) };
25        assert_eq!(libc::makedev(major, minor), expected);
26    }
27
28    // Every OS should be able to handle 8 bit major and minor numbers
29    #[test]
30    fn test_8bits() {
31        for major in 0..256 {
32            for minor in 0..256 {
33                compare(major, minor);
34            }
35        }
36    }
37
38    // Android allows 12 bits for major and 20 for minor
39    #[test]
40    #[cfg(target_os = "android")]
41    fn test_android_like() {
42        for major in [0, 1, 255, 256, 4095] {
43            for minor_exp in [1, 8, 16] {
44                for minor in [(1 << minor_exp) - 1, (1 << minor_exp)] {
45                    compare(major, minor);
46                }
47            }
48            compare(major, (1 << 20) - 1);
49        }
50    }
51
52    // These OSes allow 32 bits for minor, but only 8 for major
53    #[test]
54    #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd",))]
55    fn test_fbsd11_like() {
56        for major in [0, 1, 255] {
57            for minor_exp in [1, 8, 16, 24, 31] {
58                for minor in [(1 << minor_exp) - 1, (1 << minor_exp)] {
59                    compare(major, minor);
60                }
61            }
62            compare(major, c_uint::MAX);
63        }
64    }
65
66    // OpenBSD allows 8 bits for major and 24 for minor
67    #[test]
68    #[cfg(target_os = "openbsd")]
69    fn test_openbsd_like() {
70        for major in [0, 1, 255] {
71            for minor_exp in [1, 8, 16] {
72                for minor in [(1 << minor_exp) - 1, (1 << minor_exp)] {
73                    compare(major, minor);
74                }
75            }
76            compare(major, (1 << 24) - 1);
77        }
78    }
79
80    // These OSes allow 32 bits for both minor and major
81    #[cfg(any(
82        target_os = "empscripten",
83        target_os = "freebsd",
84        target_os = "fuchsia",
85        target_os = "linux",
86    ))]
87    #[test]
88    fn test_fbsd12_like() {
89        if std::mem::size_of::<dev_t>() >= 8 {
90            for major_exp in [0, 16, 24, 31] {
91                for major in [(1 << major_exp) - 1, (1 << major_exp)] {
92                    for minor_exp in [1, 8, 16, 24, 31] {
93                        for minor in [(1 << minor_exp) - 1, (1 << minor_exp)] {
94                            compare(major, minor);
95                        }
96                    }
97                    compare(major, c_uint::MAX);
98                }
99                compare(c_uint::MAX, c_uint::MAX);
100            }
101        }
102    }
103}
104