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

Partially implements console ioctl with com = 0x20007461 #534

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fbfcde8
dev
SuchAFuriousDeath Dec 16, 2023
2f5ee21
dev
SuchAFuriousDeath Dec 23, 2023
b3e79f4
working
SuchAFuriousDeath Dec 23, 2023
6621774
ref
SuchAFuriousDeath Dec 23, 2023
c6c3767
simplify
SuchAFuriousDeath Dec 23, 2023
7bc2f24
todo comment
SuchAFuriousDeath Dec 23, 2023
f281667
ref
SuchAFuriousDeath Dec 24, 2023
68939f1
map_or
SuchAFuriousDeath Dec 26, 2023
0b03c3e
fix name
SuchAFuriousDeath Dec 26, 2023
61432e9
fixes
SuchAFuriousDeath Dec 29, 2023
3195b93
vnode fix
SuchAFuriousDeath Dec 29, 2023
acf7a0b
info
SuchAFuriousDeath Dec 29, 2023
e4a1031
fix str
SuchAFuriousDeath Dec 29, 2023
fda88be
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 29, 2023
68cabe0
find to any
SuchAFuriousDeath Dec 29, 2023
e30202b
fix any
SuchAFuriousDeath Dec 29, 2023
c1e6d56
rename ttyerr
SuchAFuriousDeath Dec 29, 2023
5b8d6de
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 29, 2023
49a0486
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 30, 2023
4d3f632
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 30, 2023
17f8f27
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 30, 2023
441637e
vnode comment
SuchAFuriousDeath Dec 30, 2023
197288f
remove redundant dev_exists check
SuchAFuriousDeath Dec 30, 2023
2090d19
revert refactor
SuchAFuriousDeath Dec 30, 2023
869f297
arc clone refactor
SuchAFuriousDeath Dec 30, 2023
3a56116
fix
SuchAFuriousDeath Dec 30, 2023
e0dc3d1
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 30, 2023
92bcb28
vproc refactor
SuchAFuriousDeath Dec 31, 2023
cceef61
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 31, 2023
5651627
fix error after merge
SuchAFuriousDeath Dec 31, 2023
36762f2
simplify allow dead code
SuchAFuriousDeath Dec 31, 2023
7aec6d1
comment and data into boxed slice
SuchAFuriousDeath Dec 31, 2023
4e1c45a
Merge branch 'main' into console-com-97
SuchAFuriousDeath Dec 31, 2023
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
2 changes: 2 additions & 0 deletions src/kernel/src/budget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ impl Budget {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProcType {
BigApp,
#[allow(dead_code)]
MiniApp,
#[allow(dead_code)]
System, // TODO: Verify this.
}
50 changes: 38 additions & 12 deletions src/kernel/src/fs/dev/console.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
use crate::errno::Errno;
use crate::errno::{Errno, ENXIO};
use crate::fs::{IoctlCom, VFile, VFileOps, VPath};
use crate::process::VThread;
use crate::process::{VProc, VThread};
use crate::tty::Tty;
use crate::ucred::Ucred;
use macros::vpath;
use std::fmt::{Display, Formatter};
use std::io::{self, Write};
use std::num::NonZeroI32;
use std::sync::Arc;
use thiserror::Error;

/// An implementation of `/dev/console`.
#[derive(Debug)]
pub struct Console {}
pub struct Console {
tty: Arc<Tty>,
}

impl Console {
pub const PATH: &VPath = vpath!("/dev/console");

#[allow(dead_code)]
pub const TIOCSCTTY: IoctlCom = IoctlCom::io(b't', 97);

pub fn new() -> Self {
Self {}
pub fn new(vp: &Arc<VProc>) -> Self {
Self {
tty: Tty::new(vp.clone()),
}
}
}

Expand All @@ -41,12 +46,19 @@ impl VFileOps for Console {
fn ioctl(
&self,
_file: &VFile,
_com: IoctlCom,
_data: &mut [u8],
com: IoctlCom,
data: &mut [u8],
_cred: &Ucred,
_td: &VThread,
td: &VThread,
) -> Result<(), Box<dyn Errno>> {
// TODO: Implement this.
if self.tty.is_gone() || !self.tty.is_open() {
return Err(Box::new(IoctlError::TtyNotAvailable));
}

//TODO: implement tty_wait_background and the rest of the checks here.

self.tty.ioctl(com, data, td)?;

Ok(())
}
}
Expand All @@ -55,3 +67,17 @@ impl Display for Console {
Self::PATH.fmt(f)
}
}

#[derive(Debug, Error)]
enum IoctlError {
#[error("tty is not available")]
TtyNotAvailable,
}

impl Errno for IoctlError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::TtyNotAvailable => ENXIO,
}
}
}
49 changes: 41 additions & 8 deletions src/kernel/src/fs/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ pub use self::cdev::*;
use self::dirent::{Dirent, DirentFlags};
use self::vnode::VNODE_OPS;
use super::{path_contains, DirentType, FsOps, Mount, MountFlags, Vnode, VnodeType};
use crate::errno::{Errno, EEXIST, EOPNOTSUPP};
use crate::errno::{Errno, EEXIST, EINVAL, ENAMETOOLONG, EOPNOTSUPP};
use crate::ucred::Ucred;
use bitflags::bitflags;
use cdev::{Cdev, CdevSw, DeviceFlags, DriverFlags};
use std::any::Any;
use std::collections::HashMap;
use std::num::NonZeroI32;
Expand All @@ -31,14 +32,13 @@ pub fn make_dev<N: Into<String>>(
gid: i32,
mode: u16,
cred: Option<Arc<Ucred>>,
flags: MakeDev,
flags: MakeDevFlags,
) -> Result<Arc<Cdev>, MakeDevError> {
if sw.flags().intersects(DriverFlags::D_NEEDMINOR) {
todo!("make_dev_credv with D_NEEDMINOR");
}

// TODO: Implement prep_devname.
let name = name.into();
let name = prepare_name(name.into())?;

if dev_exists(&name) {
SuchAFuriousDeath marked this conversation as resolved.
Show resolved Hide resolved
return Err(MakeDevError::AlreadyExist(name));
Expand All @@ -47,7 +47,7 @@ pub fn make_dev<N: Into<String>>(
// Get device flags.
let mut df = DeviceFlags::empty();

if flags.intersects(MakeDev::MAKEDEV_ETERNAL) {
if flags.intersects(MakeDevFlags::MAKEDEV_ETERNAL) {
df |= DeviceFlags::SI_ETERNAL;
}

Expand All @@ -70,6 +70,34 @@ pub fn make_dev<N: Into<String>>(
Ok(dev)
}

/// See `prep_devname` on the PS4 for a reference.
fn prepare_name(name: String) -> Result<String, MakeDevError> {
if name.len() > 63 {
return Err(MakeDevError::NameTooLong);
}

let name = name.trim_start_matches('/').to_string();
SuchAFuriousDeath marked this conversation as resolved.
Show resolved Hide resolved

//TODO: Deduplicate consecutive slashes.

if name.is_empty() {
return Err(MakeDevError::NameInvalid);
}

for char in name.split('/') {
match char {
"." | ".." => return Err(MakeDevError::NameInvalid),
_ => {}
}
}

if dev_exists(&name) {
return Err(MakeDevError::AlreadyExist(name));
}

Ok(name)
}

/// See `devfs_dev_exists` on the PS4 for a reference.
pub fn dev_exists<N: AsRef<str>>(name: N) -> bool {
let name = name.as_ref();
Expand Down Expand Up @@ -155,8 +183,7 @@ impl DevFs {

if children
.iter()
.find(|&c| c.dirent().ty() == DirentType::Link && c.dirent().name() == name)
.is_some()
.any(|c| c.dirent().ty() == DirentType::Link && c.dirent().name() == name)
{
todo!("devfs_populate with DT_LNK children");
}
Expand Down Expand Up @@ -273,7 +300,7 @@ impl DevFs {
bitflags! {
/// Flags for [`make_dev()`].
#[derive(Clone, Copy)]
pub struct MakeDev: u32 {
pub struct MakeDevFlags: u32 {
const MAKEDEV_ETERNAL = 0x10;
}
}
Expand All @@ -296,12 +323,18 @@ impl Devices {
pub enum MakeDevError {
#[error("the device with the same name already exist")]
AlreadyExist(String),
#[error("the device name is too long")]
NameTooLong,
#[error("the device name is invalid")]
NameInvalid,
}

impl Errno for MakeDevError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::AlreadyExist(_) => EEXIST,
Self::NameTooLong => ENAMETOOLONG,
Self::NameInvalid => EINVAL,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/fs/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub enum VDev {
impl VDev {
pub fn open(&self, vp: &Arc<VProc>) -> Result<Box<dyn VFileOps>, FsError> {
let ops: Box<dyn VFileOps> = match self {
Self::Console => Box::new(Console::new()),
Self::Console => Box::new(Console::new(vp)),
Self::Dipsw => Box::new(Dipsw::new()),
Self::DeciTty6 => Box::new(DeciTty6::new()),
Self::Dmem0 => Box::new(Dmem0::new()),
Expand Down
8 changes: 1 addition & 7 deletions src/kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,7 @@ impl Fs {
loop {
nd.cnd.nameptr += 1;

if nd
.cnd
.pnbuf
.get(nd.cnd.nameptr)
.filter(|&v| *v == b'/')
.is_none()
{
if nd.cnd.pnbuf.get(nd.cnd.nameptr).is_some_and(|&v| v != b'/') {
SuchAFuriousDeath marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/kernel/src/fs/vnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::sync::Arc;

/// An implementation of `vnode`.
#[derive(Debug)]
#[allow(dead_code)]
pub struct Vnode {
fs: Arc<Mount>, // v_mount
ty: VnodeType, // v_type
Expand Down
3 changes: 2 additions & 1 deletion src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod rtld;
mod signal;
mod syscalls;
mod sysctl;
mod tty;
mod ucred;

fn main() -> ExitCode {
Expand Down Expand Up @@ -314,7 +315,7 @@ fn run<E: crate::ee::ExecutionEngine>(
let mut flags = LoadFlags::UNK1;
let path = vpath!("/system/common/lib/libkernel.sprx");

if vp.budget().filter(|v| v.1 == ProcType::BigApp).is_some() {
if vp.budget().is_some_and(|v| v.1 == ProcType::BigApp) {
flags |= LoadFlags::BIG_APP;
}

Expand Down
25 changes: 17 additions & 8 deletions src/kernel/src/process/group.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
use super::VSession;
use std::num::NonZeroI32;
use super::{VProc, VSession};
use std::{num::NonZeroI32, sync::Arc};

/// An implementation of `pgrp` struct.
#[derive(Debug)]
pub struct VProcGroup {
id: NonZeroI32, // pg_id
session: VSession, // pg_session
id: NonZeroI32, // pg_id
session: Option<Arc<VSession>>, // pg_session
leader: Arc<VProc>, // pg_leader
}

impl VProcGroup {
pub fn new(id: NonZeroI32, session: VSession) -> Self {
Self { id, session }
pub fn new(id: NonZeroI32, session: VSession, leader: &Arc<VProc>) -> Self {
Self {
id,
session: Some(Arc::new(session)),
leader: leader.clone(),
}
}

pub fn session_mut(&mut self) -> &mut VSession {
&mut self.session
pub fn session(&self) -> Option<&Arc<VSession>> {
self.session.as_ref()
}

pub fn leader(&self) -> &Arc<VProc> {
&self.leader
}
}
28 changes: 24 additions & 4 deletions src/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::signal::{
};
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use crate::ucred::{AuthInfo, Privilege, Ucred};
use bitflags::bitflags;
use gmtx::{Gutex, GutexGroup, GutexReadGuard, GutexWriteGuard};
use llt::{SpawnError, Thread};
use std::any::Any;
Expand Down Expand Up @@ -48,12 +49,13 @@ pub struct VProc {
id: NonZeroI32, // p_pid
threads: Gutex<Vec<Arc<VThread>>>, // p_threads
cred: Ucred, // p_ucred
group: Gutex<Option<VProcGroup>>, // p_pgrp
group: Gutex<Option<Arc<VProcGroup>>>, // p_pgrp
sigacts: Gutex<SignalActs>, // p_sigacts
files: FileDesc, // p_fd
system_path: String, // p_randomized_path
limits: [ResourceLimit; ResourceLimit::NLIMITS], // p_limit
comm: Gutex<Option<String>>, // p_comm
flags: Gutex<VProcFlags>, // p_flag
objects: Gutex<Idt<Arc<dyn Any + Send + Sync>>>,
dmem_container: Gutex<i32>,
budget: Gutex<Option<(usize, ProcType)>>,
Expand Down Expand Up @@ -85,6 +87,7 @@ impl VProc {
budget: gg.spawn(None),
limits,
comm: gg.spawn(None), //TODO: Find out how this is actually set
flags: gg.spawn(VProcFlags::empty()),
app_info: AppInfo::new(),
ptc: 0,
uptc: AtomicPtr::new(null_mut()),
Expand Down Expand Up @@ -116,6 +119,10 @@ impl VProc {
&self.cred
}

pub fn group(&self) -> GutexReadGuard<'_, Option<Arc<VProcGroup>>> {
self.group.read()
}

pub fn files(&self) -> &FileDesc {
&self.files
}
Expand All @@ -124,6 +131,10 @@ impl VProc {
self.limits.get(ty)
}

pub fn flags_mut(&self) -> GutexWriteGuard<'_, VProcFlags> {
self.flags.write()
}

pub fn set_name(&self, name: Option<&str>) {
*self.comm.write() = name.map(|n| n.to_owned());
}
Expand Down Expand Up @@ -233,9 +244,11 @@ impl VProc {

// Set login name.
let mut group = self.group.write();
let session = group.as_mut().unwrap().session_mut();
let session = group.as_ref().and_then(|grp| grp.session()).unwrap();

session.set_login(login);
let mut slogin = session.login_mut();

*slogin = login.to_owned();

info!("Login name was changed to '{login}'.");

Expand All @@ -256,7 +269,7 @@ impl VProc {
// TODO: Find out the correct login name for VSession.
let session = VSession::new(self.id, String::from("root"));

*group = Some(VProcGroup::new(self.id, session));
*group = Some(Arc::new(VProcGroup::new(self.id, session, &self)));
info!("Virtual process now set as group leader.");

Ok(self.id.into())
Expand Down Expand Up @@ -712,3 +725,10 @@ pub enum VProcError {
}

static NEXT_ID: AtomicI32 = AtomicI32::new(1);

bitflags! {
#[derive(Debug)]
pub struct VProcFlags: i32 {
const P_CONTROLT = 0x00002;
}
}
Loading