bitflags!
{
#[derive(Deserialize, Serialize)]
pub struct PersonalityFlags: i32
{
const UNAME26 = 0x0020000;
const ADDR_NO_RANDOMIZE = 0x0040000;
const FDPIC_FUNCPTRS = 0x0080000;
const MMAP_PAGE_ZERO = 0x0100000;
const ADDR_COMPAT_LAYOUT = 0x0200000;
const READ_IMPLIES_EXEC = 0x0400000;
const ADDR_LIMIT_32BIT = 0x0800000;
const SHORT_INODE = 0x1000000;
const WHOLE_SECONDS = 0x2000000;
const STICKY_TIMEOUTS = 0x4000000;
const ADDR_LIMIT_3GB = 0x8000000;
const PER_LINUX = 0x0000;
const PER_LINUX_32BIT = PersonalityFlags::PER_LINUX.bits | PersonalityFlags::ADDR_LIMIT_32BIT.bits;
const PER_LINUX_FDPIC = PersonalityFlags::PER_LINUX.bits | PersonalityFlags::FDPIC_FUNCPTRS.bits;
const PER_SVR4 = 0x0001 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::MMAP_PAGE_ZERO.bits;
const PER_SVR3 = 0x0002 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::SHORT_INODE.bits;
const PER_SCOSVR3 = 0x0003 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::WHOLE_SECONDS.bits | PersonalityFlags::SHORT_INODE.bits;
const PER_OSR5 = 0x0003 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::WHOLE_SECONDS.bits;
const PER_WYSEV386 = 0x0004 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::SHORT_INODE.bits;
const PER_ISCR4 = 0x0005 | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_BSD = 0x0006;
const PER_SUNOS = PersonalityFlags::PER_BSD.bits | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_XENIX = 0x0007 | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::SHORT_INODE.bits;
const PER_LINUX32 = 0x0008;
const PER_LINUX32_3GB = PersonalityFlags::PER_LINUX32.bits | PersonalityFlags::ADDR_LIMIT_3GB.bits;
const PER_IRIX32 = 0x0009 | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_IRIXN32 = 0x000A | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_IRIX64 = 0x000B | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_RISCOS = 0x000C;
const PER_SOLARIS = 0x000D | PersonalityFlags::STICKY_TIMEOUTS.bits;
const PER_UW7 = 0x000E | PersonalityFlags::STICKY_TIMEOUTS.bits | PersonalityFlags::MMAP_PAGE_ZERO.bits;
const PER_OSF4 = 0x000F;
const PER_HPUX = 0x0010;
const PER_MASK = 0x00FF;
}
}
impl FromBytes for PersonalityFlags
{
type Error = ParseNumberError;
#[inline(always)]
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>
{
Ok(Self::from_bits(i32::parse_hexadecimal_number_lower_case(bytes)?).expect("Invalid bits in previous personality flags"))
}
}
impl PersonalityFlags
{
#[inline(always)]
pub fn validate_only_one_execution_domain(proc_path: &ProcPath)
{
let file_path = proc_path.file_path("execdomains");
if file_path.exists()
{
let value = file_path.read_raw_without_line_feed().unwrap();
assert_eq!(&value[..], b"0-0\tLinux \t[kernel]" as &[u8], "Linux supported multiple execution domains");
}
}
#[inline(always)]
pub fn is_standard_linux(self) -> bool
{
self == PersonalityFlags::PER_LINUX
}
#[inline(always)]
pub fn current() -> Result<Self, ()>
{
const SpecialFlagPattern: c_ulong = 0xFFFF_FFFF;
Self::personality(SpecialFlagPattern)
}
#[inline(always)]
pub fn for_process(proc_path: &ProcPath, process_identifier: ProcessIdentifierChoice) -> io::Result<Self>
{
proc_path.process_file_path(process_identifier, "personality").read_value()
}
#[inline(always)]
pub fn set_process_domain_execution_model(self) -> Result<Self, ()>
{
Self::personality(self.bits() as c_ulong)
}
#[inline(always)]
fn personality(bits: c_ulong) -> Result<Self, ()>
{
let result = unsafe { personality(bits) };
if likely!(result != -1)
{
return Ok(Self::from_bits(result).expect("Invalid bits in previous personality flags"))
}
match errno().0
{
EINVAL => Err(()),
unexpected @ _ => panic!("Unexpected error number from 'personality' of '{:?}'", unexpected),
}
}
}