Event on close

This commit is contained in:
Jeremy Soller 2016-11-02 12:48:32 -06:00
parent 1585e67f1b
commit b43818170e

View file

@ -1,12 +1,13 @@
#![feature(arc_counts)] #![feature(rc_counts)]
extern crate syscall; extern crate syscall;
use std::cell::RefCell;
use std::collections::{BTreeMap, VecDeque}; use std::collections::{BTreeMap, VecDeque};
use std::fs::File; use std::fs::File;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::rc::{Rc, Weak};
use std::{str, thread}; use std::{str, thread};
use std::sync::{Arc, Weak, Mutex};
use syscall::data::Packet; use syscall::data::Packet;
use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT, EPIPE, EWOULDBLOCK}; use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT, EPIPE, EWOULDBLOCK};
@ -99,6 +100,14 @@ impl SchemeMut for PtyScheme {
Err(Error::new(EBADF)) Err(Error::new(EBADF))
} }
fn fevent(&mut self, id: usize, _flags: usize) -> Result<usize> {
if self.ptys.0.contains_key(&id) || self.ptys.1.contains_key(&id) {
Ok(id)
} else {
Err(Error::new(EBADF))
}
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> { fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
let master_opt = self.ptys.0.get(&id).map(|pipe| pipe.clone()); let master_opt = self.ptys.0.get(&id).map(|pipe| pipe.clone());
if let Some(pipe) = master_opt { if let Some(pipe) = master_opt {
@ -135,8 +144,8 @@ impl SchemeMut for PtyScheme {
pub struct PtyMaster { pub struct PtyMaster {
id: usize, id: usize,
flags: usize, flags: usize,
read: Arc<Mutex<VecDeque<Vec<u8>>>>, read: Rc<RefCell<VecDeque<Vec<u8>>>>,
write: Arc<Mutex<VecDeque<u8>>>, write: Rc<RefCell<VecDeque<u8>>>,
} }
impl PtyMaster { impl PtyMaster {
@ -144,8 +153,8 @@ impl PtyMaster {
PtyMaster { PtyMaster {
id: id, id: id,
flags: flags, flags: flags,
read: Arc::new(Mutex::new(VecDeque::new())), read: Rc::new(RefCell::new(VecDeque::new())),
write: Arc::new(Mutex::new(VecDeque::new())), write: Rc::new(RefCell::new(VecDeque::new())),
} }
} }
@ -163,7 +172,7 @@ impl PtyMaster {
} }
fn read(&self, buf: &mut [u8]) -> Result<usize> { fn read(&self, buf: &mut [u8]) -> Result<usize> {
let mut read = self.read.lock().unwrap(); let mut read = self.read.borrow_mut();
if let Some(packet) = read.pop_front() { if let Some(packet) = read.pop_front() {
let mut i = 0; let mut i = 0;
@ -174,7 +183,7 @@ impl PtyMaster {
} }
Ok(i) Ok(i)
} else if self.flags & O_NONBLOCK == O_NONBLOCK || Arc::weak_count(&self.read) == 0 { } else if self.flags & O_NONBLOCK == O_NONBLOCK || Rc::weak_count(&self.read) == 0 {
Ok(0) Ok(0)
} else { } else {
Err(Error::new(EWOULDBLOCK)) Err(Error::new(EWOULDBLOCK))
@ -182,7 +191,7 @@ impl PtyMaster {
} }
fn write(&self, buf: &[u8]) -> Result<usize> { fn write(&self, buf: &[u8]) -> Result<usize> {
let mut write = self.write.lock().unwrap(); let mut write = self.write.borrow_mut();
let mut i = 0; let mut i = 0;
while i < buf.len() { while i < buf.len() {
@ -199,8 +208,8 @@ impl PtyMaster {
pub struct PtySlave { pub struct PtySlave {
master_id: usize, master_id: usize,
flags: usize, flags: usize,
read: Weak<Mutex<VecDeque<u8>>>, read: Weak<RefCell<VecDeque<u8>>>,
write: Weak<Mutex<VecDeque<Vec<u8>>>>, write: Weak<RefCell<VecDeque<Vec<u8>>>>,
} }
impl PtySlave { impl PtySlave {
@ -208,8 +217,8 @@ impl PtySlave {
PtySlave { PtySlave {
master_id: master.id, master_id: master.id,
flags: flags, flags: flags,
read: Arc::downgrade(&master.write), read: Rc::downgrade(&master.write),
write: Arc::downgrade(&master.read), write: Rc::downgrade(&master.read),
} }
} }
@ -228,7 +237,7 @@ impl PtySlave {
fn read(&self, buf: &mut [u8]) -> Result<usize> { fn read(&self, buf: &mut [u8]) -> Result<usize> {
if let Some(read_lock) = self.read.upgrade() { if let Some(read_lock) = self.read.upgrade() {
let mut read = read_lock.lock().unwrap(); let mut read = read_lock.borrow_mut();
let mut i = 0; let mut i = 0;
@ -253,7 +262,7 @@ impl PtySlave {
vec.push(0); vec.push(0);
vec.extend_from_slice(buf); vec.extend_from_slice(buf);
let mut write = write_lock.lock().unwrap(); let mut write = write_lock.borrow_mut();
write.push_back(vec); write.push_back(vec);
Ok(buf.len()) Ok(buf.len())
@ -267,7 +276,7 @@ impl PtySlave {
let mut vec = Vec::new(); let mut vec = Vec::new();
vec.push(1); vec.push(1);
let mut write = write_lock.lock().unwrap(); let mut write = write_lock.borrow_mut();
write.push_back(vec); write.push_back(vec);
Ok(0) Ok(0)
@ -307,6 +316,51 @@ fn main(){
socket.write(&packet).expect("pty: failed to write responses to pty scheme"); socket.write(&packet).expect("pty: failed to write responses to pty scheme");
} }
} }
for (id, master) in scheme.ptys.0.iter() {
let read = master.read.borrow();
if let Some(data) = read.front() {
socket.write(&Packet {
id: 0,
pid: 0,
uid: 0,
gid: 0,
a: syscall::number::SYS_FEVENT,
b: *id,
c: syscall::flag::EVENT_READ,
d: data.len()
}).expect("pty: failed to write event");
}
}
for (id, slave) in scheme.ptys.1.iter() {
if let Some(read_lock) = slave.read.upgrade() {
let read = read_lock.borrow();
if ! read.is_empty() {
socket.write(&Packet {
id: 0,
pid: 0,
uid: 0,
gid: 0,
a: syscall::number::SYS_FEVENT,
b: *id,
c: syscall::flag::EVENT_READ,
d: read.len()
}).expect("pty: failed to write event");
}
} else {
socket.write(&Packet {
id: 0,
pid: 0,
uid: 0,
gid: 0,
a: syscall::number::SYS_FEVENT,
b: *id,
c: syscall::flag::EVENT_READ,
d: 0
}).expect("pty: failed to write event");
}
}
} }
}); });
} }