Skip to content

Commit e48ca0d

Browse files
authored
Merge pull request #1145 from stevenengler/improve-rust-syscalls
Improve rust syscalls/descriptors
2 parents ca59430 + 59df7d8 commit e48ca0d

6 files changed

Lines changed: 229 additions & 73 deletions

File tree

src/main/bindings/c/bindings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,12 @@ SysCallReturn rustsyscallhandler_dup(SysCallHandler *sys, const SysCallArgs *arg
139139

140140
SysCallReturn rustsyscallhandler_read(SysCallHandler *sys, const SysCallArgs *args);
141141

142+
SysCallReturn rustsyscallhandler_pread64(SysCallHandler *sys, const SysCallArgs *args);
143+
142144
SysCallReturn rustsyscallhandler_write(SysCallHandler *sys, const SysCallArgs *args);
143145

146+
SysCallReturn rustsyscallhandler_pwrite64(SysCallHandler *sys, const SysCallArgs *args);
147+
144148
SysCallReturn rustsyscallhandler_pipe(SysCallHandler *sys, const SysCallArgs *args);
145149

146150
SysCallReturn rustsyscallhandler_pipe2(SysCallHandler *sys, const SysCallArgs *args);
@@ -151,6 +155,8 @@ void bytequeue_free(ByteQueue *bq_ptr);
151155

152156
size_t bytequeue_len(ByteQueue *bq);
153157

158+
bool bytequeue_isEmpty(ByteQueue *bq);
159+
154160
void bytequeue_push(ByteQueue *bq, const unsigned char *src, size_t len);
155161

156162
size_t bytequeue_pop(ByteQueue *bq, unsigned char *dst, size_t len);

src/main/host/descriptor/mod.rs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl From<FileStatus> for c::Status {
114114
}
115115
}
116116

117-
#[derive(Clone)]
117+
#[derive(Clone, Debug)]
118118
pub enum NewStatusListenerFilter {
119119
Never,
120120
OffToOn,
@@ -260,15 +260,31 @@ impl IsSend for PosixFile {}
260260
impl IsSync for PosixFile {}
261261

262262
impl PosixFile {
263-
pub fn read(&mut self, bytes: &mut [u8], event_queue: &mut EventQueue) -> SyscallReturn {
263+
pub fn close(&mut self, event_queue: &mut EventQueue) -> SyscallReturn {
264264
match self {
265-
Self::Pipe(f) => f.read(bytes, event_queue),
265+
Self::Pipe(f) => f.close(event_queue),
266266
}
267267
}
268268

269-
pub fn write(&mut self, bytes: &[u8], event_queue: &mut EventQueue) -> SyscallReturn {
269+
pub fn read(
270+
&mut self,
271+
bytes: &mut [u8],
272+
offset: libc::off_t,
273+
event_queue: &mut EventQueue,
274+
) -> SyscallReturn {
275+
match self {
276+
Self::Pipe(f) => f.read(bytes, offset, event_queue),
277+
}
278+
}
279+
280+
pub fn write(
281+
&mut self,
282+
bytes: &[u8],
283+
offset: libc::off_t,
284+
event_queue: &mut EventQueue,
285+
) -> SyscallReturn {
270286
match self {
271-
Self::Pipe(f) => f.write(bytes, event_queue),
287+
Self::Pipe(f) => f.write(bytes, offset, event_queue),
272288
}
273289
}
274290

@@ -303,6 +319,20 @@ impl PosixFile {
303319
}
304320
}
305321

322+
impl std::fmt::Debug for PosixFile {
323+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
324+
match self {
325+
Self::Pipe(_) => write!(f, "Pipe")?,
326+
}
327+
write!(
328+
f,
329+
"(status: {:?}, flags: {:?})",
330+
self.status(),
331+
self.get_flags()
332+
)
333+
}
334+
}
335+
306336
bitflags::bitflags! {
307337
// Linux only supports a single descriptor flag:
308338
// https://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html
@@ -311,17 +341,24 @@ bitflags::bitflags! {
311341
}
312342
}
313343

314-
#[derive(Clone)]
344+
#[derive(Clone, Debug)]
315345
pub struct Descriptor {
346+
/// The PosixFile that this descriptor points to.
316347
file: Arc<AtomicRefCell<PosixFile>>,
348+
/// Descriptor flags.
317349
flags: DescriptorFlags,
350+
/// A count of how many open descriptors there are with reference to this file. Since a
351+
/// reference to the file can be held by other objects like an epoll file, it should
352+
/// be true that `Arc::strong_count(&self.count)` <= `Arc::strong_count(&self.file)`.
353+
open_count: Arc<()>,
318354
}
319355

320356
impl Descriptor {
321357
pub fn new(file: Arc<AtomicRefCell<PosixFile>>) -> Self {
322358
Self {
323359
file,
324360
flags: DescriptorFlags::empty(),
361+
open_count: Arc::new(()),
325362
}
326363
}
327364

@@ -336,6 +373,10 @@ impl Descriptor {
336373
pub fn set_flags(&mut self, flags: DescriptorFlags) {
337374
self.flags = flags;
338375
}
376+
377+
pub fn get_open_count(&self) -> usize {
378+
Arc::<()>::strong_count(&self.open_count)
379+
}
339380
}
340381

341382
// don't implement copy or clone without considering the legacy descriptor's ref count

src/main/host/descriptor/pipe.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,27 @@ impl PipeFile {
4343
self.flags = flags;
4444
}
4545

46-
pub fn read(&mut self, bytes: &mut [u8], event_queue: &mut EventQueue) -> SyscallReturn {
46+
pub fn close(&mut self, event_queue: &mut EventQueue) -> SyscallReturn {
47+
// set the closed flag and remove the active flag
48+
self.copy_status(
49+
FileStatus::CLOSED | FileStatus::ACTIVE,
50+
FileStatus::CLOSED,
51+
event_queue,
52+
);
53+
SyscallReturn::Success(0)
54+
}
55+
56+
pub fn read(
57+
&mut self,
58+
bytes: &mut [u8],
59+
offset: libc::off_t,
60+
event_queue: &mut EventQueue,
61+
) -> SyscallReturn {
62+
// pipes don't support seeking
63+
if offset != 0 {
64+
return SyscallReturn::Error(nix::errno::Errno::ESPIPE);
65+
}
66+
4767
// if the file is not open for reading, return EBADF
4868
if !self.mode.contains(FileMode::READ) {
4969
return SyscallReturn::Error(nix::errno::Errno::EBADF);
@@ -54,7 +74,17 @@ impl PipeFile {
5474
SyscallReturn::Success(num_read as i32)
5575
}
5676

57-
pub fn write(&mut self, bytes: &[u8], event_queue: &mut EventQueue) -> SyscallReturn {
77+
pub fn write(
78+
&mut self,
79+
bytes: &[u8],
80+
offset: libc::off_t,
81+
event_queue: &mut EventQueue,
82+
) -> SyscallReturn {
83+
// pipes don't support seeking
84+
if offset != 0 {
85+
return SyscallReturn::Error(nix::errno::Errno::ESPIPE);
86+
}
87+
5888
// if the file is not open for writing, return EBADF
5989
if !self.mode.contains(FileMode::WRITE) {
6090
return SyscallReturn::Error(nix::errno::Errno::EBADF);
@@ -63,7 +93,7 @@ impl PipeFile {
6393
let num_written = self.buffer.borrow_mut().write(bytes, event_queue);
6494

6595
// the write would block if we could not write any bytes, but were asked to
66-
if num_written == 0 && bytes.len() > 0 {
96+
if num_written == 0 && !bytes.is_empty() {
6797
SyscallReturn::Error(nix::errno::EWOULDBLOCK)
6898
} else {
6999
SyscallReturn::Success(num_written as i32)
@@ -72,7 +102,7 @@ impl PipeFile {
72102

73103
pub fn enable_notifications(arc: &Arc<AtomicRefCell<PosixFile>>) {
74104
// we remove some of these later in this function
75-
let monitoring = FileStatus::CLOSED | FileStatus::READABLE | FileStatus::WRITABLE;
105+
let monitoring = FileStatus::READABLE | FileStatus::WRITABLE;
76106

77107
let weak = Arc::downgrade(arc);
78108
match *arc.borrow_mut() {

0 commit comments

Comments
 (0)