Skip to content

Commit

Permalink
Merge pull request #1570 from stlankes/dup2
Browse files Browse the repository at this point in the history
add syscalls corresponding to dup2 and isatty
  • Loading branch information
mkroening authored Jan 23, 2025
2 parents 15366d2 + 5bec244 commit fbf22a8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
14 changes: 14 additions & 0 deletions src/fd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ pub(crate) trait ObjectInterface: Sync + Send + core::fmt::Debug {
async fn ioctl(&self, _cmd: IoCtl, _value: bool) -> io::Result<()> {
Err(io::Error::ENOSYS)
}

/// `isatty` returns `true` for a terminal device
async fn isatty(&self) -> io::Result<bool> {
Ok(false)
}
}

pub(crate) fn read(fd: FileDescriptor, buf: &mut [u8]) -> io::Result<usize> {
Expand Down Expand Up @@ -379,6 +384,15 @@ pub(crate) fn dup_object(fd: FileDescriptor) -> io::Result<FileDescriptor> {
block_on(core_scheduler().dup_object(fd), None)
}

pub(crate) fn dup_object2(fd1: FileDescriptor, fd2: FileDescriptor) -> io::Result<FileDescriptor> {
block_on(core_scheduler().dup_object2(fd1, fd2), None)
}

pub(crate) fn remove_object(fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
block_on(core_scheduler().remove_object(fd), None)
}

pub(crate) fn isatty(fd: FileDescriptor) -> io::Result<bool> {
let obj = get_object(fd)?;
block_on(obj.isatty(), None)
}
27 changes: 26 additions & 1 deletion src/fd/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ impl ObjectInterface for GenericStdin {
})
.await
}

async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl GenericStdin {
Expand All @@ -75,6 +79,10 @@ impl ObjectInterface for GenericStdout {
CONSOLE.lock().write(buf);
Ok(buf.len())
}

async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl GenericStdout {
Expand All @@ -97,6 +105,10 @@ impl ObjectInterface for GenericStderr {
CONSOLE.lock().write(buf);
Ok(buf.len())
}

async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl GenericStderr {
Expand All @@ -108,7 +120,12 @@ impl GenericStderr {
#[derive(Debug)]
pub struct UhyveStdin;

impl ObjectInterface for UhyveStdin {}
#[async_trait]
impl ObjectInterface for UhyveStdin {
async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl UhyveStdin {
pub const fn new() -> Self {
Expand Down Expand Up @@ -136,6 +153,10 @@ impl ObjectInterface for UhyveStdout {

Ok(write_params.len)
}

async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl UhyveStdout {
Expand Down Expand Up @@ -164,6 +185,10 @@ impl ObjectInterface for UhyveStderr {

Ok(write_params.len)
}

async fn isatty(&self) -> io::Result<bool> {
Ok(true)
}
}

impl UhyveStderr {
Expand Down
22 changes: 22 additions & 0 deletions src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,28 @@ impl PerCoreScheduler {
.await
}

pub async fn dup_object2(
&self,
fd1: FileDescriptor,
fd2: FileDescriptor,
) -> io::Result<FileDescriptor> {
future::poll_fn(|cx| {
without_interrupts(|| {
let borrowed = self.current_task.borrow();
let mut pinned_obj = core::pin::pin!(borrowed.object_map.write());
let mut guard = ready!(pinned_obj.as_mut().poll(cx));
let obj = guard.get(&fd1).cloned().ok_or(io::Error::EBADF)?;

if guard.try_insert(fd2, obj).is_err() {
Ready(Err(io::Error::EMFILE))
} else {
Ready(Ok(fd2))
}
})
})
.await
}

/// Remove a IO interface, which is named by the file descriptor
pub async fn remove_object(&self, fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
future::poll_fn(|cx| {
Expand Down
23 changes: 22 additions & 1 deletion src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use self::timer::*;
use crate::executor::block_on;
use crate::fd::{
AccessPermission, EventFlags, FileDescriptor, IoCtl, OpenOption, PollFd, dup_object,
get_object, remove_object,
dup_object2, get_object, isatty, remove_object,
};
use crate::fs::{self, FileAttr};
#[cfg(all(target_os = "none", not(feature = "common-os")))]
Expand Down Expand Up @@ -634,6 +634,27 @@ pub extern "C" fn sys_dup(fd: i32) -> i32 {
dup_object(fd).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap())
}

#[hermit_macro::system]
#[unsafe(no_mangle)]
pub extern "C" fn sys_dup2(fd1: i32, fd2: i32) -> i32 {
dup_object2(fd1, fd2).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap())
}

#[hermit_macro::system]
#[unsafe(no_mangle)]
pub extern "C" fn sys_isatty(fd: i32) -> i32 {
match isatty(fd) {
Err(e) => -num::ToPrimitive::to_i32(&e).unwrap(),
Ok(v) => {
if v {
1
} else {
0
}
}
}
}

#[hermit_macro::system]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 {
Expand Down

0 comments on commit fbf22a8

Please sign in to comment.