diff --git a/kernel/aster-nix/src/fs/utils/ioctl.rs b/kernel/aster-nix/src/fs/utils/ioctl.rs index 4503dcfa3..d0dc222b8 100644 --- a/kernel/aster-nix/src/fs/utils/ioctl.rs +++ b/kernel/aster-nix/src/fs/utils/ioctl.rs @@ -23,8 +23,12 @@ pub enum IoctlCmd { /// Set window size TIOCGWINSZ = 0x5413, TIOCSWINSZ = 0x5414, + /// Enable or disable non-blocking I/O mode. + FIONBIO = 0x5421, /// the calling process gives up this controlling terminal TIOCNOTTY = 0x5422, + /// Enable or disable asynchronous I/O mode. + FIOASYNC = 0x5452, /// Get Pty Number TIOCGPTN = 0x80045430, /// Lock/unlock Pty diff --git a/kernel/aster-nix/src/net/socket/ip/datagram/mod.rs b/kernel/aster-nix/src/net/socket/ip/datagram/mod.rs index 7cca30f42..5ffd09535 100644 --- a/kernel/aster-nix/src/net/socket/ip/datagram/mod.rs +++ b/kernel/aster-nix/src/net/socket/ip/datagram/mod.rs @@ -232,6 +232,7 @@ impl FileLike for DatagramSocket { } fn status_flags(&self) -> StatusFlags { + // TODO: when we fully support O_ASYNC, return the flag if self.is_nonblocking() { StatusFlags::O_NONBLOCK } else { diff --git a/kernel/aster-nix/src/net/socket/ip/stream/mod.rs b/kernel/aster-nix/src/net/socket/ip/stream/mod.rs index c6c9e80d7..1fa831eea 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/mod.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/mod.rs @@ -377,6 +377,7 @@ impl FileLike for StreamSocket { } fn status_flags(&self) -> StatusFlags { + // TODO: when we fully support O_ASYNC, return the flag if self.is_nonblocking() { StatusFlags::O_NONBLOCK } else { diff --git a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs index d4ba273bd..05dd3f04b 100644 --- a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs +++ b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs @@ -137,6 +137,7 @@ impl FileLike for UnixStreamSocket { State::Connected(connected) => connected.is_nonblocking(), }; + // TODO: when we fully support O_ASYNC, return the flag if is_nonblocking { StatusFlags::O_NONBLOCK } else { diff --git a/kernel/aster-nix/src/syscall/ioctl.rs b/kernel/aster-nix/src/syscall/ioctl.rs index ecfdee520..14e860c9b 100644 --- a/kernel/aster-nix/src/syscall/ioctl.rs +++ b/kernel/aster-nix/src/syscall/ioctl.rs @@ -2,8 +2,12 @@ use super::SyscallReturn; use crate::{ - fs::{file_table::FileDesc, utils::IoctlCmd}, + fs::{ + file_table::FileDesc, + utils::{IoctlCmd, StatusFlags}, + }, prelude::*, + util::read_val_from_user, }; pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result { @@ -15,6 +19,26 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result { let current = current!(); let file_table = current.file_table().lock(); let file = file_table.get_file(fd)?; - let res = file.ioctl(ioctl_cmd, arg)?; + let res = match ioctl_cmd { + IoctlCmd::FIONBIO => { + let is_nonblocking = read_val_from_user::(arg)? != 0; + let mut flags = file.status_flags(); + flags.set(StatusFlags::O_NONBLOCK, is_nonblocking); + file.set_status_flags(flags)?; + 0 + } + IoctlCmd::FIOASYNC => { + let is_async = read_val_from_user::(arg)? != 0; + let mut flags = file.status_flags(); + + // Set `O_ASYNC` flags will send `SIGIO` signal to a process when + // I/O is possible, user should call `fcntl(fd, F_SETOWN, pid)` + // first to let the kernel know just whom to notify. + flags.set(StatusFlags::O_ASYNC, is_async); + file.set_status_flags(flags)?; + 0 + } + _ => file.ioctl(ioctl_cmd, arg)?, + }; Ok(SyscallReturn::Return(res as _)) }