mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Add sys_close_range
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
492898d1d5
commit
3e32a38316
@ -342,6 +342,7 @@ provided by Linux on x86-64 architecture.
|
||||
| 328 | pwritev2 | ✅ |
|
||||
| 332 | statx | ✅ |
|
||||
| 435 | clone3 | ✅ |
|
||||
| 436 | close_range | ✅ |
|
||||
| 439 | faccessat2 | ✅ |
|
||||
| 441 | epoll_pwait2 | ✅ |
|
||||
|
||||
|
@ -116,6 +116,11 @@ impl FileTableRefMut<'_> {
|
||||
pub(super) fn remove(&mut self) {
|
||||
*self.0 = None;
|
||||
}
|
||||
|
||||
/// Replaces the file table with a new one, returning the old one.
|
||||
pub fn replace(&mut self, new_table: Option<RwArc<FileTable>>) -> Option<RwArc<FileTable>> {
|
||||
core::mem::replace(&mut *self.0, new_table)
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait to provide the `as_thread_local` method for tasks.
|
||||
|
@ -13,7 +13,7 @@ use crate::syscall::{
|
||||
chroot::sys_chroot,
|
||||
clock_gettime::sys_clock_gettime,
|
||||
clone::{sys_clone, sys_clone3},
|
||||
close::sys_close,
|
||||
close::{sys_close, sys_close_range},
|
||||
connect::sys_connect,
|
||||
dup::{sys_dup, sys_dup3},
|
||||
epoll::{sys_epoll_create1, sys_epoll_ctl, sys_epoll_pwait, sys_epoll_pwait2},
|
||||
@ -302,6 +302,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
||||
SYS_UTIMENSAT = 412 => sys_utimensat(args[..4]);
|
||||
SYS_SEMTIMEDOP = 420 => sys_semtimedop(args[..4]);
|
||||
SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx);
|
||||
SYS_CLOSE_RANGE = 436 => sys_close_range(args[..3]);
|
||||
SYS_FACCESSAT2 = 439 => sys_faccessat2(args[..4]);
|
||||
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use crate::syscall::{
|
||||
chroot::sys_chroot,
|
||||
clock_gettime::sys_clock_gettime,
|
||||
clone::{sys_clone, sys_clone3},
|
||||
close::sys_close,
|
||||
close::{sys_close, sys_close_range},
|
||||
connect::sys_connect,
|
||||
dup::{sys_dup, sys_dup2, sys_dup3},
|
||||
epoll::{
|
||||
@ -371,6 +371,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
||||
SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]);
|
||||
SYS_STATX = 332 => sys_statx(args[..5]);
|
||||
SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx);
|
||||
SYS_CLOSE_RANGE = 436 => sys_close_range(args[..3]);
|
||||
SYS_FACCESSAT2 = 439 => sys_faccessat2(args[..4]);
|
||||
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
||||
}
|
||||
|
@ -1,7 +1,20 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use bitflags::bitflags;
|
||||
use ostd::sync::RwArc;
|
||||
|
||||
use super::SyscallReturn;
|
||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||
use crate::{
|
||||
fs::file_table::{FdFlags, FileDesc},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
bitflags! {
|
||||
struct CloseRangeFlags: u32 {
|
||||
const UNSHARE = 1 << 1;
|
||||
const CLOEXEC = 1 << 2;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||
debug!("fd = {}", fd);
|
||||
@ -29,3 +42,59 @@ pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||
// <https://man7.org/linux/man-pages/man2/close.2.html>.
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
pub fn sys_close_range(
|
||||
first: u32,
|
||||
last: u32,
|
||||
raw_flags: u32,
|
||||
ctx: &Context,
|
||||
) -> Result<SyscallReturn> {
|
||||
debug!("first = {}, last = {}, flags = {}", first, last, raw_flags);
|
||||
|
||||
if last < first {
|
||||
return_errno!(Errno::EINVAL);
|
||||
}
|
||||
|
||||
let flags = CloseRangeFlags::from_bits(raw_flags).ok_or_else(|| Error::new(Errno::EINVAL))?;
|
||||
|
||||
let original_table = ctx.thread_local.borrow_file_table().unwrap().clone();
|
||||
|
||||
let file_table = if flags.contains(CloseRangeFlags::UNSHARE) {
|
||||
let new_table = RwArc::new(original_table.get_cloned());
|
||||
let _ = ctx
|
||||
.thread_local
|
||||
.borrow_file_table_mut()
|
||||
.replace(Some(new_table.clone()));
|
||||
new_table
|
||||
} else {
|
||||
original_table
|
||||
};
|
||||
|
||||
let mut files_to_drop = Vec::new();
|
||||
|
||||
{
|
||||
let mut file_table_locked = file_table.write();
|
||||
|
||||
let table_len = file_table_locked.len() as u32;
|
||||
if first >= table_len {
|
||||
return Ok(SyscallReturn::Return(0));
|
||||
}
|
||||
let actual_last = last.min(table_len - 1);
|
||||
|
||||
for fd in first..=actual_last {
|
||||
let fd = fd as FileDesc;
|
||||
|
||||
if flags.contains(CloseRangeFlags::CLOEXEC) {
|
||||
if let Ok(entry) = file_table_locked.get_entry_mut(fd) {
|
||||
entry.set_flags(entry.flags() | FdFlags::CLOEXEC);
|
||||
}
|
||||
} else if let Some(file) = file_table_locked.close_file(fd) {
|
||||
files_to_drop.push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop(files_to_drop);
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
@ -98,6 +98,14 @@ impl<T> Drop for RwArc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> RwArc<T> {
|
||||
/// Returns the contained value by cloning it.
|
||||
pub fn get_cloned(&self) -> T {
|
||||
let guard = self.read();
|
||||
guard.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RoArc<T> {
|
||||
/// Acquires the read lock for immutable access.
|
||||
pub fn read(&self) -> RwLockReadGuard<T, PreemptDisabled> {
|
||||
|
@ -133,7 +133,7 @@ close01
|
||||
close02
|
||||
|
||||
# close_range01
|
||||
# close_range02
|
||||
close_range02
|
||||
|
||||
confstr01
|
||||
|
||||
|
Reference in New Issue
Block a user