use crate::common::output;
use crate::common::report::{report_error, report_simple_failure};
use yash_env::Env;
use yash_env::System as _;
use yash_env::semantics::Field;
use yash_env::system::Errno;
use yash_env::system::resource::{Limit, Resource};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ShowLimitType {
Soft,
Hard,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SetLimitType {
Soft,
Hard,
Both,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SetLimitValue {
Number(Limit),
Unlimited,
CurrentSoft,
CurrentHard,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Command {
ShowAll(ShowLimitType),
ShowOne(Resource, ShowLimitType),
Set(Resource, SetLimitType, SetLimitValue),
}
mod resource;
pub use resource::ResourceExt;
pub mod set;
pub mod show;
pub mod syntax;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("specified resource not supported on this platform")]
UnsupportedResource,
#[error("soft limit exceeds hard limit")]
SoftLimitExceedsHardLimit,
#[error("no permission to raise hard limit")]
NoPermissionToRaiseHardLimit,
#[error("limit out of range")]
Overflow,
#[error("unexpected error: {}", .0)]
Unknown(Errno),
}
impl Command {
pub async fn execute(&self, env: &mut Env) -> Result<String, Error> {
let getrlimit = |resource| env.system.getrlimit(resource);
match self {
Command::ShowAll(limit_type) => Ok(show::show_all(getrlimit, *limit_type)),
Command::ShowOne(resource, limit_type) => {
show::show_one(getrlimit, *resource, *limit_type)
}
Command::Set(resource, limit_type, limit) => {
set::set(&mut env.system, *resource, *limit_type, *limit)?;
Ok(String::new())
}
}
}
}
pub async fn main(env: &mut Env, args: Vec<Field>) -> crate::Result {
match syntax::parse(env, args) {
Ok(command) => match command.execute(env).await {
Ok(result) => output(env, &result).await,
Err(e) => report_simple_failure(env, &e.to_string()).await,
},
Err(e) => report_error(env, &e).await,
}
}