mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Open stdio by opening /dev/tty
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
7803d9037e
commit
4c4366ccb0
@ -5,10 +5,9 @@ use crate::prelude::*;
|
||||
use core::cell::Cell;
|
||||
use jinux_util::slot_vec::SlotVec;
|
||||
|
||||
use super::{
|
||||
file_handle::FileLike,
|
||||
stdio::{Stderr, Stdin, Stdout},
|
||||
};
|
||||
use super::file_handle::FileLike;
|
||||
use super::fs_resolver::{FsPath, FsResolver, AT_FDCWD};
|
||||
use super::utils::{AccessMode, InodeMode};
|
||||
|
||||
pub type FileDescripter = i32;
|
||||
|
||||
@ -27,9 +26,23 @@ impl FileTable {
|
||||
|
||||
pub fn new_with_stdio() -> Self {
|
||||
let mut table = SlotVec::new();
|
||||
let stdin = Stdin::new_with_default_console();
|
||||
let stdout = Stdout::new_with_default_console();
|
||||
let stderr = Stderr::new_with_default_console();
|
||||
let fs_resolver = FsResolver::new();
|
||||
let tty_path = FsPath::new(AT_FDCWD, "/dev/tty").expect("cannot find tty");
|
||||
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(stdout), false));
|
||||
table.put(FileTableEntry::new(Arc::new(stderr), false));
|
||||
|
@ -341,6 +341,7 @@ impl FsResolver {
|
||||
|
||||
pub const AT_FDCWD: FileDescripter = -100;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FsPath<'a> {
|
||||
inner: FsPathInner<'a>,
|
||||
}
|
||||
|
@ -8,5 +8,4 @@ pub mod inode_handle;
|
||||
pub mod pipe;
|
||||
pub mod procfs;
|
||||
pub mod ramfs;
|
||||
pub mod stdio;
|
||||
pub mod utils;
|
||||
|
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,28 @@ pub enum InodeType {
|
||||
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 {
|
||||
fn from(type_: DeviceType) -> InodeType {
|
||||
match type_ {
|
||||
|
@ -45,7 +45,7 @@ impl Vnode {
|
||||
|
||||
pub fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_write() {
|
||||
return_errno!(Errno::EINVAL);
|
||||
}
|
||||
let inner = self.inner.write();
|
||||
@ -68,7 +68,7 @@ impl Vnode {
|
||||
|
||||
pub fn write_direct_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_write() {
|
||||
return_errno!(Errno::EINVAL);
|
||||
}
|
||||
let inner = self.inner.write();
|
||||
@ -80,7 +80,7 @@ impl Vnode {
|
||||
|
||||
pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_read() {
|
||||
return_errno!(Errno::EISDIR);
|
||||
}
|
||||
let inner = self.inner.read();
|
||||
@ -103,7 +103,7 @@ impl Vnode {
|
||||
|
||||
pub fn read_direct_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_read() {
|
||||
return_errno!(Errno::EISDIR);
|
||||
}
|
||||
let inner = self.inner.read();
|
||||
@ -115,7 +115,7 @@ impl Vnode {
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_read() {
|
||||
return_errno!(Errno::EISDIR);
|
||||
}
|
||||
let inner = self.inner.read();
|
||||
@ -134,7 +134,7 @@ impl Vnode {
|
||||
|
||||
pub fn read_direct_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
|
||||
let type_ = self.inode_type();
|
||||
if type_ != InodeType::File && type_ != InodeType::Socket {
|
||||
if !type_.support_read() {
|
||||
return_errno!(Errno::EISDIR);
|
||||
}
|
||||
let inner = self.inner.read();
|
||||
|
Reference in New Issue
Block a user