Add termios read/write file
This commit is contained in:
@@ -15,6 +15,7 @@ mod pty;
|
||||
mod resource;
|
||||
mod scheme;
|
||||
mod slave;
|
||||
mod termios;
|
||||
|
||||
use scheme::PtyScheme;
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ impl Resource for PtyMaster {
|
||||
fn pty(&self) -> Weak<RefCell<Pty>> {
|
||||
Rc::downgrade(&self.pty)
|
||||
}
|
||||
|
||||
fn flags(&self) -> usize {
|
||||
self.flags
|
||||
}
|
||||
|
||||
fn path(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
self.pty.borrow_mut().path(buf)
|
||||
|
||||
@@ -8,6 +8,8 @@ use pty::Pty;
|
||||
pub trait Resource {
|
||||
fn boxed_clone(&self) -> Box<Resource>;
|
||||
fn pty(&self) -> Weak<RefCell<Pty>>;
|
||||
fn flags(&self) -> usize;
|
||||
|
||||
fn path(&self, buf: &mut [u8]) -> Result<usize>;
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize>;
|
||||
fn write(&self, buf: &[u8]) -> Result<usize>;
|
||||
|
||||
+9
-5
@@ -12,6 +12,7 @@ use master::PtyMaster;
|
||||
use pty::Pty;
|
||||
use resource::Resource;
|
||||
use slave::PtySlave;
|
||||
use termios::PtyTermios;
|
||||
|
||||
pub struct PtyScheme {
|
||||
next_id: usize,
|
||||
@@ -56,13 +57,16 @@ impl SchemeMut for PtyScheme {
|
||||
}
|
||||
|
||||
fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result<usize> {
|
||||
if ! buf.is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let handle = {
|
||||
let old_handle = self.handles.get(&old_id).ok_or(Error::new(EBADF))?;
|
||||
old_handle.boxed_clone()
|
||||
|
||||
if buf.is_empty() {
|
||||
old_handle.boxed_clone()
|
||||
} else if buf == b"termios" {
|
||||
Box::new(PtyTermios::new(old_handle.pty(), old_handle.flags()))
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
};
|
||||
|
||||
let id = self.next_id;
|
||||
|
||||
@@ -32,6 +32,10 @@ impl Resource for PtySlave {
|
||||
self.pty.clone()
|
||||
}
|
||||
|
||||
fn flags(&self) -> usize {
|
||||
self.flags
|
||||
}
|
||||
|
||||
fn path(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
if let Some(pty_lock) = self.pty.upgrade() {
|
||||
pty_lock.borrow_mut().path(buf)
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::rc::Weak;
|
||||
|
||||
use syscall::error::{Error, Result, EBADF, EINVAL, EPIPE};
|
||||
use syscall::flag::{F_GETFL, F_SETFL, O_ACCMODE};
|
||||
|
||||
use pty::Pty;
|
||||
use resource::Resource;
|
||||
|
||||
/// Read side of a pipe
|
||||
#[derive(Clone)]
|
||||
pub struct PtyTermios {
|
||||
pty: Weak<RefCell<Pty>>,
|
||||
flags: usize,
|
||||
}
|
||||
|
||||
impl PtyTermios {
|
||||
pub fn new(pty: Weak<RefCell<Pty>>, flags: usize) -> Self {
|
||||
PtyTermios {
|
||||
pty: pty,
|
||||
flags: flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Resource for PtyTermios {
|
||||
fn boxed_clone(&self) -> Box<Resource> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn pty(&self) -> Weak<RefCell<Pty>> {
|
||||
self.pty.clone()
|
||||
}
|
||||
|
||||
fn flags(&self) -> usize {
|
||||
self.flags
|
||||
}
|
||||
|
||||
fn path(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
if let Some(pty_lock) = self.pty.upgrade() {
|
||||
pty_lock.borrow_mut().path(buf)
|
||||
} else {
|
||||
Err(Error::new(EPIPE))
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
if let Some(pty_lock) = self.pty.upgrade() {
|
||||
let pty = pty_lock.borrow();
|
||||
let termios: &[u8] = pty.termios.deref();
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() && i < termios.len() {
|
||||
buf[i] = termios[i];
|
||||
i += 1;
|
||||
}
|
||||
Ok(i)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
if let Some(pty_lock) = self.pty.upgrade() {
|
||||
let mut pty = pty_lock.borrow_mut();
|
||||
let termios: &mut [u8] = pty.termios.deref_mut();
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() && i < termios.len() {
|
||||
termios[i] = buf[i];
|
||||
i += 1;
|
||||
}
|
||||
Ok(i)
|
||||
} else {
|
||||
Err(Error::new(EPIPE))
|
||||
}
|
||||
}
|
||||
|
||||
fn sync(&self) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
|
||||
match cmd {
|
||||
F_GETFL => Ok(self.flags),
|
||||
F_SETFL => {
|
||||
self.flags = (self.flags & O_ACCMODE) | (arg & ! O_ACCMODE);
|
||||
Ok(0)
|
||||
},
|
||||
_ => Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
|
||||
fn fevent(&self) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
fn fevent_count(&self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user