Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements sysctl.name2oid #389

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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