Skip to content

Commit

Permalink
Implements sysctl.name2oid (#389)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Oct 8, 2023
1 parent f65b343 commit ad4fd92
Show file tree
Hide file tree
Showing 4 changed files with 477 additions and 142 deletions.
8 changes: 4 additions & 4 deletions src/kernel/src/errno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ pub fn strerror(num: NonZeroI32) -> &'static str {
EPROTO => "protocol error",
ENOTCAPABLE => "capabilities insufficient",
ECAPMODE => "not permitted in capability mode",
ENOBLK => "Block not ready",
EICV => "Integrity Check Error",
ENOPLAYGOENT => "File not found in PlayGo chunk definition file",
EREVOKE => "File is revoked",
ENOBLK => "block not ready",
EICV => "integrity check error",
ENOPLAYGOENT => "file not found in PlayGo chunk definition file",
EREVOKE => "file is revoked",
ESDKVERSION => "SDK version of a binary file is invalid",
v => todo!("strerror {v}"),
}
Expand Down
30 changes: 2 additions & 28 deletions src/kernel/src/process/appinfo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
use crate::errno::{Errno, EINVAL};
use thiserror::Error;

/// An implementation of `appinfo` structure on the PS4.
#[derive(Debug)]
pub struct AppInfo {
Expand All @@ -20,32 +17,9 @@ impl AppInfo {
self.unk1
}

pub fn read(&self, buf: &mut [u8]) -> Result<(), AppInfoReadError> {
if buf.len() >= 73 {
return Err(AppInfoReadError::UnknownBuffer);
} else if buf.len() != 72 {
todo!("appinfo with size != 72");
}

pub fn serialize(&self) -> [u8; 72] {
// TODO: Right now we don't know how appinfo is structured but it seems like it is safe to
// fill it with zeroes.
buf.fill(0);

Ok(())
}
}

/// Represents an error when [`AppInfo::read()`] is failed.
#[derive(Debug, Error)]
pub enum AppInfoReadError {
#[error("size of the buffer is not recognized")]
UnknownBuffer,
}

impl Errno for AppInfoReadError {
fn errno(&self) -> std::num::NonZeroI32 {
match self {
Self::UnknownBuffer => EINVAL,
}
[0; 72]
}
}
60 changes: 40 additions & 20 deletions src/kernel/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub use input::*;
pub use output::*;
pub use self::error::*;
pub use self::input::*;
pub use self::output::*;

use self::error::Error;
use crate::errno::{
EBADF, EFAULT, EINVAL, ENAMETOOLONG, ENOENT, ENOMEM, ENOSYS, ENOTTY, EPERM, ESRCH,
};
Expand All @@ -12,7 +12,7 @@ use crate::process::{NamedObj, ProcObj, VProc, VProcGroup, VSession, VThread};
use crate::regmgr::{RegError, RegMgr};
use crate::rtld::{ModuleFlags, RuntimeLinker};
use crate::signal::{SignalSet, SIGKILL, SIGSTOP, SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK};
use crate::sysctl::Sysctl;
use crate::sysctl::{Sysctl, SysctlReq};
use crate::ucred::{AuthInfo, Privilege};
use crate::{info, warn};
use macros::cpu_abi;
Expand Down Expand Up @@ -343,36 +343,56 @@ impl Syscalls {
newlen: usize,
) -> Result<Output, Error> {
// Convert name to a slice.
let name = std::slice::from_raw_parts(name, namelen.try_into().unwrap());
let name = if namelen < 2 || namelen > 24 {
return Err(Error::Raw(EINVAL));
} else if name.is_null() {
return Err(Error::Raw(EFAULT));
} else {
std::slice::from_raw_parts(name, namelen as _)
};

if name[0] == Sysctl::CTL_DEBUG && !self.vp.cred().is_system() {
return Err(Error::Raw(EINVAL));
}

if name[0] == Sysctl::CTL_VM && name[1] == Sysctl::VM_TOTAL {
todo!("sysctl CTL_VM:VM_TOTAL")
}

// Setup a request.
let mut req = SysctlReq::default();

// Convert old to a slice.
let old = if oldlenp.is_null() {
if !oldlenp.is_null() {
req.validlen = *oldlenp;
}

req.old = if old.is_null() {
None
} else if old.is_null() {
todo!("oldlenp is non-null but old is null")
} else if oldlenp.is_null() {
Some(std::slice::from_raw_parts_mut(old, 0))
} else {
Some(std::slice::from_raw_parts_mut(old, *oldlenp))
};

// Convert new to a slice.
let new = if newlen == 0 {
req.new = if new.is_null() {
None
} else if new.is_null() {
todo!("newlen is non-zero but new is null")
} else {
Some(std::slice::from_raw_parts(new, newlen))
};

// Execute.
let written = self.sysctl.invoke(name, old, new)?;

if !oldlenp.is_null() {
assert!(written <= *oldlenp);
*oldlenp = written;
if let Err(e) = self.sysctl.exec(name, &mut req) {
if e.errno() != ENOMEM {
return Err(e);
}
}

if let Some(new) = new {
info!("Setting sysctl {:?} to {:?}.", name, new);
if !oldlenp.is_null() {
*oldlenp = if req.old.is_none() || req.oldidx <= req.validlen {
req.oldidx
} else {
req.validlen
};
}

Ok(Output::ZERO)
Expand Down
Loading

0 comments on commit ad4fd92

Please sign in to comment.