Add ioctl subcommand FIONBIO/FIOASYNC

This commit is contained in:
Qingsong Chen
2024-07-15 09:28:22 +00:00
committed by Tate, Hongliang Tian
parent 8a9c012249
commit fbf2afd799
5 changed files with 33 additions and 2 deletions

View File

@ -23,8 +23,12 @@ pub enum IoctlCmd {
/// Set window size /// Set window size
TIOCGWINSZ = 0x5413, TIOCGWINSZ = 0x5413,
TIOCSWINSZ = 0x5414, TIOCSWINSZ = 0x5414,
/// Enable or disable non-blocking I/O mode.
FIONBIO = 0x5421,
/// the calling process gives up this controlling terminal /// the calling process gives up this controlling terminal
TIOCNOTTY = 0x5422, TIOCNOTTY = 0x5422,
/// Enable or disable asynchronous I/O mode.
FIOASYNC = 0x5452,
/// Get Pty Number /// Get Pty Number
TIOCGPTN = 0x80045430, TIOCGPTN = 0x80045430,
/// Lock/unlock Pty /// Lock/unlock Pty

View File

@ -232,6 +232,7 @@ impl FileLike for DatagramSocket {
} }
fn status_flags(&self) -> StatusFlags { fn status_flags(&self) -> StatusFlags {
// TODO: when we fully support O_ASYNC, return the flag
if self.is_nonblocking() { if self.is_nonblocking() {
StatusFlags::O_NONBLOCK StatusFlags::O_NONBLOCK
} else { } else {

View File

@ -377,6 +377,7 @@ impl FileLike for StreamSocket {
} }
fn status_flags(&self) -> StatusFlags { fn status_flags(&self) -> StatusFlags {
// TODO: when we fully support O_ASYNC, return the flag
if self.is_nonblocking() { if self.is_nonblocking() {
StatusFlags::O_NONBLOCK StatusFlags::O_NONBLOCK
} else { } else {

View File

@ -137,6 +137,7 @@ impl FileLike for UnixStreamSocket {
State::Connected(connected) => connected.is_nonblocking(), State::Connected(connected) => connected.is_nonblocking(),
}; };
// TODO: when we fully support O_ASYNC, return the flag
if is_nonblocking { if is_nonblocking {
StatusFlags::O_NONBLOCK StatusFlags::O_NONBLOCK
} else { } else {

View File

@ -2,8 +2,12 @@
use super::SyscallReturn; use super::SyscallReturn;
use crate::{ use crate::{
fs::{file_table::FileDesc, utils::IoctlCmd}, fs::{
file_table::FileDesc,
utils::{IoctlCmd, StatusFlags},
},
prelude::*, prelude::*,
util::read_val_from_user,
}; };
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> { pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
@ -15,6 +19,26 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
let current = current!(); let current = current!();
let file_table = current.file_table().lock(); let file_table = current.file_table().lock();
let file = file_table.get_file(fd)?; 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::<i32>(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::<i32>(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 _)) Ok(SyscallReturn::Return(res as _))
} }