mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 00:43:24 +00:00
Add dup3 syscall and fix EventFile
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
e0c6c29481
commit
8e1aeaf578
@ -312,7 +312,7 @@ provided by Linux on x86-64 architecture.
|
||||
| 289 | signalfd4 | ❌ |
|
||||
| 290 | eventfd2 | ✅ |
|
||||
| 291 | epoll_create1 | ✅ |
|
||||
| 292 | dup3 | ❌ |
|
||||
| 292 | dup3 | ✅ |
|
||||
| 293 | pipe2 | ✅ |
|
||||
| 294 | inotify_init1 | ❌ |
|
||||
| 295 | preadv | ❌ |
|
||||
|
@ -99,7 +99,7 @@ impl FileTable {
|
||||
item: Arc<dyn FileLike>,
|
||||
flags: FdFlags,
|
||||
) -> Option<Arc<dyn FileLike>> {
|
||||
let entry = FileTableEntry::new(item, FdFlags::empty());
|
||||
let entry = FileTableEntry::new(item, flags);
|
||||
let entry = self.table.put_at(fd as usize, entry);
|
||||
if entry.is_some() {
|
||||
let events = FdEvents::Close(fd);
|
||||
|
@ -15,7 +15,7 @@ use crate::syscall::{
|
||||
clone::{sys_clone, sys_clone3},
|
||||
close::sys_close,
|
||||
connect::sys_connect,
|
||||
dup::{sys_dup, sys_dup2},
|
||||
dup::{sys_dup, sys_dup2, sys_dup3},
|
||||
epoll::{sys_epoll_create, sys_epoll_create1, sys_epoll_ctl, sys_epoll_pwait, sys_epoll_wait},
|
||||
eventfd::{sys_eventfd, sys_eventfd2},
|
||||
execve::{sys_execve, sys_execveat},
|
||||
@ -264,6 +264,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
||||
SYS_ACCEPT4 = 288 => sys_accept4(args[..4]);
|
||||
SYS_EVENTFD2 = 290 => sys_eventfd2(args[..2]);
|
||||
SYS_EPOLL_CREATE1 = 291 => sys_epoll_create1(args[..1]);
|
||||
SYS_DUP3 = 292 => sys_dup3(args[..3]);
|
||||
SYS_PIPE2 = 293 => sys_pipe2(args[..2]);
|
||||
SYS_PRLIMIT64 = 302 => sys_prlimit64(args[..4]);
|
||||
SYS_GETRANDOM = 318 => sys_getrandom(args[..3]);
|
||||
|
@ -4,6 +4,7 @@ use super::SyscallReturn;
|
||||
use crate::{
|
||||
fs::file_table::{FdFlags, FileDesc},
|
||||
prelude::*,
|
||||
process::ResourceType,
|
||||
};
|
||||
|
||||
pub fn sys_dup(old_fd: FileDesc) -> Result<SyscallReturn> {
|
||||
@ -11,24 +12,55 @@ pub fn sys_dup(old_fd: FileDesc) -> Result<SyscallReturn> {
|
||||
|
||||
let current = current!();
|
||||
let mut file_table = current.file_table().lock();
|
||||
let file = file_table.get_file(old_fd)?.clone();
|
||||
// The two file descriptors do not share the close-on-exec flag.
|
||||
let new_fd = file_table.insert(file, FdFlags::empty());
|
||||
let new_fd = file_table.dup(old_fd, 0, FdFlags::empty())?;
|
||||
|
||||
Ok(SyscallReturn::Return(new_fd as _))
|
||||
}
|
||||
|
||||
pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<SyscallReturn> {
|
||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||
|
||||
if old_fd == new_fd {
|
||||
let current = current!();
|
||||
let file_table = current.file_table().lock();
|
||||
let _ = file_table.get_file(old_fd)?;
|
||||
return Ok(SyscallReturn::Return(new_fd as _));
|
||||
}
|
||||
|
||||
do_dup3(old_fd, new_fd, FdFlags::empty())
|
||||
}
|
||||
|
||||
pub fn sys_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<SyscallReturn> {
|
||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||
|
||||
let fdflag = match flags {
|
||||
0x0 => FdFlags::empty(),
|
||||
0x80000 => FdFlags::CLOEXEC,
|
||||
_ => return_errno_with_message!(Errno::EINVAL, "flags must be O_CLOEXEC or 0"),
|
||||
};
|
||||
|
||||
do_dup3(old_fd, new_fd, fdflag)
|
||||
}
|
||||
|
||||
fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: FdFlags) -> Result<SyscallReturn> {
|
||||
if old_fd == new_fd {
|
||||
return_errno!(Errno::EINVAL);
|
||||
}
|
||||
|
||||
let current = current!();
|
||||
if new_fd
|
||||
>= current
|
||||
.resource_limits()
|
||||
.lock()
|
||||
.get_rlimit(ResourceType::RLIMIT_NOFILE)
|
||||
.get_cur() as FileDesc
|
||||
{
|
||||
return_errno!(Errno::EBADF);
|
||||
}
|
||||
|
||||
let mut file_table = current.file_table().lock();
|
||||
let file = file_table.get_file(old_fd)?.clone();
|
||||
if old_fd != new_fd {
|
||||
// The two file descriptors do not share the close-on-exec flag.
|
||||
if let Some(old_file) = file_table.insert_at(new_fd, file, FdFlags::empty()) {
|
||||
// If the file descriptor `new_fd` was previously open, close it silently.
|
||||
let _ = old_file.clean_for_close();
|
||||
}
|
||||
}
|
||||
let _ = file_table.close_file(new_fd);
|
||||
let new_fd = file_table.dup(old_fd, new_fd, flags)?;
|
||||
|
||||
Ok(SyscallReturn::Return(new_fd as _))
|
||||
}
|
||||
|
@ -20,10 +20,14 @@ use crate::{
|
||||
fs::{
|
||||
file_handle::FileLike,
|
||||
file_table::{FdFlags, FileDesc},
|
||||
utils::{CreationFlags, StatusFlags},
|
||||
utils::{CreationFlags, InodeMode, InodeType, Metadata, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
process::signal::{Pauser, Pollee, Poller},
|
||||
process::{
|
||||
signal::{Pauser, Pollee, Poller},
|
||||
Gid, Uid,
|
||||
},
|
||||
time::clocks::RealTimeClock,
|
||||
};
|
||||
|
||||
pub fn sys_eventfd(init_val: u64) -> Result<SyscallReturn> {
|
||||
@ -253,4 +257,24 @@ impl FileLike for EventFile {
|
||||
) -> Option<Weak<dyn Observer<IoEvents>>> {
|
||||
self.pollee.unregister_observer(observer)
|
||||
}
|
||||
|
||||
fn metadata(&self) -> Metadata {
|
||||
let now = RealTimeClock::get().read_time();
|
||||
Metadata {
|
||||
dev: 0,
|
||||
ino: 0,
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: now,
|
||||
mtime: now,
|
||||
ctime: now,
|
||||
type_: InodeType::NamedPipe,
|
||||
mode: InodeMode::from_bits_truncate(0o200),
|
||||
nlinks: 1,
|
||||
uid: Uid::new_root(),
|
||||
gid: Gid::new_root(),
|
||||
rdev: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ TESTS ?= \
|
||||
chown_test \
|
||||
chroot_test \
|
||||
creat_test \
|
||||
dup_test \
|
||||
epoll_test \
|
||||
eventfd_test \
|
||||
fsync_test \
|
||||
|
Reference in New Issue
Block a user