#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
#[repr(i32)]
pub enum Nice
{
Positive_19 = 19,
Positive_18 = 18,
Positive_17 = 17,
Positive_16 = 16,
Positive_15 = 15,
Positive_14 = 14,
Positive_13 = 13,
Positive_12 = 12,
Positive_11 = 11,
Positive_10 = 10,
Positive_9 = 9,
Positive_8 = 8,
Positive_7 = 7,
Positive_6 = 6,
Positive_5 = 5,
Positive_4 = 4,
Positive_3 = 3,
Positive_2 = 2,
Positive_1 = 1,
Zero = 0,
Negative_1 = -1,
Negative_2 = -2,
Negative_3 = -3,
Negative_4 = -4,
Negative_5 = -5,
Negative_6 = -6,
Negative_7 = -7,
Negative_8 = -8,
Negative_9 = -9,
Negative_10 = -10,
Negative_11 = -11,
Negative_12 = -12,
Negative_13 = -13,
Negative_14 = -14,
Negative_15 = -15,
Negative_16 = -16,
Negative_17 = -17,
Negative_18 = -18,
Negative_19 = -19,
Negative_20 = -20,
}
impl Display for Nice
{
#[inline(always)]
fn fmt(&self, f: &mut Formatter) -> fmt::Result
{
write!(f, "{}", *self as i32)
}
}
impl Default for Nice
{
#[inline(always)]
fn default() -> Self
{
Nice::Default
}
}
impl Into<i8> for Nice
{
#[inline(always)]
fn into(self) -> i8
{
self as i32 as i8
}
}
impl Into<i16> for Nice
{
#[inline(always)]
fn into(self) -> i16
{
self as i32 as i16
}
}
impl Into<i32> for Nice
{
#[inline(always)]
fn into(self) -> i32
{
self as i32
}
}
impl Into<i64> for Nice
{
#[inline(always)]
fn into(self) -> i64
{
self as i32 as i64
}
}
impl Into<isize> for Nice
{
#[inline(always)]
fn into(self) -> isize
{
self as i32 as isize
}
}
impl ParseNumber for Nice
{
#[inline(always)]
fn parse_number(bytes: &[u8], radix: Radix, parse_byte: impl Fn(Radix, u8) -> Result<u8, ParseNumberError>) -> Result<Self, ParseNumberError>
{
use self::ParseNumberError::*;
let value = i32::parse_number(bytes, radix, parse_byte)?;
if unlikely!(value < Self::InclusiveMinimum)
{
Err(TooSmall)
}
else if unlikely!(value > Self::InclusiveMaximum)
{
Err(TooLarge)
}
else
{
Ok(unsafe { transmute(value) })
}
}
}
impl<'a> IntoLineFeedTerminatedByteString<'a> for Nice
{
#[inline(always)]
fn into_line_feed_terminated_byte_string(self) -> Cow<'a, [u8]>
{
UnpaddedDecimalInteger(self as i32).into_line_feed_terminated_byte_string()
}
}
impl Nice
{
pub const Default: Self = Nice::Negative_20;
pub(super) const InclusiveMinimum: i32 = -20;
pub(super) const InclusiveMaximum: i32 = 19;
#[inline(always)]
pub fn set_autogroup_for_current_process(self, proc_path: &ProcPath) -> Result<(), io::Error>
{
self.set_autogroup_for_process(ProcessIdentifierChoice::Current, proc_path)
}
#[inline(always)]
pub fn set_autogroup_for_process(self, process_identifier: ProcessIdentifierChoice, proc_path: &ProcPath) -> Result<(), io::Error>
{
proc_path.process_file_path(process_identifier, "autogroup").write_value(UnpaddedDecimalInteger(self as i32))
}
#[inline(always)]
pub fn get_autogroup_name_and_nice_value(process_identifier: ProcessIdentifierChoice, proc_path: &ProcPath) -> io::Result<(Box<[u8]>, Self)>
{
let line = proc_path.process_file_path(process_identifier, "autogroup").read_raw_without_line_feed()?;
let mut parts = line.split_bytes_n(3, b' ');
let name = parts.next().unwrap();
let nice_string = parts.next().ok_or(io_error_other("Missing `nice` string"))?;
if nice_string != b"nice"
{
return Err(io_error_other("`nice` string was not 'nice'"))
}
let raw_nice_value = parts.next().ok_or(io_error_other("Missing `nice` value"))?;
let nice = Self::parse_decimal_number(raw_nice_value).map_err(io_error_other)?;
Ok((name.to_vec().into_boxed_slice(), nice))
}
#[inline(always)]
pub fn set_process_group_priority(self, process_group_identifier: ProcessGroupIdentifierChoice) -> Result<(), ()>
{
let pgid: pid_t = process_group_identifier.into();
self.set_priority(PRIO_PGRP, pgid as u32)
}
#[inline(always)]
pub fn set_process_priority(self, process_identifier: ProcessIdentifierChoice) -> Result<(), ()>
{
let pid: pid_t = process_identifier.into();
self.set_priority(PRIO_PROCESS, pid as u32)
}
#[inline(always)]
pub fn set_thread_priority(self, thread_identifier: ThreadIdentifier) -> Result<(), ()>
{
let tid: pid_t = thread_identifier.into();
self.set_priority(PRIO_PROCESS, tid as u32)
}
#[inline(always)]
pub fn set_real_user_priority(self, user_identifier: UserIdentifier) -> Result<(), ()>
{
let uid: uid_t = user_identifier.into();
self.set_priority(PRIO_USER, uid)
}
#[inline(always)]
fn set_priority(self, which: i32, who: u32) -> Result<(), ()>
{
let result = unsafe { setpriority(which, who, self as i32) };
if likely!(result == 0)
{
Ok(())
}
else if likely!(result == -1)
{
match errno().0
{
ESRCH => Err(()),
EACCES | EPERM => panic!("Permission denied"),
EINVAL => panic!("`which` was not one of `PRIO_PROCESS`, `PRIO_PGRP`, or `PRIO_USER`"),
unexpected @ _ => panic!("Unexpected error `{}` from `setpriority()`", unexpected),
}
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from `setpriority()`", result))
}
}
#[inline(always)]
pub fn get_process_group_priority(process_group_identifier: ProcessGroupIdentifierChoice) -> Result<Self, ()>
{
let pgid: pid_t = process_group_identifier.into();
Self::get_priority(PRIO_PGRP, pgid as u32)
}
#[inline(always)]
pub fn get_process_priority(process_identifier: ProcessIdentifierChoice) -> Result<Self, ()>
{
let pid: pid_t = process_identifier.into();
Self::get_priority(PRIO_PROCESS, pid as u32)
}
#[inline(always)]
pub fn get_thread_priority(thread_identifier: ThreadIdentifier) -> Result<Self, ()>
{
let tid: pid_t = thread_identifier.into();
Self::get_priority(PRIO_PROCESS, tid as u32)
}
#[inline(always)]
pub fn get_real_user_priority(user_identifier: UserIdentifier) -> Result<Self, ()>
{
let uid: uid_t = user_identifier.into();
Self::get_priority(PRIO_USER, uid)
}
#[inline(always)]
fn get_priority(which: i32, who: u32) -> Result<Self, ()>
{
set_errno(Errno(0));
let result = unsafe { getpriority(which, who) };
match errno().0
{
0 => match result
{
-20 ..= 19 => Ok(unsafe { transmute(result) }),
invalid @ _ => panic!("Invalid priority value `{}`", invalid),
}
EINVAL => panic!("`which` was not one of `PRIO_PROCESS`, `PRIO_PGRP`, or `PRIO_USER`"),
ESRCH => Err(()),
_ => unreachable_code(format_args!("")),
}
}
}