Open stdio by opening /dev/tty

This commit is contained in:
Jianfeng Jiang
2023-06-02 16:10:18 +08:00
committed by Tate, Hongliang Tian
parent 7803d9037e
commit 4c4366ccb0
6 changed files with 49 additions and 203 deletions

View File

@ -5,10 +5,9 @@ use crate::prelude::*;
use core::cell::Cell; use core::cell::Cell;
use jinux_util::slot_vec::SlotVec; use jinux_util::slot_vec::SlotVec;
use super::{ use super::file_handle::FileLike;
file_handle::FileLike, use super::fs_resolver::{FsPath, FsResolver, AT_FDCWD};
stdio::{Stderr, Stdin, Stdout}, use super::utils::{AccessMode, InodeMode};
};
pub type FileDescripter = i32; pub type FileDescripter = i32;
@ -27,9 +26,23 @@ impl FileTable {
pub fn new_with_stdio() -> Self { pub fn new_with_stdio() -> Self {
let mut table = SlotVec::new(); let mut table = SlotVec::new();
let stdin = Stdin::new_with_default_console(); let fs_resolver = FsResolver::new();
let stdout = Stdout::new_with_default_console(); let tty_path = FsPath::new(AT_FDCWD, "/dev/tty").expect("cannot find tty");
let stderr = Stderr::new_with_default_console(); let stdin = {
let flags = AccessMode::O_RDONLY as u32;
let mode = InodeMode::S_IRUSR;
fs_resolver.open(&tty_path, flags, mode.bits()).unwrap()
};
let stdout = {
let flags = AccessMode::O_WRONLY as u32;
let mode = InodeMode::S_IWUSR;
fs_resolver.open(&tty_path, flags, mode.bits()).unwrap()
};
let stderr = {
let flags = AccessMode::O_WRONLY as u32;
let mode = InodeMode::S_IWUSR;
fs_resolver.open(&tty_path, flags, mode.bits()).unwrap()
};
table.put(FileTableEntry::new(Arc::new(stdin), false)); table.put(FileTableEntry::new(Arc::new(stdin), false));
table.put(FileTableEntry::new(Arc::new(stdout), false)); table.put(FileTableEntry::new(Arc::new(stdout), false));
table.put(FileTableEntry::new(Arc::new(stderr), false)); table.put(FileTableEntry::new(Arc::new(stderr), false));

View File

@ -341,6 +341,7 @@ impl FsResolver {
pub const AT_FDCWD: FileDescripter = -100; pub const AT_FDCWD: FileDescripter = -100;
#[derive(Debug)]
pub struct FsPath<'a> { pub struct FsPath<'a> {
inner: FsPathInner<'a>, inner: FsPathInner<'a>,
} }

View File

@ -8,5 +8,4 @@ pub mod inode_handle;
pub mod pipe; pub mod pipe;
pub mod procfs; pub mod procfs;
pub mod ramfs; pub mod ramfs;
pub mod stdio;
pub mod utils; pub mod utils;

View File

@ -1,189 +0,0 @@
use crate::device::tty::{get_n_tty, Tty};
use crate::prelude::*;
use super::device::Device;
use super::file_handle::FileLike;
use super::file_table::FileDescripter;
use super::utils::{InodeMode, InodeType, IoEvents, Metadata, Poller, SeekFrom};
pub const FD_STDIN: FileDescripter = 0;
pub const FD_STDOUT: FileDescripter = 1;
pub const FD_STDERR: FileDescripter = 2;
pub struct Stdin {
console: Option<Arc<Tty>>,
}
pub struct Stdout {
console: Option<Arc<Tty>>,
}
pub struct Stderr {
console: Option<Arc<Tty>>,
}
impl FileLike for Stdin {
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
if let Some(console) = self.console.as_ref() {
console.poll(mask, poller)
} else {
todo!()
}
}
fn read(&self, buf: &mut [u8]) -> Result<usize> {
if let Some(console) = self.console.as_ref() {
console.read(buf)
} else {
todo!()
}
}
fn ioctl(&self, cmd: super::utils::IoctlCmd, arg: usize) -> Result<i32> {
if let Some(console) = self.console.as_ref() {
console.ioctl(cmd, arg)
} else {
todo!()
}
}
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
// TODO: do real seek
Ok(0)
}
fn metadata(&self) -> Metadata {
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 1024,
blocks: 0,
atime: Default::default(),
mtime: Default::default(),
ctime: Default::default(),
type_: InodeType::CharDevice,
mode: InodeMode::from_bits_truncate(0o620),
nlinks: 1,
uid: 0,
gid: 0,
rdev: 0,
}
}
}
impl FileLike for Stdout {
fn ioctl(&self, cmd: super::utils::IoctlCmd, arg: usize) -> Result<i32> {
if let Some(console) = self.console.as_ref() {
console.ioctl(cmd, arg)
} else {
todo!()
}
}
fn write(&self, buf: &[u8]) -> Result<usize> {
if let Some(console) = self.console.as_ref() {
console.write(buf)
} else {
todo!()
}
}
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
// TODO: do real seek
Ok(0)
}
fn metadata(&self) -> Metadata {
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 1024,
blocks: 0,
atime: Default::default(),
mtime: Default::default(),
ctime: Default::default(),
type_: InodeType::CharDevice,
mode: InodeMode::from_bits_truncate(0o620),
nlinks: 1,
uid: 0,
gid: 0,
rdev: 0,
}
}
}
impl FileLike for Stderr {
fn ioctl(&self, cmd: super::utils::IoctlCmd, arg: usize) -> Result<i32> {
if let Some(console) = self.console.as_ref() {
console.ioctl(cmd, arg)
} else {
todo!()
}
}
fn write(&self, buf: &[u8]) -> Result<usize> {
if let Some(console) = self.console.as_ref() {
console.write(buf)
} else {
todo!()
}
}
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
// TODO: do real seek
Ok(0)
}
fn metadata(&self) -> Metadata {
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 1024,
blocks: 0,
atime: Default::default(),
mtime: Default::default(),
ctime: Default::default(),
type_: InodeType::CharDevice,
mode: InodeMode::from_bits_truncate(0o620),
nlinks: 1,
uid: 0,
gid: 0,
rdev: 0,
}
}
}
impl Stdin {
/// FIXME: console should be file under devfs.
/// reimplement the function when devfs is enabled.
pub fn new_with_default_console() -> Self {
let console = get_n_tty();
Self {
console: Some(console.clone()),
}
}
}
impl Stdout {
/// FIXME: console should be file under devfs.
/// reimplement the function when devfs is enabled.
pub fn new_with_default_console() -> Self {
let console = get_n_tty();
Self {
console: Some(console.clone()),
}
}
}
impl Stderr {
/// FIXME: console should be file under devfs.
/// reimplement the function when devfs is enabled.
pub fn new_with_default_console() -> Self {
let console = get_n_tty();
Self {
console: Some(console.clone()),
}
}
}

View File

@ -21,6 +21,28 @@ pub enum InodeType {
Socket = 0o140000, Socket = 0o140000,
} }
impl InodeType {
pub fn support_read(&self) -> bool {
match self {
InodeType::File
| InodeType::Socket
| InodeType::CharDevice
| InodeType::BlockDevice => true,
_ => false,
}
}
pub fn support_write(&self) -> bool {
match self {
InodeType::File
| InodeType::Socket
| InodeType::CharDevice
| InodeType::BlockDevice => true,
_ => false,
}
}
}
impl From<DeviceType> for InodeType { impl From<DeviceType> for InodeType {
fn from(type_: DeviceType) -> InodeType { fn from(type_: DeviceType) -> InodeType {
match type_ { match type_ {

View File

@ -45,7 +45,7 @@ impl Vnode {
pub fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> { pub fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_write() {
return_errno!(Errno::EINVAL); return_errno!(Errno::EINVAL);
} }
let inner = self.inner.write(); let inner = self.inner.write();
@ -68,7 +68,7 @@ impl Vnode {
pub fn write_direct_at(&self, offset: usize, buf: &[u8]) -> Result<usize> { pub fn write_direct_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_write() {
return_errno!(Errno::EINVAL); return_errno!(Errno::EINVAL);
} }
let inner = self.inner.write(); let inner = self.inner.write();
@ -80,7 +80,7 @@ impl Vnode {
pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> { pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_read() {
return_errno!(Errno::EISDIR); return_errno!(Errno::EISDIR);
} }
let inner = self.inner.read(); let inner = self.inner.read();
@ -103,7 +103,7 @@ impl Vnode {
pub fn read_direct_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> { pub fn read_direct_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_read() {
return_errno!(Errno::EISDIR); return_errno!(Errno::EISDIR);
} }
let inner = self.inner.read(); let inner = self.inner.read();
@ -115,7 +115,7 @@ impl Vnode {
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> { pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_read() {
return_errno!(Errno::EISDIR); return_errno!(Errno::EISDIR);
} }
let inner = self.inner.read(); let inner = self.inner.read();
@ -134,7 +134,7 @@ impl Vnode {
pub fn read_direct_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> { pub fn read_direct_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
let type_ = self.inode_type(); let type_ = self.inode_type();
if type_ != InodeType::File && type_ != InodeType::Socket { if !type_.support_read() {
return_errno!(Errno::EISDIR); return_errno!(Errno::EISDIR);
} }
let inner = self.inner.read(); let inner = self.inner.read();