| use libc::{c_int, c_long, syscall, SYS_userfaultfd, INT_MAX}; |
| pub use userfaultfd_sys::*; |
| |
| pub unsafe fn userfaultfd(flags: c_int) -> c_int { |
| let fd = syscall(SYS_userfaultfd, flags as c_long); |
| if fd > INT_MAX as c_long { |
| panic!("fd doesn't fit in a c_int"); |
| } else { |
| fd as c_int |
| } |
| } |
| |
| nix::ioctl_readwrite!(api, UFFDIO, _UFFDIO_API, uffdio_api); |
| nix::ioctl_readwrite!(register, UFFDIO, _UFFDIO_REGISTER, uffdio_register); |
| nix::ioctl_read!(unregister, UFFDIO, _UFFDIO_UNREGISTER, uffdio_range); |
| nix::ioctl_read!(wake, UFFDIO, _UFFDIO_WAKE, uffdio_range); |
| nix::ioctl_readwrite!(copy, UFFDIO, _UFFDIO_COPY, uffdio_copy); |
| nix::ioctl_readwrite!(zeropage, UFFDIO, _UFFDIO_ZEROPAGE, uffdio_zeropage); |
| #[cfg(feature = "linux5_7")] |
| nix::ioctl_readwrite!( |
| write_protect, |
| UFFDIO, |
| _UFFDIO_WRITEPROTECT, |
| uffdio_writeprotect |
| ); |
| |
| // ioctls for /dev/userfaultfd |
| |
| // This is the `/dev/userfaultfd` ioctl() from creating a new userfault file descriptor. |
| // It is a "bad" ioctl in the sense that it is defined as an _IOC: |
| // https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/userfaultfd.h#L17, |
| // aka `nix::ioctl_none`, however it does receive an integer argument: |
| // https://elixir.bootlin.com/linux/latest/source/fs/userfaultfd.c#L2186. That is the same argument |
| // that the userfaultfd() system call receives. |
| nix::ioctl_write_int_bad!( |
| /// Create a new userfault file descriptor from the `/dev/userfaultfd` |
| /// device. This receives the same arguments as the userfaultfd system call. |
| new_uffd, |
| nix::request_code_none!(USERFAULTFD_IOC, 0x00) |
| ); |