|
@@ -1,30 +1,25 @@
|
|
|
-use core::time::Duration;
|
|
|
|
|
-
|
|
|
|
|
-use super::FromSyscallArg;
|
|
|
|
|
|
|
+use super::{FromSyscallArg, User};
|
|
|
use crate::io::IntoStream;
|
|
use crate::io::IntoStream;
|
|
|
use crate::kernel::constants::{
|
|
use crate::kernel::constants::{
|
|
|
- EBADF, EFAULT, EINVAL, ENOENT, ENOSYS, ENOTDIR, SEEK_CUR, SEEK_END, SEEK_SET, S_IFBLK, S_IFCHR,
|
|
|
|
|
|
|
+ EBADF, EFAULT, EINVAL, ENOENT, ENOSYS, ENOTDIR, SEEK_CUR, SEEK_END, SEEK_SET,
|
|
|
};
|
|
};
|
|
|
|
|
+use crate::kernel::syscall::UserMut;
|
|
|
use crate::kernel::task::Thread;
|
|
use crate::kernel::task::Thread;
|
|
|
use crate::kernel::timer::sleep;
|
|
use crate::kernel::timer::sleep;
|
|
|
use crate::kernel::vfs::filearray::FD;
|
|
use crate::kernel::vfs::filearray::FD;
|
|
|
|
|
+use crate::kernel::vfs::inode::Mode;
|
|
|
|
|
+use crate::kernel::vfs::{PollEvent, SeekOption};
|
|
|
use crate::{
|
|
use crate::{
|
|
|
io::{Buffer, BufferFill},
|
|
io::{Buffer, BufferFill},
|
|
|
kernel::{
|
|
kernel::{
|
|
|
- user::{
|
|
|
|
|
- dataflow::{CheckedUserPointer, UserBuffer, UserString},
|
|
|
|
|
- UserPointer, UserPointerMut,
|
|
|
|
|
- },
|
|
|
|
|
- vfs::{
|
|
|
|
|
- dentry::Dentry,
|
|
|
|
|
- file::{PollEvent, SeekOption},
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ user::{CheckedUserPointer, UserBuffer, UserPointer, UserPointerMut, UserString},
|
|
|
|
|
+ vfs::dentry::Dentry,
|
|
|
},
|
|
},
|
|
|
path::Path,
|
|
path::Path,
|
|
|
prelude::*,
|
|
prelude::*,
|
|
|
};
|
|
};
|
|
|
use alloc::sync::Arc;
|
|
use alloc::sync::Arc;
|
|
|
-use eonix_runtime::task::Task;
|
|
|
|
|
|
|
+use core::time::Duration;
|
|
|
use posix_types::ctypes::{Long, PtrT};
|
|
use posix_types::ctypes::{Long, PtrT};
|
|
|
use posix_types::namei::RenameFlags;
|
|
use posix_types::namei::RenameFlags;
|
|
|
use posix_types::open::{AtFlags, OpenFlags};
|
|
use posix_types::open::{AtFlags, OpenFlags};
|
|
@@ -49,7 +44,7 @@ impl FromSyscallArg for AtFlags {
|
|
|
fn dentry_from(
|
|
fn dentry_from(
|
|
|
thread: &Thread,
|
|
thread: &Thread,
|
|
|
dirfd: FD,
|
|
dirfd: FD,
|
|
|
- pathname: *const u8,
|
|
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
follow_symlink: bool,
|
|
follow_symlink: bool,
|
|
|
) -> KResult<Arc<Dentry>> {
|
|
) -> KResult<Arc<Dentry>> {
|
|
|
let path = UserString::new(pathname)?;
|
|
let path = UserString::new(pathname)?;
|
|
@@ -74,83 +69,95 @@ fn dentry_from(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_READ)]
|
|
#[eonix_macros::define_syscall(SYS_READ)]
|
|
|
-fn read(fd: FD, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn read(fd: FD, buffer: UserMut<u8>, bufsize: usize) -> KResult<usize> {
|
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
|
|
|
|
|
|
- Task::block_on(thread.files.get(fd).ok_or(EBADF)?.read(&mut buffer, None))
|
|
|
|
|
|
|
+ thread
|
|
|
|
|
+ .files
|
|
|
|
|
+ .get(fd)
|
|
|
|
|
+ .ok_or(EBADF)?
|
|
|
|
|
+ .read(&mut buffer, None)
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_PREAD64)]
|
|
#[eonix_macros::define_syscall(SYS_PREAD64)]
|
|
|
-fn pread64(fd: FD, buffer: *mut u8, bufsize: usize, offset: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn pread64(fd: FD, buffer: UserMut<u8>, bufsize: usize, offset: usize) -> KResult<usize> {
|
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
|
|
|
|
|
|
- Task::block_on(
|
|
|
|
|
- thread
|
|
|
|
|
- .files
|
|
|
|
|
- .get(fd)
|
|
|
|
|
- .ok_or(EBADF)?
|
|
|
|
|
- .read(&mut buffer, Some(offset)),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ thread
|
|
|
|
|
+ .files
|
|
|
|
|
+ .get(fd)
|
|
|
|
|
+ .ok_or(EBADF)?
|
|
|
|
|
+ .read(&mut buffer, Some(offset))
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_WRITE)]
|
|
#[eonix_macros::define_syscall(SYS_WRITE)]
|
|
|
-fn write(fd: FD, buffer: *const u8, count: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn write(fd: FD, buffer: User<u8>, count: usize) -> KResult<usize> {
|
|
|
let buffer = CheckedUserPointer::new(buffer, count)?;
|
|
let buffer = CheckedUserPointer::new(buffer, count)?;
|
|
|
let mut stream = buffer.into_stream();
|
|
let mut stream = buffer.into_stream();
|
|
|
|
|
|
|
|
- Task::block_on(thread.files.get(fd).ok_or(EBADF)?.write(&mut stream, None))
|
|
|
|
|
|
|
+ thread
|
|
|
|
|
+ .files
|
|
|
|
|
+ .get(fd)
|
|
|
|
|
+ .ok_or(EBADF)?
|
|
|
|
|
+ .write(&mut stream, None)
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_PWRITE64)]
|
|
#[eonix_macros::define_syscall(SYS_PWRITE64)]
|
|
|
-fn pwrite64(fd: FD, buffer: *const u8, count: usize, offset: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn pwrite64(fd: FD, buffer: User<u8>, count: usize, offset: usize) -> KResult<usize> {
|
|
|
let buffer = CheckedUserPointer::new(buffer, count)?;
|
|
let buffer = CheckedUserPointer::new(buffer, count)?;
|
|
|
let mut stream = buffer.into_stream();
|
|
let mut stream = buffer.into_stream();
|
|
|
|
|
|
|
|
- Task::block_on(
|
|
|
|
|
- thread
|
|
|
|
|
- .files
|
|
|
|
|
- .get(fd)
|
|
|
|
|
- .ok_or(EBADF)?
|
|
|
|
|
- .write(&mut stream, Some(offset)),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ thread
|
|
|
|
|
+ .files
|
|
|
|
|
+ .get(fd)
|
|
|
|
|
+ .ok_or(EBADF)?
|
|
|
|
|
+ .write(&mut stream, Some(offset))
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_OPENAT)]
|
|
#[eonix_macros::define_syscall(SYS_OPENAT)]
|
|
|
-fn openat(dirfd: FD, pathname: *const u8, flags: OpenFlags, mode: u32) -> KResult<FD> {
|
|
|
|
|
|
|
+async fn openat(dirfd: FD, pathname: User<u8>, flags: OpenFlags, mut mode: Mode) -> KResult<FD> {
|
|
|
let dentry = dentry_from(thread, dirfd, pathname, flags.follow_symlink())?;
|
|
let dentry = dentry_from(thread, dirfd, pathname, flags.follow_symlink())?;
|
|
|
|
|
+
|
|
|
|
|
+ let umask = *thread.fs_context.umask.lock();
|
|
|
|
|
+ mode.mask_perm(!umask.non_format_bits());
|
|
|
|
|
+
|
|
|
thread.files.open(&dentry, flags, mode)
|
|
thread.files.open(&dentry, flags, mode)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_OPEN)]
|
|
#[eonix_macros::define_syscall(SYS_OPEN)]
|
|
|
-fn open(path: *const u8, flags: OpenFlags, mode: u32) -> KResult<FD> {
|
|
|
|
|
- sys_openat(thread, FD::AT_FDCWD, path, flags, mode)
|
|
|
|
|
|
|
+async fn open(path: User<u8>, flags: OpenFlags, mode: u32) -> KResult<FD> {
|
|
|
|
|
+ sys_openat(thread, FD::AT_FDCWD, path, flags, mode).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_CLOSE)]
|
|
#[eonix_macros::define_syscall(SYS_CLOSE)]
|
|
|
-fn close(fd: FD) -> KResult<()> {
|
|
|
|
|
- thread.files.close(fd)
|
|
|
|
|
|
|
+async fn close(fd: FD) -> KResult<()> {
|
|
|
|
|
+ thread.files.close(fd).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_DUP)]
|
|
#[eonix_macros::define_syscall(SYS_DUP)]
|
|
|
-fn dup(fd: FD) -> KResult<FD> {
|
|
|
|
|
|
|
+async fn dup(fd: FD) -> KResult<FD> {
|
|
|
thread.files.dup(fd)
|
|
thread.files.dup(fd)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_DUP2)]
|
|
#[eonix_macros::define_syscall(SYS_DUP2)]
|
|
|
-fn dup2(old_fd: FD, new_fd: FD) -> KResult<FD> {
|
|
|
|
|
|
|
+async fn dup2(old_fd: FD, new_fd: FD) -> KResult<FD> {
|
|
|
thread.files.dup_to(old_fd, new_fd, OpenFlags::empty())
|
|
thread.files.dup_to(old_fd, new_fd, OpenFlags::empty())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_DUP3)]
|
|
#[eonix_macros::define_syscall(SYS_DUP3)]
|
|
|
-fn dup3(old_fd: FD, new_fd: FD, flags: OpenFlags) -> KResult<FD> {
|
|
|
|
|
- thread.files.dup_to(old_fd, new_fd, flags)
|
|
|
|
|
|
|
+async fn dup3(old_fd: FD, new_fd: FD, flags: OpenFlags) -> KResult<FD> {
|
|
|
|
|
+ thread.files.dup_to(old_fd, new_fd, flags).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_PIPE2)]
|
|
#[eonix_macros::define_syscall(SYS_PIPE2)]
|
|
|
-fn pipe2(pipe_fd: *mut [FD; 2], flags: OpenFlags) -> KResult<()> {
|
|
|
|
|
- let mut buffer = UserBuffer::new(pipe_fd as *mut u8, core::mem::size_of::<[FD; 2]>())?;
|
|
|
|
|
|
|
+async fn pipe2(pipe_fd: UserMut<[FD; 2]>, flags: OpenFlags) -> KResult<()> {
|
|
|
|
|
+ let mut buffer = UserBuffer::new(pipe_fd.cast(), core::mem::size_of::<[FD; 2]>())?;
|
|
|
let (read_fd, write_fd) = thread.files.pipe(flags)?;
|
|
let (read_fd, write_fd) = thread.files.pipe(flags)?;
|
|
|
|
|
|
|
|
buffer.copy(&[read_fd, write_fd])?.ok_or(EFAULT)
|
|
buffer.copy(&[read_fd, write_fd])?.ok_or(EFAULT)
|
|
@@ -158,13 +165,13 @@ fn pipe2(pipe_fd: *mut [FD; 2], flags: OpenFlags) -> KResult<()> {
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_PIPE)]
|
|
#[eonix_macros::define_syscall(SYS_PIPE)]
|
|
|
-fn pipe(pipe_fd: *mut [FD; 2]) -> KResult<()> {
|
|
|
|
|
- sys_pipe2(thread, pipe_fd, OpenFlags::empty())
|
|
|
|
|
|
|
+async fn pipe(pipe_fd: UserMut<[FD; 2]>) -> KResult<()> {
|
|
|
|
|
+ sys_pipe2(thread, pipe_fd, OpenFlags::empty()).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_GETDENTS)]
|
|
#[eonix_macros::define_syscall(SYS_GETDENTS)]
|
|
|
-fn getdents(fd: FD, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn getdents(fd: FD, buffer: UserMut<u8>, bufsize: usize) -> KResult<usize> {
|
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
|
|
|
|
|
|
thread.files.get(fd).ok_or(EBADF)?.getdents(&mut buffer)?;
|
|
thread.files.get(fd).ok_or(EBADF)?.getdents(&mut buffer)?;
|
|
@@ -172,10 +179,15 @@ fn getdents(fd: FD, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_GETDENTS64)]
|
|
#[eonix_macros::define_syscall(SYS_GETDENTS64)]
|
|
|
-fn getdents64(fd: FD, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn getdents64(fd: FD, buffer: UserMut<u8>, bufsize: usize) -> KResult<usize> {
|
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
|
|
|
|
|
|
- thread.files.get(fd).ok_or(EBADF)?.getdents64(&mut buffer)?;
|
|
|
|
|
|
|
+ thread
|
|
|
|
|
+ .files
|
|
|
|
|
+ .get(fd)
|
|
|
|
|
+ .ok_or(EBADF)?
|
|
|
|
|
+ .getdents64(&mut buffer)
|
|
|
|
|
+ .await?;
|
|
|
Ok(buffer.wrote())
|
|
Ok(buffer.wrote())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -184,7 +196,12 @@ fn getdents64(fd: FD, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
eonix_macros::define_syscall(SYS_NEWFSTATAT)
|
|
eonix_macros::define_syscall(SYS_NEWFSTATAT)
|
|
|
)]
|
|
)]
|
|
|
#[cfg_attr(target_arch = "x86_64", eonix_macros::define_syscall(SYS_FSTATAT64))]
|
|
#[cfg_attr(target_arch = "x86_64", eonix_macros::define_syscall(SYS_FSTATAT64))]
|
|
|
-fn newfstatat(dirfd: FD, pathname: *const u8, statbuf: *mut Stat, flags: AtFlags) -> KResult<()> {
|
|
|
|
|
|
|
+async fn newfstatat(
|
|
|
|
|
+ dirfd: FD,
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
|
|
+ statbuf: UserMut<Stat>,
|
|
|
|
|
+ flags: AtFlags,
|
|
|
|
|
+) -> KResult<()> {
|
|
|
let dentry = if flags.at_empty_path() {
|
|
let dentry = if flags.at_empty_path() {
|
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
@@ -207,23 +224,17 @@ fn newfstatat(dirfd: FD, pathname: *const u8, statbuf: *mut Stat, flags: AtFlags
|
|
|
eonix_macros::define_syscall(SYS_NEWFSTAT)
|
|
eonix_macros::define_syscall(SYS_NEWFSTAT)
|
|
|
)]
|
|
)]
|
|
|
#[cfg_attr(target_arch = "x86_64", eonix_macros::define_syscall(SYS_FSTAT64))]
|
|
#[cfg_attr(target_arch = "x86_64", eonix_macros::define_syscall(SYS_FSTAT64))]
|
|
|
-fn newfstat(fd: FD, statbuf: *mut Stat) -> KResult<()> {
|
|
|
|
|
- sys_newfstatat(
|
|
|
|
|
- thread,
|
|
|
|
|
- fd,
|
|
|
|
|
- core::ptr::null(),
|
|
|
|
|
- statbuf,
|
|
|
|
|
- AtFlags::AT_EMPTY_PATH,
|
|
|
|
|
- )
|
|
|
|
|
|
|
+async fn newfstat(fd: FD, statbuf: UserMut<Stat>) -> KResult<()> {
|
|
|
|
|
+ sys_newfstatat(thread, fd, User::null(), statbuf, AtFlags::AT_EMPTY_PATH).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_STATX)]
|
|
#[eonix_macros::define_syscall(SYS_STATX)]
|
|
|
-fn statx(
|
|
|
|
|
|
|
+async fn statx(
|
|
|
dirfd: FD,
|
|
dirfd: FD,
|
|
|
- pathname: *const u8,
|
|
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
flags: AtFlags,
|
|
flags: AtFlags,
|
|
|
mask: u32,
|
|
mask: u32,
|
|
|
- buffer: *mut StatX,
|
|
|
|
|
|
|
+ buffer: UserMut<StatX>,
|
|
|
) -> KResult<()> {
|
|
) -> KResult<()> {
|
|
|
if !flags.statx_default_sync() {
|
|
if !flags.statx_default_sync() {
|
|
|
unimplemented!("statx with no default sync flags: {:?}", flags);
|
|
unimplemented!("statx with no default sync flags: {:?}", flags);
|
|
@@ -246,9 +257,9 @@ fn statx(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_MKDIRAT)]
|
|
#[eonix_macros::define_syscall(SYS_MKDIRAT)]
|
|
|
-fn mkdirat(dirfd: FD, pathname: *const u8, mode: u32) -> KResult<()> {
|
|
|
|
|
|
|
+async fn mkdirat(dirfd: FD, pathname: User<u8>, mut mode: Mode) -> KResult<()> {
|
|
|
let umask = *thread.fs_context.umask.lock();
|
|
let umask = *thread.fs_context.umask.lock();
|
|
|
- let mode = mode & !umask & 0o777;
|
|
|
|
|
|
|
+ mode.mask_perm(!umask.non_format_bits());
|
|
|
|
|
|
|
|
let dentry = dentry_from(thread, dirfd, pathname, true)?;
|
|
let dentry = dentry_from(thread, dirfd, pathname, true)?;
|
|
|
dentry.mkdir(mode)
|
|
dentry.mkdir(mode)
|
|
@@ -256,19 +267,19 @@ fn mkdirat(dirfd: FD, pathname: *const u8, mode: u32) -> KResult<()> {
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_MKDIR)]
|
|
#[eonix_macros::define_syscall(SYS_MKDIR)]
|
|
|
-fn mkdir(pathname: *const u8, mode: u32) -> KResult<()> {
|
|
|
|
|
- sys_mkdirat(thread, FD::AT_FDCWD, pathname, mode)
|
|
|
|
|
|
|
+async fn mkdir(pathname: User<u8>, mode: u32) -> KResult<()> {
|
|
|
|
|
+ sys_mkdirat(thread, FD::AT_FDCWD, pathname, mode).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FTRUNCATE64)]
|
|
#[eonix_macros::define_syscall(SYS_FTRUNCATE64)]
|
|
|
-fn truncate64(fd: FD, length: usize) -> KResult<()> {
|
|
|
|
|
|
|
+async fn truncate64(fd: FD, length: usize) -> KResult<()> {
|
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
|
file.as_path().ok_or(EBADF)?.truncate(length)
|
|
file.as_path().ok_or(EBADF)?.truncate(length)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_TRUNCATE)]
|
|
#[eonix_macros::define_syscall(SYS_TRUNCATE)]
|
|
|
-fn truncate(pathname: *const u8, length: usize) -> KResult<()> {
|
|
|
|
|
|
|
+async fn truncate(pathname: User<u8>, length: usize) -> KResult<()> {
|
|
|
let path = UserString::new(pathname)?;
|
|
let path = UserString::new(pathname)?;
|
|
|
let path = Path::new(path.as_cstr().to_bytes())?;
|
|
let path = Path::new(path.as_cstr().to_bytes())?;
|
|
|
|
|
|
|
@@ -278,18 +289,18 @@ fn truncate(pathname: *const u8, length: usize) -> KResult<()> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_UNLINKAT)]
|
|
#[eonix_macros::define_syscall(SYS_UNLINKAT)]
|
|
|
-fn unlinkat(dirfd: FD, pathname: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
+async fn unlinkat(dirfd: FD, pathname: User<u8>) -> KResult<()> {
|
|
|
dentry_from(thread, dirfd, pathname, false)?.unlink()
|
|
dentry_from(thread, dirfd, pathname, false)?.unlink()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_UNLINK)]
|
|
#[eonix_macros::define_syscall(SYS_UNLINK)]
|
|
|
-fn unlink(pathname: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
+async fn unlink(pathname: User<u8>) -> KResult<()> {
|
|
|
sys_unlinkat(thread, FD::AT_FDCWD, pathname)
|
|
sys_unlinkat(thread, FD::AT_FDCWD, pathname)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_SYMLINKAT)]
|
|
#[eonix_macros::define_syscall(SYS_SYMLINKAT)]
|
|
|
-fn symlinkat(target: *const u8, dirfd: FD, linkpath: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
+async fn symlinkat(target: User<u8>, dirfd: FD, linkpath: User<u8>) -> KResult<()> {
|
|
|
let target = UserString::new(target)?;
|
|
let target = UserString::new(target)?;
|
|
|
let dentry = dentry_from(thread, dirfd, linkpath, false)?;
|
|
let dentry = dentry_from(thread, dirfd, linkpath, false)?;
|
|
|
|
|
|
|
@@ -298,28 +309,37 @@ fn symlinkat(target: *const u8, dirfd: FD, linkpath: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_SYMLINK)]
|
|
#[eonix_macros::define_syscall(SYS_SYMLINK)]
|
|
|
-fn symlink(target: *const u8, linkpath: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
+async fn symlink(target: User<u8>, linkpath: User<u8>) -> KResult<()> {
|
|
|
sys_symlinkat(thread, target, FD::AT_FDCWD, linkpath)
|
|
sys_symlinkat(thread, target, FD::AT_FDCWD, linkpath)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_MKNODAT)]
|
|
#[eonix_macros::define_syscall(SYS_MKNODAT)]
|
|
|
-fn mknodat(dirfd: FD, pathname: *const u8, mode: u32, dev: u32) -> KResult<()> {
|
|
|
|
|
|
|
+async fn mknodat(dirfd: FD, pathname: User<u8>, mut mode: Mode, dev: u32) -> KResult<()> {
|
|
|
|
|
+ if !mode.is_blk() && !mode.is_chr() {
|
|
|
|
|
+ return Err(EINVAL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
let dentry = dentry_from(thread, dirfd, pathname, true)?;
|
|
let dentry = dentry_from(thread, dirfd, pathname, true)?;
|
|
|
|
|
|
|
|
let umask = *thread.fs_context.umask.lock();
|
|
let umask = *thread.fs_context.umask.lock();
|
|
|
- let mode = mode & ((!umask & 0o777) | (S_IFBLK | S_IFCHR));
|
|
|
|
|
|
|
+ mode.mask_perm(!umask.non_format_bits());
|
|
|
|
|
|
|
|
dentry.mknod(mode, dev)
|
|
dentry.mknod(mode, dev)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_MKNOD)]
|
|
#[eonix_macros::define_syscall(SYS_MKNOD)]
|
|
|
-fn mknod(pathname: *const u8, mode: u32, dev: u32) -> KResult<()> {
|
|
|
|
|
- sys_mknodat(thread, FD::AT_FDCWD, pathname, mode, dev)
|
|
|
|
|
|
|
+async fn mknod(pathname: User<u8>, mode: u32, dev: u32) -> KResult<()> {
|
|
|
|
|
+ sys_mknodat(thread, FD::AT_FDCWD, pathname, mode, dev).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_READLINKAT)]
|
|
#[eonix_macros::define_syscall(SYS_READLINKAT)]
|
|
|
-fn readlinkat(dirfd: FD, pathname: *const u8, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn readlinkat(
|
|
|
|
|
+ dirfd: FD,
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
|
|
+ buffer: UserMut<u8>,
|
|
|
|
|
+ bufsize: usize,
|
|
|
|
|
+) -> KResult<usize> {
|
|
|
let dentry = dentry_from(thread, dirfd, pathname, false)?;
|
|
let dentry = dentry_from(thread, dirfd, pathname, false)?;
|
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
let mut buffer = UserBuffer::new(buffer, bufsize)?;
|
|
|
|
|
|
|
@@ -328,34 +348,40 @@ fn readlinkat(dirfd: FD, pathname: *const u8, buffer: *mut u8, bufsize: usize) -
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_READLINK)]
|
|
#[eonix_macros::define_syscall(SYS_READLINK)]
|
|
|
-fn readlink(pathname: *const u8, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
- sys_readlinkat(thread, FD::AT_FDCWD, pathname, buffer, bufsize)
|
|
|
|
|
|
|
+async fn readlink(pathname: User<u8>, buffer: UserMut<u8>, bufsize: usize) -> KResult<usize> {
|
|
|
|
|
+ sys_readlinkat(thread, FD::AT_FDCWD, pathname, buffer, bufsize).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-fn do_lseek(thread: &Thread, fd: FD, offset: u64, whence: u32) -> KResult<u64> {
|
|
|
|
|
|
|
+async fn do_lseek(thread: &Thread, fd: FD, offset: u64, whence: u32) -> KResult<u64> {
|
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
|
|
|
|
|
|
Ok(match whence {
|
|
Ok(match whence {
|
|
|
- SEEK_SET => file.seek(SeekOption::Set(offset as usize))?,
|
|
|
|
|
- SEEK_CUR => file.seek(SeekOption::Current(offset as isize))?,
|
|
|
|
|
- SEEK_END => file.seek(SeekOption::End(offset as isize))?,
|
|
|
|
|
|
|
+ SEEK_SET => file.seek(SeekOption::Set(offset as usize)).await?,
|
|
|
|
|
+ SEEK_CUR => file.seek(SeekOption::Current(offset as isize)).await?,
|
|
|
|
|
+ SEEK_END => file.seek(SeekOption::End(offset as isize)).await?,
|
|
|
_ => return Err(EINVAL),
|
|
_ => return Err(EINVAL),
|
|
|
} as u64)
|
|
} as u64)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "x86_64"))]
|
|
#[cfg(not(target_arch = "x86_64"))]
|
|
|
#[eonix_macros::define_syscall(SYS_LSEEK)]
|
|
#[eonix_macros::define_syscall(SYS_LSEEK)]
|
|
|
-fn lseek(fd: FD, offset: u64, whence: u32) -> KResult<u64> {
|
|
|
|
|
- do_lseek(thread, fd, offset, whence)
|
|
|
|
|
|
|
+async fn lseek(fd: FD, offset: u64, whence: u32) -> KResult<u64> {
|
|
|
|
|
+ do_lseek(thread, fd, offset, whence).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_LLSEEK)]
|
|
#[eonix_macros::define_syscall(SYS_LLSEEK)]
|
|
|
-fn llseek(fd: FD, offset_high: u32, offset_low: u32, result: *mut u64, whence: u32) -> KResult<()> {
|
|
|
|
|
- let mut result = UserBuffer::new(result as *mut u8, core::mem::size_of::<u64>())?;
|
|
|
|
|
|
|
+fn llseek(
|
|
|
|
|
+ fd: FD,
|
|
|
|
|
+ offset_high: u32,
|
|
|
|
|
+ offset_low: u32,
|
|
|
|
|
+ result: UserMut<u64>,
|
|
|
|
|
+ whence: u32,
|
|
|
|
|
+) -> KResult<()> {
|
|
|
|
|
+ let mut result = UserBuffer::new(result.cast(), core::mem::size_of::<u64>())?;
|
|
|
let offset = ((offset_high as u64) << 32) | (offset_low as u64);
|
|
let offset = ((offset_high as u64) << 32) | (offset_low as u64);
|
|
|
|
|
|
|
|
- let new_offset = do_lseek(thread, fd, offset, whence)?;
|
|
|
|
|
|
|
+ let new_offset = do_lseek(thread, fd, offset, whence).await?;
|
|
|
|
|
|
|
|
result.copy(&new_offset)?.ok_or(EFAULT)
|
|
result.copy(&new_offset)?.ok_or(EFAULT)
|
|
|
}
|
|
}
|
|
@@ -368,7 +394,7 @@ struct IoVec {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_READV)]
|
|
#[eonix_macros::define_syscall(SYS_READV)]
|
|
|
-fn readv(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn readv(fd: FD, iov_user: User<IoVec>, iovcnt: u32) -> KResult<usize> {
|
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
|
|
|
|
|
|
let mut iov_user = UserPointer::new(iov_user)?;
|
|
let mut iov_user = UserPointer::new(iov_user)?;
|
|
@@ -383,14 +409,16 @@ fn readv(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
Ok(IoVec {
|
|
Ok(IoVec {
|
|
|
len: Long::ZERO, ..
|
|
len: Long::ZERO, ..
|
|
|
}) => None,
|
|
}) => None,
|
|
|
- Ok(IoVec { base, len }) => Some(UserBuffer::new(base.addr() as *mut u8, len.get())),
|
|
|
|
|
|
|
+ Ok(IoVec { base, len }) => {
|
|
|
|
|
+ Some(UserBuffer::new(UserMut::with_addr(base.addr()), len.get()))
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
.collect::<KResult<Vec<_>>>()?;
|
|
.collect::<KResult<Vec<_>>>()?;
|
|
|
|
|
|
|
|
let mut tot = 0usize;
|
|
let mut tot = 0usize;
|
|
|
for mut buffer in iov_buffers.into_iter() {
|
|
for mut buffer in iov_buffers.into_iter() {
|
|
|
// TODO!!!: `readv`
|
|
// TODO!!!: `readv`
|
|
|
- let nread = Task::block_on(file.read(&mut buffer, None))?;
|
|
|
|
|
|
|
+ let nread = file.read(&mut buffer, None).await?;
|
|
|
tot += nread;
|
|
tot += nread;
|
|
|
|
|
|
|
|
if nread != buffer.total() {
|
|
if nread != buffer.total() {
|
|
@@ -402,7 +430,7 @@ fn readv(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_WRITEV)]
|
|
#[eonix_macros::define_syscall(SYS_WRITEV)]
|
|
|
-fn writev(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn writev(fd: FD, iov_user: User<IoVec>, iovcnt: u32) -> KResult<usize> {
|
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
|
|
|
|
|
|
let mut iov_user = UserPointer::new(iov_user)?;
|
|
let mut iov_user = UserPointer::new(iov_user)?;
|
|
@@ -418,7 +446,7 @@ fn writev(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
len: Long::ZERO, ..
|
|
len: Long::ZERO, ..
|
|
|
}) => None,
|
|
}) => None,
|
|
|
Ok(IoVec { base, len }) => Some(
|
|
Ok(IoVec { base, len }) => Some(
|
|
|
- CheckedUserPointer::new(base.addr() as *mut u8, len.get())
|
|
|
|
|
|
|
+ CheckedUserPointer::new(User::with_addr(base.addr()), len.get())
|
|
|
.map(|ptr| ptr.into_stream()),
|
|
.map(|ptr| ptr.into_stream()),
|
|
|
),
|
|
),
|
|
|
})
|
|
})
|
|
@@ -426,7 +454,7 @@ fn writev(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
|
|
|
|
|
let mut tot = 0usize;
|
|
let mut tot = 0usize;
|
|
|
for mut stream in iov_streams.into_iter() {
|
|
for mut stream in iov_streams.into_iter() {
|
|
|
- let nread = Task::block_on(file.write(&mut stream, None))?;
|
|
|
|
|
|
|
+ let nread = file.write(&mut stream, None).await?;
|
|
|
tot += nread;
|
|
tot += nread;
|
|
|
|
|
|
|
|
if nread == 0 || !stream.is_drained() {
|
|
if nread == 0 || !stream.is_drained() {
|
|
@@ -438,7 +466,7 @@ fn writev(fd: FD, iov_user: *const IoVec, iovcnt: u32) -> KResult<usize> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FACCESSAT)]
|
|
#[eonix_macros::define_syscall(SYS_FACCESSAT)]
|
|
|
-fn faccessat(dirfd: FD, pathname: *const u8, _mode: u32, flags: AtFlags) -> KResult<()> {
|
|
|
|
|
|
|
+async fn faccessat(dirfd: FD, pathname: User<u8>, _mode: u32, flags: AtFlags) -> KResult<()> {
|
|
|
let dentry = if flags.at_empty_path() {
|
|
let dentry = if flags.at_empty_path() {
|
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
@@ -464,12 +492,12 @@ fn faccessat(dirfd: FD, pathname: *const u8, _mode: u32, flags: AtFlags) -> KRes
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_ACCESS)]
|
|
#[eonix_macros::define_syscall(SYS_ACCESS)]
|
|
|
-fn access(pathname: *const u8, mode: u32) -> KResult<()> {
|
|
|
|
|
- sys_faccessat(thread, FD::AT_FDCWD, pathname, mode, AtFlags::empty())
|
|
|
|
|
|
|
+async fn access(pathname: User<u8>, mode: u32) -> KResult<()> {
|
|
|
|
|
+ sys_faccessat(thread, FD::AT_FDCWD, pathname, mode, AtFlags::empty()).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_SENDFILE64)]
|
|
#[eonix_macros::define_syscall(SYS_SENDFILE64)]
|
|
|
-fn sendfile64(out_fd: FD, in_fd: FD, offset: *mut u8, count: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn sendfile64(out_fd: FD, in_fd: FD, offset: UserMut<u8>, count: usize) -> KResult<usize> {
|
|
|
let in_file = thread.files.get(in_fd).ok_or(EBADF)?;
|
|
let in_file = thread.files.get(in_fd).ok_or(EBADF)?;
|
|
|
let out_file = thread.files.get(out_fd).ok_or(EBADF)?;
|
|
let out_file = thread.files.get(out_fd).ok_or(EBADF)?;
|
|
|
|
|
|
|
@@ -477,18 +505,18 @@ fn sendfile64(out_fd: FD, in_fd: FD, offset: *mut u8, count: usize) -> KResult<u
|
|
|
unimplemented!("sendfile64 with offset");
|
|
unimplemented!("sendfile64 with offset");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Task::block_on(in_file.sendfile(&out_file, count))
|
|
|
|
|
|
|
+ in_file.sendfile(&out_file, count).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_IOCTL)]
|
|
#[eonix_macros::define_syscall(SYS_IOCTL)]
|
|
|
-fn ioctl(fd: FD, request: usize, arg3: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn ioctl(fd: FD, request: usize, arg3: usize) -> KResult<usize> {
|
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd).ok_or(EBADF)?;
|
|
|
|
|
|
|
|
- file.ioctl(request, arg3)
|
|
|
|
|
|
|
+ file.ioctl(request, arg3).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FCNTL64)]
|
|
#[eonix_macros::define_syscall(SYS_FCNTL64)]
|
|
|
-fn fcntl64(fd: FD, cmd: u32, arg: usize) -> KResult<usize> {
|
|
|
|
|
|
|
+async fn fcntl64(fd: FD, cmd: u32, arg: usize) -> KResult<usize> {
|
|
|
thread.files.fcntl(fd, cmd, arg)
|
|
thread.files.fcntl(fd, cmd, arg)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -500,7 +528,12 @@ struct UserPollFd {
|
|
|
revents: u16,
|
|
revents: u16,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-fn do_poll(thread: &Thread, fds: *mut UserPollFd, nfds: u32, _timeout: u32) -> KResult<u32> {
|
|
|
|
|
|
|
+async fn do_poll(
|
|
|
|
|
+ thread: &Thread,
|
|
|
|
|
+ fds: UserMut<UserPollFd>,
|
|
|
|
|
+ nfds: u32,
|
|
|
|
|
+ _timeout: u32,
|
|
|
|
|
+) -> KResult<u32> {
|
|
|
match nfds {
|
|
match nfds {
|
|
|
0 => Ok(0),
|
|
0 => Ok(0),
|
|
|
2.. => unimplemented!("Poll with {} fds", nfds),
|
|
2.. => unimplemented!("Poll with {} fds", nfds),
|
|
@@ -513,7 +546,10 @@ fn do_poll(thread: &Thread, fds: *mut UserPollFd, nfds: u32, _timeout: u32) -> K
|
|
|
let mut fd = fds.read()?;
|
|
let mut fd = fds.read()?;
|
|
|
|
|
|
|
|
let file = thread.files.get(fd.fd).ok_or(EBADF)?;
|
|
let file = thread.files.get(fd.fd).ok_or(EBADF)?;
|
|
|
- fd.revents = Task::block_on(file.poll(PollEvent::from_bits_retain(fd.events)))?.bits();
|
|
|
|
|
|
|
+ fd.revents = file
|
|
|
|
|
+ .poll(PollEvent::from_bits_retain(fd.events))
|
|
|
|
|
+ .await?
|
|
|
|
|
+ .bits();
|
|
|
|
|
|
|
|
fds.write(fd)?;
|
|
fds.write(fd)?;
|
|
|
Ok(1)
|
|
Ok(1)
|
|
@@ -522,24 +558,24 @@ fn do_poll(thread: &Thread, fds: *mut UserPollFd, nfds: u32, _timeout: u32) -> K
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_PPOLL)]
|
|
#[eonix_macros::define_syscall(SYS_PPOLL)]
|
|
|
-fn ppoll(
|
|
|
|
|
- fds: *mut UserPollFd,
|
|
|
|
|
|
|
+async fn ppoll(
|
|
|
|
|
+ fds: UserMut<UserPollFd>,
|
|
|
nfds: u32,
|
|
nfds: u32,
|
|
|
- _timeout_ptr: *const TimeSpec,
|
|
|
|
|
- _sigmask: *const SigSet,
|
|
|
|
|
|
|
+ _timeout_ptr: User<TimeSpec>,
|
|
|
|
|
+ _sigmask: User<SigSet>,
|
|
|
) -> KResult<u32> {
|
|
) -> KResult<u32> {
|
|
|
// TODO: Implement ppoll with signal mask and timeout
|
|
// TODO: Implement ppoll with signal mask and timeout
|
|
|
- do_poll(thread, fds, nfds, 0)
|
|
|
|
|
|
|
+ do_poll(thread, fds, nfds, 0).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_PSELECT6)]
|
|
#[eonix_macros::define_syscall(SYS_PSELECT6)]
|
|
|
-fn pselect6(
|
|
|
|
|
|
|
+async fn pselect6(
|
|
|
nfds: u32,
|
|
nfds: u32,
|
|
|
- _readfds: *mut FDSet,
|
|
|
|
|
- _writefds: *mut FDSet,
|
|
|
|
|
- _exceptfds: *mut FDSet,
|
|
|
|
|
- timeout: *mut TimeSpec,
|
|
|
|
|
- _sigmask: *const (),
|
|
|
|
|
|
|
+ _readfds: UserMut<FDSet>,
|
|
|
|
|
+ _writefds: UserMut<FDSet>,
|
|
|
|
|
+ _exceptfds: UserMut<FDSet>,
|
|
|
|
|
+ timeout: UserMut<TimeSpec>,
|
|
|
|
|
+ _sigmask: User<()>,
|
|
|
) -> KResult<usize> {
|
|
) -> KResult<usize> {
|
|
|
// According to [pthread6(2)](https://linux.die.net/man/2/pselect6):
|
|
// According to [pthread6(2)](https://linux.die.net/man/2/pselect6):
|
|
|
// Some code calls select() with all three sets empty, nfds zero, and
|
|
// Some code calls select() with all three sets empty, nfds zero, and
|
|
@@ -550,11 +586,11 @@ fn pselect6(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
let timeout = UserPointerMut::new(timeout)?;
|
|
let timeout = UserPointerMut::new(timeout)?;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Read here to check for invalid pointers.
|
|
// Read here to check for invalid pointers.
|
|
|
let _timeout_value = timeout.read()?;
|
|
let _timeout_value = timeout.read()?;
|
|
|
|
|
|
|
|
- Task::block_on(sleep(Duration::from_millis(10)));
|
|
|
|
|
|
|
+ sleep(Duration::from_millis(10)).await;
|
|
|
|
|
|
|
|
timeout.write(TimeSpec {
|
|
timeout.write(TimeSpec {
|
|
|
tv_sec: 0,
|
|
tv_sec: 0,
|
|
@@ -566,12 +602,18 @@ fn pselect6(
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_POLL)]
|
|
#[eonix_macros::define_syscall(SYS_POLL)]
|
|
|
-fn poll(fds: *mut UserPollFd, nfds: u32, timeout: u32) -> KResult<u32> {
|
|
|
|
|
- do_poll(thread, fds, nfds, timeout)
|
|
|
|
|
|
|
+async fn poll(fds: UserMut<UserPollFd>, nfds: u32, timeout: u32) -> KResult<u32> {
|
|
|
|
|
+ do_poll(thread, fds, nfds, timeout).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FCHOWNAT)]
|
|
#[eonix_macros::define_syscall(SYS_FCHOWNAT)]
|
|
|
-fn fchownat(dirfd: FD, pathname: *const u8, uid: u32, gid: u32, flags: AtFlags) -> KResult<()> {
|
|
|
|
|
|
|
+async fn fchownat(
|
|
|
|
|
+ dirfd: FD,
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
|
|
+ uid: u32,
|
|
|
|
|
+ gid: u32,
|
|
|
|
|
+ flags: AtFlags,
|
|
|
|
|
+) -> KResult<()> {
|
|
|
let dentry = dentry_from(thread, dirfd, pathname, !flags.no_follow())?;
|
|
let dentry = dentry_from(thread, dirfd, pathname, !flags.no_follow())?;
|
|
|
if !dentry.is_valid() {
|
|
if !dentry.is_valid() {
|
|
|
return Err(ENOENT);
|
|
return Err(ENOENT);
|
|
@@ -581,7 +623,7 @@ fn fchownat(dirfd: FD, pathname: *const u8, uid: u32, gid: u32, flags: AtFlags)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FCHMODAT)]
|
|
#[eonix_macros::define_syscall(SYS_FCHMODAT)]
|
|
|
-fn fchmodat(dirfd: FD, pathname: *const u8, mode: u32, flags: AtFlags) -> KResult<()> {
|
|
|
|
|
|
|
+async fn fchmodat(dirfd: FD, pathname: User<u8>, mode: Mode, flags: AtFlags) -> KResult<()> {
|
|
|
let dentry = if flags.at_empty_path() {
|
|
let dentry = if flags.at_empty_path() {
|
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
let file = thread.files.get(dirfd).ok_or(EBADF)?;
|
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
file.as_path().ok_or(EBADF)?.clone()
|
|
@@ -597,15 +639,15 @@ fn fchmodat(dirfd: FD, pathname: *const u8, mode: u32, flags: AtFlags) -> KResul
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_FCHMOD)]
|
|
#[eonix_macros::define_syscall(SYS_FCHMOD)]
|
|
|
-fn chmod(pathname: *const u8, mode: u32) -> KResult<()> {
|
|
|
|
|
- sys_fchmodat(thread, FD::AT_FDCWD, pathname, mode, AtFlags::empty())
|
|
|
|
|
|
|
+async fn chmod(pathname: User<u8>, mode: Mode) -> KResult<()> {
|
|
|
|
|
+ sys_fchmodat(thread, FD::AT_FDCWD, pathname, mode, AtFlags::empty()).await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_UTIMENSAT)]
|
|
#[eonix_macros::define_syscall(SYS_UTIMENSAT)]
|
|
|
-fn utimensat(
|
|
|
|
|
|
|
+async fn utimensat(
|
|
|
dirfd: FD,
|
|
dirfd: FD,
|
|
|
- pathname: *const u8,
|
|
|
|
|
- times: *const TimeSpec,
|
|
|
|
|
|
|
+ pathname: User<u8>,
|
|
|
|
|
+ times: User<TimeSpec>,
|
|
|
flags: AtFlags,
|
|
flags: AtFlags,
|
|
|
) -> KResult<()> {
|
|
) -> KResult<()> {
|
|
|
let dentry = if flags.at_empty_path() {
|
|
let dentry = if flags.at_empty_path() {
|
|
@@ -632,11 +674,11 @@ fn utimensat(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[eonix_macros::define_syscall(SYS_RENAMEAT2)]
|
|
#[eonix_macros::define_syscall(SYS_RENAMEAT2)]
|
|
|
-fn renameat2(
|
|
|
|
|
|
|
+async fn renameat2(
|
|
|
old_dirfd: FD,
|
|
old_dirfd: FD,
|
|
|
- old_pathname: *const u8,
|
|
|
|
|
|
|
+ old_pathname: User<u8>,
|
|
|
new_dirfd: FD,
|
|
new_dirfd: FD,
|
|
|
- new_pathname: *const u8,
|
|
|
|
|
|
|
+ new_pathname: User<u8>,
|
|
|
flags: u32,
|
|
flags: u32,
|
|
|
) -> KResult<()> {
|
|
) -> KResult<()> {
|
|
|
let flags = RenameFlags::from_bits(flags).ok_or(EINVAL)?;
|
|
let flags = RenameFlags::from_bits(flags).ok_or(EINVAL)?;
|
|
@@ -654,7 +696,7 @@ fn renameat2(
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
#[eonix_macros::define_syscall(SYS_RENAME)]
|
|
#[eonix_macros::define_syscall(SYS_RENAME)]
|
|
|
-fn rename(old_pathname: *const u8, new_pathname: *const u8) -> KResult<()> {
|
|
|
|
|
|
|
+async fn rename(old_pathname: User<u8>, new_pathname: User<u8>) -> KResult<()> {
|
|
|
sys_renameat2(
|
|
sys_renameat2(
|
|
|
thread,
|
|
thread,
|
|
|
FD::AT_FDCWD,
|
|
FD::AT_FDCWD,
|
|
@@ -663,6 +705,7 @@ fn rename(old_pathname: *const u8, new_pathname: *const u8) -> KResult<()> {
|
|
|
new_pathname,
|
|
new_pathname,
|
|
|
0,
|
|
0,
|
|
|
)
|
|
)
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub fn keep_alive() {}
|
|
pub fn keep_alive() {}
|