13da5c369Sopenharmony_ci//! Process execution domains
23da5c369Sopenharmony_ciuse crate::errno::Errno;
33da5c369Sopenharmony_ciuse crate::Result;
43da5c369Sopenharmony_ci
53da5c369Sopenharmony_ciuse libc::{self, c_int, c_ulong};
63da5c369Sopenharmony_ci
73da5c369Sopenharmony_cilibc_bitflags! {
83da5c369Sopenharmony_ci    /// Flags used and returned by [`get()`](fn.get.html) and
93da5c369Sopenharmony_ci    /// [`set()`](fn.set.html).
103da5c369Sopenharmony_ci    pub struct Persona: c_int {
113da5c369Sopenharmony_ci        /// Provide the legacy virtual address space layout.
123da5c369Sopenharmony_ci        ADDR_COMPAT_LAYOUT;
133da5c369Sopenharmony_ci        /// Disable address-space-layout randomization.
143da5c369Sopenharmony_ci        ADDR_NO_RANDOMIZE;
153da5c369Sopenharmony_ci        /// Limit the address space to 32 bits.
163da5c369Sopenharmony_ci        ADDR_LIMIT_32BIT;
173da5c369Sopenharmony_ci        /// Use `0xc0000000` as the offset at which to search a virtual memory
183da5c369Sopenharmony_ci        /// chunk on [`mmap(2)`], otherwise use `0xffffe000`.
193da5c369Sopenharmony_ci        ///
203da5c369Sopenharmony_ci        /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
213da5c369Sopenharmony_ci        ADDR_LIMIT_3GB;
223da5c369Sopenharmony_ci        /// User-space function pointers to signal handlers point to descriptors.
233da5c369Sopenharmony_ci        #[cfg(not(any(target_env = "musl", target_env = "ohos", target_env = "uclibc")))]
243da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
253da5c369Sopenharmony_ci        FDPIC_FUNCPTRS;
263da5c369Sopenharmony_ci        /// Map page 0 as read-only.
273da5c369Sopenharmony_ci        MMAP_PAGE_ZERO;
283da5c369Sopenharmony_ci        /// `PROT_READ` implies `PROT_EXEC` for [`mmap(2)`].
293da5c369Sopenharmony_ci        ///
303da5c369Sopenharmony_ci        /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
313da5c369Sopenharmony_ci        READ_IMPLIES_EXEC;
323da5c369Sopenharmony_ci        /// No effects.
333da5c369Sopenharmony_ci        SHORT_INODE;
343da5c369Sopenharmony_ci        /// [`select(2)`], [`pselect(2)`], and [`ppoll(2)`] do not modify the
353da5c369Sopenharmony_ci        /// returned timeout argument when interrupted by a signal handler.
363da5c369Sopenharmony_ci        ///
373da5c369Sopenharmony_ci        /// [`select(2)`]: https://man7.org/linux/man-pages/man2/select.2.html
383da5c369Sopenharmony_ci        /// [`pselect(2)`]: https://man7.org/linux/man-pages/man2/pselect.2.html
393da5c369Sopenharmony_ci        /// [`ppoll(2)`]: https://man7.org/linux/man-pages/man2/ppoll.2.html
403da5c369Sopenharmony_ci        STICKY_TIMEOUTS;
413da5c369Sopenharmony_ci        /// Have [`uname(2)`] report a 2.6.40+ version number rather than a 3.x
423da5c369Sopenharmony_ci        /// version number.
433da5c369Sopenharmony_ci        ///
443da5c369Sopenharmony_ci        /// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html
453da5c369Sopenharmony_ci        #[cfg(not(any(target_env = "musl", target_env = "ohos", target_env = "uclibc")))]
463da5c369Sopenharmony_ci        #[cfg_attr(docsrs, doc(cfg(all())))]
473da5c369Sopenharmony_ci        UNAME26;
483da5c369Sopenharmony_ci        /// No effects.
493da5c369Sopenharmony_ci        WHOLE_SECONDS;
503da5c369Sopenharmony_ci    }
513da5c369Sopenharmony_ci}
523da5c369Sopenharmony_ci
533da5c369Sopenharmony_ci/// Retrieve the current process personality.
543da5c369Sopenharmony_ci///
553da5c369Sopenharmony_ci/// Returns a Result containing a Persona instance.
563da5c369Sopenharmony_ci///
573da5c369Sopenharmony_ci/// Example:
583da5c369Sopenharmony_ci///
593da5c369Sopenharmony_ci/// ```
603da5c369Sopenharmony_ci/// # use nix::sys::personality::{self, Persona};
613da5c369Sopenharmony_ci/// let pers = personality::get().unwrap();
623da5c369Sopenharmony_ci/// assert!(!pers.contains(Persona::WHOLE_SECONDS));
633da5c369Sopenharmony_ci/// ```
643da5c369Sopenharmony_cipub fn get() -> Result<Persona> {
653da5c369Sopenharmony_ci    let res = unsafe { libc::personality(0xFFFFFFFF) };
663da5c369Sopenharmony_ci
673da5c369Sopenharmony_ci    Errno::result(res).map(Persona::from_bits_truncate)
683da5c369Sopenharmony_ci}
693da5c369Sopenharmony_ci
703da5c369Sopenharmony_ci/// Set the current process personality.
713da5c369Sopenharmony_ci///
723da5c369Sopenharmony_ci/// Returns a Result containing the *previous* personality for the
733da5c369Sopenharmony_ci/// process, as a Persona.
743da5c369Sopenharmony_ci///
753da5c369Sopenharmony_ci/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html)
763da5c369Sopenharmony_ci///
773da5c369Sopenharmony_ci/// **NOTE**: This call **replaces** the current personality entirely.
783da5c369Sopenharmony_ci/// To **update** the personality, first call `get()` and then `set()`
793da5c369Sopenharmony_ci/// with the modified persona.
803da5c369Sopenharmony_ci///
813da5c369Sopenharmony_ci/// Example:
823da5c369Sopenharmony_ci///
833da5c369Sopenharmony_ci/// ```
843da5c369Sopenharmony_ci/// # use nix::sys::personality::{self, Persona};
853da5c369Sopenharmony_ci/// let mut pers = personality::get().unwrap();
863da5c369Sopenharmony_ci/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE));
873da5c369Sopenharmony_ci/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap();
883da5c369Sopenharmony_ci/// ```
893da5c369Sopenharmony_cipub fn set(persona: Persona) -> Result<Persona> {
903da5c369Sopenharmony_ci    let res = unsafe { libc::personality(persona.bits() as c_ulong) };
913da5c369Sopenharmony_ci
923da5c369Sopenharmony_ci    Errno::result(res).map(Persona::from_bits_truncate)
933da5c369Sopenharmony_ci}
94