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 | ✅ |
|
| 328 | pwritev2 | ✅ |
|
||||||
| 332 | statx | ✅ |
|
| 332 | statx | ✅ |
|
||||||
| 435 | clone3 | ✅ |
|
| 435 | clone3 | ✅ |
|
||||||
|
| 436 | close_range | ✅ |
|
||||||
| 439 | faccessat2 | ✅ |
|
| 439 | faccessat2 | ✅ |
|
||||||
| 441 | epoll_pwait2 | ✅ |
|
| 441 | epoll_pwait2 | ✅ |
|
||||||
|
|
||||||
|
@ -116,6 +116,11 @@ impl FileTableRefMut<'_> {
|
|||||||
pub(super) fn remove(&mut self) {
|
pub(super) fn remove(&mut self) {
|
||||||
*self.0 = None;
|
*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.
|
/// A trait to provide the `as_thread_local` method for tasks.
|
||||||
|
@ -13,7 +13,7 @@ use crate::syscall::{
|
|||||||
chroot::sys_chroot,
|
chroot::sys_chroot,
|
||||||
clock_gettime::sys_clock_gettime,
|
clock_gettime::sys_clock_gettime,
|
||||||
clone::{sys_clone, sys_clone3},
|
clone::{sys_clone, sys_clone3},
|
||||||
close::sys_close,
|
close::{sys_close, sys_close_range},
|
||||||
connect::sys_connect,
|
connect::sys_connect,
|
||||||
dup::{sys_dup, sys_dup3},
|
dup::{sys_dup, sys_dup3},
|
||||||
epoll::{sys_epoll_create1, sys_epoll_ctl, sys_epoll_pwait, sys_epoll_pwait2},
|
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_UTIMENSAT = 412 => sys_utimensat(args[..4]);
|
||||||
SYS_SEMTIMEDOP = 420 => sys_semtimedop(args[..4]);
|
SYS_SEMTIMEDOP = 420 => sys_semtimedop(args[..4]);
|
||||||
SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx);
|
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_FACCESSAT2 = 439 => sys_faccessat2(args[..4]);
|
||||||
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::syscall::{
|
|||||||
chroot::sys_chroot,
|
chroot::sys_chroot,
|
||||||
clock_gettime::sys_clock_gettime,
|
clock_gettime::sys_clock_gettime,
|
||||||
clone::{sys_clone, sys_clone3},
|
clone::{sys_clone, sys_clone3},
|
||||||
close::sys_close,
|
close::{sys_close, sys_close_range},
|
||||||
connect::sys_connect,
|
connect::sys_connect,
|
||||||
dup::{sys_dup, sys_dup2, sys_dup3},
|
dup::{sys_dup, sys_dup2, sys_dup3},
|
||||||
epoll::{
|
epoll::{
|
||||||
@ -371,6 +371,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]);
|
SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]);
|
||||||
SYS_STATX = 332 => sys_statx(args[..5]);
|
SYS_STATX = 332 => sys_statx(args[..5]);
|
||||||
SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx);
|
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_FACCESSAT2 = 439 => sys_faccessat2(args[..4]);
|
||||||
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
SYS_EPOLL_PWAIT2 = 441 => sys_epoll_pwait2(args[..5]);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use bitflags::bitflags;
|
||||||
|
use ostd::sync::RwArc;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
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> {
|
pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
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>.
|
// <https://man7.org/linux/man-pages/man2/close.2.html>.
|
||||||
Ok(SyscallReturn::Return(0))
|
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> {
|
impl<T> RoArc<T> {
|
||||||
/// Acquires the read lock for immutable access.
|
/// Acquires the read lock for immutable access.
|
||||||
pub fn read(&self) -> RwLockReadGuard<T, PreemptDisabled> {
|
pub fn read(&self) -> RwLockReadGuard<T, PreemptDisabled> {
|
||||||
|
@ -133,7 +133,7 @@ close01
|
|||||||
close02
|
close02
|
||||||
|
|
||||||
# close_range01
|
# close_range01
|
||||||
# close_range02
|
close_range02
|
||||||
|
|
||||||
confstr01
|
confstr01
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user