1 use libc::{c_int, c_long, syscall, SYS_userfaultfd, INT_MAX};
2 pub use userfaultfd_sys::*;
3
userfaultfd(flags: c_int) -> c_int4 pub unsafe fn userfaultfd(flags: c_int) -> c_int {
5 let fd = syscall(SYS_userfaultfd, flags as c_long);
6 if fd > INT_MAX as c_long {
7 panic!("fd doesn't fit in a c_int");
8 } else {
9 fd as c_int
10 }
11 }
12
13 nix::ioctl_readwrite!(api, UFFDIO, _UFFDIO_API, uffdio_api);
14 nix::ioctl_readwrite!(register, UFFDIO, _UFFDIO_REGISTER, uffdio_register);
15 nix::ioctl_read!(unregister, UFFDIO, _UFFDIO_UNREGISTER, uffdio_range);
16 nix::ioctl_read!(wake, UFFDIO, _UFFDIO_WAKE, uffdio_range);
17 nix::ioctl_readwrite!(copy, UFFDIO, _UFFDIO_COPY, uffdio_copy);
18 nix::ioctl_readwrite!(zeropage, UFFDIO, _UFFDIO_ZEROPAGE, uffdio_zeropage);
19 #[cfg(feature = "linux5_7")]
20 nix::ioctl_readwrite!(
21 write_protect,
22 UFFDIO,
23 _UFFDIO_WRITEPROTECT,
24 uffdio_writeprotect
25 );
26
27 // ioctls for /dev/userfaultfd
28
29 // This is the `/dev/userfaultfd` ioctl() from creating a new userfault file descriptor.
30 // It is a "bad" ioctl in the sense that it is defined as an _IOC:
31 // https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/userfaultfd.h#L17,
32 // aka `nix::ioctl_none`, however it does receive an integer argument:
33 // https://elixir.bootlin.com/linux/latest/source/fs/userfaultfd.c#L2186. That is the same argument
34 // that the userfaultfd() system call receives.
35 nix::ioctl_write_int_bad!(
36 /// Create a new userfault file descriptor from the `/dev/userfaultfd`
37 /// device. This receives the same arguments as the userfaultfd system call.
38 new_uffd,
39 nix::request_code_none!(USERFAULTFD_IOC, 0x00)
40 );
41