• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 17385983897

01 Sep 2025 07:41PM UTC coverage: 18.009% (-0.1%) from 18.149%
17385983897

Pull #281

github

web-flow
Merge 782c57b11 into 6ec9a6d6b
Pull Request #281: Port to Apple Hypervisor framework

0 of 154 new or added lines in 11 files covered. (0.0%)

1166 existing lines in 29 files now uncovered.

1362 of 7563 relevant lines covered (18.01%)

18.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/alioth/src/utils/ioctls.rs
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
use std::mem::size_of;
16

17
const IOC_NONN: u32 = 0;
18
const IOC_WRITE: u32 = 1;
19
const IOC_READ: u32 = 2;
20

21
const IOC_NRSHIFT: usize = 0;
22
const IOC_TYPESHIFT: usize = 8;
23
const IOC_SIZESHIFT: usize = 16;
24
const IOC_DIRSHIFT: usize = 30;
25

26
const fn ioctl_ioc(dir: u32, type_: u8, nr: u8, size: u32) -> u32 {
5✔
27
    (dir << IOC_DIRSHIFT)
8✔
28
        | (size << IOC_SIZESHIFT)
5✔
29
        | ((type_ as u32) << IOC_TYPESHIFT)
5✔
30
        | ((nr as u32) << IOC_NRSHIFT)
5✔
31
}
32

33
pub const fn ioctl_io(type_: u8, nr: u8) -> u32 {
2✔
34
    ioctl_ioc(IOC_NONN, type_, nr, 0)
4✔
35
}
36

37
pub const fn ioctl_ior<T>(type_: u8, nr: u8) -> u32 {
2✔
38
    ioctl_ioc(IOC_READ, type_, nr, size_of::<T>() as u32)
5✔
39
}
40

41
pub const fn ioctl_iow<T>(type_: u8, nr: u8) -> u32 {
2✔
42
    ioctl_ioc(IOC_WRITE, type_, nr, size_of::<T>() as u32)
5✔
43
}
44

45
pub const fn ioctl_iowr<T>(type_: u8, nr: u8) -> u32 {
2✔
46
    ioctl_ioc(IOC_WRITE | IOC_READ, type_, nr, size_of::<T>() as u32)
6✔
47
}
48

49
#[macro_export]
50
macro_rules! ioctl_none {
51
    ($name:ident, $type_:expr, $nr:expr, $val:expr) => {
52
        #[allow(clippy::missing_safety_doc)]
UNCOV
53
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<libc::c_int> {
UNCOV
54
            let op = $crate::utils::ioctls::ioctl_io($type_, $nr);
UNCOV
55
            let v = $val as ::libc::c_ulong;
UNCOV
56
            $crate::ffi!(unsafe {
UNCOV
57
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, v)
58
            })
59
        }
60
    };
61
    ($name:ident, $type_:expr, $nr:expr) => {
62
        $crate::ioctl_none!($name, $type_, $nr, 0);
63
    };
64
}
65

66
#[macro_export]
67
macro_rules! ioctl_write_val {
68
    ($name:ident, $code:expr) => {
69
        #[allow(clippy::missing_safety_doc)]
UNCOV
70
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
UNCOV
71
            fd: &F,
UNCOV
72
            val: ::libc::c_ulong,
UNCOV
73
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
74
            let op = $code;
UNCOV
75
            $crate::ffi!(unsafe {
UNCOV
76
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, val)
77
            })
78
        }
79
    };
80
    ($name:ident, $code:expr, $ty:ty) => {
81
        #[allow(clippy::missing_safety_doc)]
UNCOV
82
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
UNCOV
83
            fd: &F,
UNCOV
84
            val: $ty,
UNCOV
85
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
86
            let op = $code;
UNCOV
87
            $crate::ffi!(unsafe {
UNCOV
88
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, val)
89
            })
90
        }
91
    };
92
}
93

94
#[macro_export]
95
macro_rules! ioctl_write_ptr {
96
    ($name:ident, $code:expr, $ty:ty) => {
97
        #[allow(clippy::missing_safety_doc)]
UNCOV
98
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
UNCOV
99
            fd: &F,
UNCOV
100
            val: &$ty,
UNCOV
101
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
102
            let op = $code;
UNCOV
103
            $crate::ffi!(unsafe {
UNCOV
104
                ::libc::ioctl(
UNCOV
105
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
UNCOV
106
                    op as _,
UNCOV
107
                    val as *const $ty,
108
                )
109
            })
110
        }
111
    };
112

113
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
114
        #[allow(clippy::missing_safety_doc)]
UNCOV
115
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
UNCOV
116
            fd: &F,
UNCOV
117
            val: &$ty,
UNCOV
118
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
119
            let op = $crate::utils::ioctls::ioctl_iow::<$ty>($type_, $nr);
UNCOV
120
            $crate::ffi!(unsafe {
UNCOV
121
                ::libc::ioctl(
UNCOV
122
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
UNCOV
123
                    op as _,
UNCOV
124
                    val as *const $ty,
125
                )
126
            })
127
        }
128
    };
129
}
130

131
#[macro_export]
132
macro_rules! ioctl_write_buf {
133
    ($name:ident, $code:expr, $ty:ident) => {
134
        #[allow(clippy::missing_safety_doc)]
UNCOV
135
        pub unsafe fn $name<F: ::std::os::fd::AsFd, const N: usize>(
UNCOV
136
            fd: &F,
UNCOV
137
            val: &$ty<N>,
UNCOV
138
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
139
            let op = $code;
UNCOV
140
            $crate::ffi!(unsafe {
UNCOV
141
                ::libc::ioctl(
UNCOV
142
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
UNCOV
143
                    op as _,
UNCOV
144
                    val as *const $ty<N>,
145
                )
146
            })
147
        }
148
    };
149
    ($name:ident, $type_:expr, $nr:expr, $ty:ident) => {
150
        $crate::ioctl_write_buf!(
151
            $name,
152
            $crate::utils::ioctls::ioctl_iow::<$ty<0>>($type_, $nr),
153
            $ty
154
        );
155
    };
156
}
157

158
#[macro_export]
159
macro_rules! ioctl_writeread {
160
    ($name:ident, $code:expr, $ty:ty) => {
161
        #[allow(clippy::missing_safety_doc)]
UNCOV
162
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
UNCOV
163
            fd: &F,
UNCOV
164
            val: &mut $ty,
UNCOV
165
        ) -> ::std::io::Result<libc::c_int> {
UNCOV
166
            let op = $code;
UNCOV
167
            $crate::ffi!(unsafe {
UNCOV
168
                ::libc::ioctl(
UNCOV
169
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
UNCOV
170
                    op as _,
UNCOV
171
                    val as *mut $ty,
172
                )
173
            })
174
        }
175
    };
176
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
177
        $crate::ioctl_writeread!(
178
            $name,
179
            $crate::utils::ioctls::ioctl_iowr::<$ty>($type_, $nr),
180
            $ty
181
        );
182
    };
183
    ($name:ident, $code:expr) => {
184
        #[allow(clippy::missing_safety_doc)]
185
        pub unsafe fn $name<F: ::std::os::fd::AsFd, T>(
186
            fd: &F,
187
            val: &mut T,
188
        ) -> ::std::io::Result<libc::c_int> {
189
            let op = $code;
190
            $crate::ffi!(unsafe {
191
                ::libc::ioctl(
192
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
193
                    op as _,
194
                    val as *mut T,
195
                )
196
            })
197
        }
198
    };
199
}
200

201
#[macro_export]
202
macro_rules! ioctl_writeread_buf {
203
    ($name:ident, $type_:expr, $nr:expr, $ty:ident) => {
204
        #[allow(clippy::missing_safety_doc)]
205
        pub unsafe fn $name<F: ::std::os::fd::AsFd, const N: usize>(
206
            fd: &F,
207
            val: &mut $ty<N>,
208
        ) -> ::std::io::Result<libc::c_int> {
209
            let op = $crate::utils::ioctls::ioctl_iowr::<$ty<0>>($type_, $nr);
210
            $crate::ffi!(unsafe {
211
                ::libc::ioctl(
212
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
213
                    op as _,
214
                    val as *mut $ty<N>,
215
                )
216
            })
217
        }
218
    };
219
}
220

221
#[macro_export]
222
macro_rules! ioctl_read {
223
    ($name:ident, $code:expr, $ty:ty) => {
224
        #[allow(clippy::missing_safety_doc)]
225
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<$ty> {
226
            let mut val = ::core::mem::MaybeUninit::<$ty>::uninit();
227
            $crate::ffi!(::libc::ioctl(
228
                ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
229
                $code as _,
230
                val.as_mut_ptr()
231
            ))?;
232
            ::std::io::Result::Ok(val.assume_init())
233
        }
234
    };
235
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
236
        #[allow(clippy::missing_safety_doc)]
UNCOV
237
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<$ty> {
UNCOV
238
            let mut val = ::core::mem::MaybeUninit::<$ty>::uninit();
UNCOV
239
            let op = $crate::utils::ioctls::ioctl_ior::<$ty>($type_, $nr);
UNCOV
240
            $crate::ffi!(unsafe {
UNCOV
241
                ::libc::ioctl(
UNCOV
242
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
UNCOV
243
                    op as _,
UNCOV
244
                    val.as_mut_ptr(),
245
                )
246
            })?;
UNCOV
247
            ::std::io::Result::Ok(unsafe { val.assume_init() })
248
        }
249
    };
250
}
251

252
#[cfg(test)]
253
mod test {
254
    use crate::utils::ioctls::{ioctl_io, ioctl_ior, ioctl_iow, ioctl_iowr};
255

256
    #[test]
257
    fn test_codes() {
258
        const KVMIO: u8 = 0xAE;
259
        assert_eq!(ioctl_io(KVMIO, 0x01), 0xae01);
260
        assert_eq!(ioctl_ior::<[u8; 320]>(KVMIO, 0xcc), 0x8140aecc);
261
        assert_eq!(ioctl_iow::<[u8; 320]>(KVMIO, 0xcd), 0x4140aecd);
262
        assert_eq!(ioctl_iowr::<[u8; 8]>(KVMIO, 0x05), 0xc008ae05);
263
    }
264
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc