1//! Process execution domains 2use crate::errno::Errno; 3use crate::Result; 4 5use libc::{self, c_int, c_ulong}; 6 7libc_bitflags! { 8 /// Flags used and returned by [`get()`](fn.get.html) and 9 /// [`set()`](fn.set.html). 10 pub struct Persona: c_int { 11 /// Provide the legacy virtual address space layout. 12 ADDR_COMPAT_LAYOUT; 13 /// Disable address-space-layout randomization. 14 ADDR_NO_RANDOMIZE; 15 /// Limit the address space to 32 bits. 16 ADDR_LIMIT_32BIT; 17 /// Use `0xc0000000` as the offset at which to search a virtual memory 18 /// chunk on [`mmap(2)`], otherwise use `0xffffe000`. 19 /// 20 /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html 21 ADDR_LIMIT_3GB; 22 /// User-space function pointers to signal handlers point to descriptors. 23 #[cfg(not(any(target_env = "musl", target_env = "ohos", target_env = "uclibc")))] 24 #[cfg_attr(docsrs, doc(cfg(all())))] 25 FDPIC_FUNCPTRS; 26 /// Map page 0 as read-only. 27 MMAP_PAGE_ZERO; 28 /// `PROT_READ` implies `PROT_EXEC` for [`mmap(2)`]. 29 /// 30 /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html 31 READ_IMPLIES_EXEC; 32 /// No effects. 33 SHORT_INODE; 34 /// [`select(2)`], [`pselect(2)`], and [`ppoll(2)`] do not modify the 35 /// returned timeout argument when interrupted by a signal handler. 36 /// 37 /// [`select(2)`]: https://man7.org/linux/man-pages/man2/select.2.html 38 /// [`pselect(2)`]: https://man7.org/linux/man-pages/man2/pselect.2.html 39 /// [`ppoll(2)`]: https://man7.org/linux/man-pages/man2/ppoll.2.html 40 STICKY_TIMEOUTS; 41 /// Have [`uname(2)`] report a 2.6.40+ version number rather than a 3.x 42 /// version number. 43 /// 44 /// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html 45 #[cfg(not(any(target_env = "musl", target_env = "ohos", target_env = "uclibc")))] 46 #[cfg_attr(docsrs, doc(cfg(all())))] 47 UNAME26; 48 /// No effects. 49 WHOLE_SECONDS; 50 } 51} 52 53/// Retrieve the current process personality. 54/// 55/// Returns a Result containing a Persona instance. 56/// 57/// Example: 58/// 59/// ``` 60/// # use nix::sys::personality::{self, Persona}; 61/// let pers = personality::get().unwrap(); 62/// assert!(!pers.contains(Persona::WHOLE_SECONDS)); 63/// ``` 64pub fn get() -> Result<Persona> { 65 let res = unsafe { libc::personality(0xFFFFFFFF) }; 66 67 Errno::result(res).map(Persona::from_bits_truncate) 68} 69 70/// Set the current process personality. 71/// 72/// Returns a Result containing the *previous* personality for the 73/// process, as a Persona. 74/// 75/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html) 76/// 77/// **NOTE**: This call **replaces** the current personality entirely. 78/// To **update** the personality, first call `get()` and then `set()` 79/// with the modified persona. 80/// 81/// Example: 82/// 83/// ``` 84/// # use nix::sys::personality::{self, Persona}; 85/// let mut pers = personality::get().unwrap(); 86/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE)); 87/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap(); 88/// ``` 89pub fn set(persona: Persona) -> Result<Persona> { 90 let res = unsafe { libc::personality(persona.bits() as c_ulong) }; 91 92 Errno::result(res).map(Persona::from_bits_truncate) 93} 94