This commit is contained in:
Jeremy Soller
2017-07-23 12:54:32 -06:00
parent b69fd15d3c
commit a44184adb7
4 changed files with 118 additions and 0 deletions
+1
View File
@@ -11,6 +11,7 @@ use syscall::error::EWOULDBLOCK;
use syscall::scheme::SchemeMut;
mod master;
mod pgrp;
mod pty;
mod resource;
mod scheme;
+112
View File
@@ -0,0 +1,112 @@
use std::{mem, slice};
use std::cell::RefCell;
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 PtyPgrp {
pty: Weak<RefCell<Pty>>,
flags: usize,
}
impl PtyPgrp {
pub fn new(pty: Weak<RefCell<Pty>>, flags: usize) -> Self {
PtyPgrp {
pty: pty,
flags: flags,
}
}
}
impl Resource for PtyPgrp {
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 pgrp: &[u8] = unsafe {
slice::from_raw_parts(
&pty.pgrp as *const usize as *const u8,
mem::size_of::<usize>()
)
};
let mut i = 0;
while i < buf.len() && i < pgrp.len() {
buf[i] = pgrp[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 pgrp: &mut [u8] = unsafe {
slice::from_raw_parts_mut(
&mut pty.pgrp as *mut usize as *mut u8,
mem::size_of::<usize>()
)
};
let mut i = 0;
while i < buf.len() && i < pgrp.len() {
pgrp[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
}
}
+2
View File
@@ -5,6 +5,7 @@ use syscall::error::Result;
pub struct Pty {
pub id: usize,
pub pgrp: usize,
pub termios: Termios,
pub winsize: Winsize,
pub miso: VecDeque<Vec<u8>>,
@@ -15,6 +16,7 @@ impl Pty {
pub fn new(id: usize) -> Self {
let mut pty = Pty {
id: id,
pgrp: 0,
termios: Termios::default(),
winsize: Winsize::default(),
miso: VecDeque::new(),
+3
View File
@@ -9,6 +9,7 @@ use syscall::flag::MODE_CHR;
use syscall::scheme::SchemeMut;
use master::PtyMaster;
use pgrp::PtyPgrp;
use pty::Pty;
use resource::Resource;
use slave::PtySlave;
@@ -63,6 +64,8 @@ impl SchemeMut for PtyScheme {
if buf.is_empty() {
old_handle.boxed_clone()
} else if buf == b"pgrp" {
Box::new(PtyPgrp::new(old_handle.pty(), old_handle.flags()))
} else if buf == b"termios" {
Box::new(PtyTermios::new(old_handle.pty(), old_handle.flags()))
} else if buf == b"winsize" {