mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Replace a myriad of current!
usages via Context
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
f84d328956
commit
9200538175
@ -14,11 +14,11 @@ pub fn sys_accept(
|
|||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
||||||
|
|
||||||
let fd = do_accept(sockfd, sockaddr_ptr, addrlen_ptr, Flags::empty())?;
|
let fd = do_accept(sockfd, sockaddr_ptr, addrlen_ptr, Flags::empty(), ctx)?;
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ pub fn sys_accept4(
|
|||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
trace!("raw flags = 0x{:x}", flags);
|
trace!("raw flags = 0x{:x}", flags);
|
||||||
let flags = Flags::from_bits_truncate(flags);
|
let flags = Flags::from_bits_truncate(flags);
|
||||||
@ -36,7 +36,7 @@ pub fn sys_accept4(
|
|||||||
sockfd, sockaddr_ptr, addrlen_ptr, flags
|
sockfd, sockaddr_ptr, addrlen_ptr, flags
|
||||||
);
|
);
|
||||||
|
|
||||||
let fd = do_accept(sockfd, sockaddr_ptr, addrlen_ptr, flags)?;
|
let fd = do_accept(sockfd, sockaddr_ptr, addrlen_ptr, flags, ctx)?;
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +45,7 @@ fn do_accept(
|
|||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<FileDesc> {
|
) -> Result<FileDesc> {
|
||||||
let (connected_socket, socket_addr) = {
|
let (connected_socket, socket_addr) = {
|
||||||
let socket = get_socket_from_fd(sockfd)?;
|
let socket = get_socket_from_fd(sockfd)?;
|
||||||
@ -66,8 +67,7 @@ fn do_accept(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let fd = {
|
let fd = {
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
file_table.insert(connected_socket, fd_flags)
|
file_table.insert(connected_socket, fd_flags)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,20 +14,20 @@ pub fn sys_faccessat(
|
|||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
path_ptr: Vaddr,
|
path_ptr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}",
|
"faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}",
|
||||||
dirfd, path_ptr, mode
|
dirfd, path_ptr, mode
|
||||||
);
|
);
|
||||||
|
|
||||||
do_faccessat(dirfd, path_ptr, mode, 0)
|
do_faccessat(dirfd, path_ptr, mode, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_access(path_ptr: Vaddr, mode: u16, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_access(path_ptr: Vaddr, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode);
|
debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode);
|
||||||
|
|
||||||
do_faccessat(AT_FDCWD, path_ptr, mode, 0)
|
do_faccessat(AT_FDCWD, path_ptr, mode, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@ -53,6 +53,7 @@ pub fn do_faccessat(
|
|||||||
path_ptr: Vaddr,
|
path_ptr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
flags: i32,
|
flags: i32,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let mode = AccessMode::from_bits(mode)
|
let mode = AccessMode::from_bits(mode)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid mode"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid mode"))?;
|
||||||
@ -65,11 +66,10 @@ pub fn do_faccessat(
|
|||||||
dirfd, path, mode, flags
|
dirfd, path, mode, flags
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
let fs = current.fs().read();
|
let fs = ctx.process.fs().read();
|
||||||
if flags.contains(FaccessatFlags::AT_SYMLINK_NOFOLLOW) {
|
if flags.contains(FaccessatFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
fs.lookup_no_follow(&fs_path)?
|
fs.lookup_no_follow(&fs_path)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,11 +5,10 @@ use core::time::Duration;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, time::timer::Timeout};
|
use crate::{prelude::*, time::timer::Timeout};
|
||||||
|
|
||||||
pub fn sys_alarm(seconds: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_alarm(seconds: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("seconds = {}", seconds);
|
debug!("seconds = {}", seconds);
|
||||||
|
|
||||||
let current = current!();
|
let alarm_timer = ctx.process.timer_manager().alarm_timer();
|
||||||
let alarm_timer = current.timer_manager().alarm_timer();
|
|
||||||
|
|
||||||
let remaining = alarm_timer.remain();
|
let remaining = alarm_timer.remain();
|
||||||
let mut remaining_secs = remaining.as_secs();
|
let mut remaining_secs = remaining.as_secs();
|
||||||
|
@ -3,15 +3,14 @@
|
|||||||
use crate::{prelude::*, syscall::SyscallReturn};
|
use crate::{prelude::*, syscall::SyscallReturn};
|
||||||
|
|
||||||
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
||||||
pub fn sys_brk(heap_end: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_brk(heap_end: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let new_heap_end = if heap_end == 0 {
|
let new_heap_end = if heap_end == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(heap_end as usize)
|
Some(heap_end as usize)
|
||||||
};
|
};
|
||||||
debug!("new heap end = {:x?}", heap_end);
|
debug!("new heap end = {:x?}", heap_end);
|
||||||
let current = current!();
|
let user_heap = ctx.process.heap();
|
||||||
let user_heap = current.heap();
|
|
||||||
let new_heap_end = user_heap.brk(new_heap_end)?;
|
let new_heap_end = user_heap.brk(new_heap_end)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(new_heap_end as _))
|
Ok(SyscallReturn::Return(new_heap_end as _))
|
||||||
|
@ -7,12 +7,11 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chdir(path_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_chdir(path_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
let current = current!();
|
let mut fs = ctx.process.fs().write();
|
||||||
let mut fs = current.fs().write();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
@ -28,12 +27,11 @@ pub fn sys_chdir(path_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_fchdir(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fchdir(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let file_table = current.file_table().lock();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
let inode_handle = file
|
let inode_handle = file
|
||||||
.downcast_ref::<InodeHandle>()
|
.downcast_ref::<InodeHandle>()
|
||||||
@ -43,6 +41,6 @@ pub fn sys_fchdir(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
if dentry.type_() != InodeType::Dir {
|
if dentry.type_() != InodeType::Dir {
|
||||||
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
|
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
|
||||||
}
|
}
|
||||||
current.fs().write().set_cwd(dentry);
|
ctx.process.fs().write().set_cwd(dentry);
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,10 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchmod(fd: FileDesc, mode: u16, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, mode = 0o{:o}", fd, mode);
|
debug!("fd = {}, mode = 0o{:o}", fd, mode);
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
file.set_mode(InodeMode::from_bits_truncate(mode))?;
|
file.set_mode(InodeMode::from_bits_truncate(mode))?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
@ -30,19 +29,18 @@ pub fn sys_fchmodat(
|
|||||||
path_ptr: Vaddr,
|
path_ptr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
/* flags: u32, */
|
/* flags: u32, */
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,);
|
debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
dentry.set_mode(InodeMode::from_bits_truncate(mode))?;
|
dentry.set_mode(InodeMode::from_bits_truncate(mode))?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
process::{Gid, Uid},
|
process::{Gid, Uid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, uid = {}, gid = {}", fd, uid, gid);
|
debug!("fd = {}, uid = {}, gid = {}", fd, uid, gid);
|
||||||
|
|
||||||
let uid = to_optional_id(uid, Uid::new)?;
|
let uid = to_optional_id(uid, Uid::new)?;
|
||||||
@ -20,8 +20,7 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, _ctx: &Context) -> Result<Sy
|
|||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
if let Some(uid) = uid {
|
if let Some(uid) = uid {
|
||||||
file.set_owner(uid)?;
|
file.set_owner(uid)?;
|
||||||
@ -76,11 +75,10 @@ pub fn sys_fchownat(
|
|||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
let fs = current.fs().read();
|
let fs = ctx.process.fs().read();
|
||||||
if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) {
|
if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
fs.lookup_no_follow(&fs_path)?
|
fs.lookup_no_follow(&fs_path)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,12 +7,11 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chroot(path_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_chroot(path_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
let current = current!();
|
let mut fs = ctx.process.fs().write();
|
||||||
let mut fs = current.fs().write();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
|
@ -22,11 +22,11 @@ use crate::{
|
|||||||
pub fn sys_clock_gettime(
|
pub fn sys_clock_gettime(
|
||||||
clockid: clockid_t,
|
clockid: clockid_t,
|
||||||
timespec_addr: Vaddr,
|
timespec_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("clockid = {:?}", clockid);
|
debug!("clockid = {:?}", clockid);
|
||||||
|
|
||||||
let time_duration = read_clock(clockid)?;
|
let time_duration = read_clock(clockid, ctx)?;
|
||||||
|
|
||||||
let timespec = timespec_t::from(time_duration);
|
let timespec = timespec_t::from(time_duration);
|
||||||
CurrentUserSpace::get().write_val(timespec_addr, ×pec)?;
|
CurrentUserSpace::get().write_val(timespec_addr, ×pec)?;
|
||||||
@ -109,7 +109,7 @@ pub enum DynamicClockType {
|
|||||||
/// Reads the time of a clock specified by the input clock ID.
|
/// Reads the time of a clock specified by the input clock ID.
|
||||||
///
|
///
|
||||||
/// If the clock ID does not support, this function will return `Err`.
|
/// If the clock ID does not support, this function will return `Err`.
|
||||||
pub fn read_clock(clockid: clockid_t) -> Result<Duration> {
|
pub fn read_clock(clockid: clockid_t, ctx: &Context) -> Result<Duration> {
|
||||||
if clockid >= 0 {
|
if clockid >= 0 {
|
||||||
let clock_id = ClockId::try_from(clockid)?;
|
let clock_id = ClockId::try_from(clockid)?;
|
||||||
match clock_id {
|
match clock_id {
|
||||||
@ -119,14 +119,8 @@ pub fn read_clock(clockid: clockid_t) -> Result<Duration> {
|
|||||||
ClockId::CLOCK_REALTIME_COARSE => Ok(RealTimeCoarseClock::get().read_time()),
|
ClockId::CLOCK_REALTIME_COARSE => Ok(RealTimeCoarseClock::get().read_time()),
|
||||||
ClockId::CLOCK_MONOTONIC_COARSE => Ok(MonotonicCoarseClock::get().read_time()),
|
ClockId::CLOCK_MONOTONIC_COARSE => Ok(MonotonicCoarseClock::get().read_time()),
|
||||||
ClockId::CLOCK_BOOTTIME => Ok(BootTimeClock::get().read_time()),
|
ClockId::CLOCK_BOOTTIME => Ok(BootTimeClock::get().read_time()),
|
||||||
ClockId::CLOCK_PROCESS_CPUTIME_ID => {
|
ClockId::CLOCK_PROCESS_CPUTIME_ID => Ok(ctx.process.prof_clock().read_time()),
|
||||||
let process = current!();
|
ClockId::CLOCK_THREAD_CPUTIME_ID => Ok(ctx.posix_thread.prof_clock().read_time()),
|
||||||
Ok(process.prof_clock().read_time())
|
|
||||||
}
|
|
||||||
ClockId::CLOCK_THREAD_CPUTIME_ID => {
|
|
||||||
let thread = current_thread!();
|
|
||||||
Ok(thread.as_posix_thread().unwrap().prof_clock().read_time())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let dynamic_clockid_info = DynamicClockIdInfo::try_from(clockid)?;
|
let dynamic_clockid_info = DynamicClockIdInfo::try_from(clockid)?;
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let _ = file_table.get_file(fd)?;
|
let _ = file_table.get_file(fd)?;
|
||||||
file_table.close_file(fd).unwrap()
|
file_table.close_file(fd).unwrap()
|
||||||
};
|
};
|
||||||
|
@ -7,34 +7,32 @@ use crate::{
|
|||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_dup(old_fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_dup(old_fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}", old_fd);
|
debug!("old_fd = {}", old_fd);
|
||||||
|
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let new_fd = file_table.dup(old_fd, 0, FdFlags::empty())?;
|
let new_fd = file_table.dup(old_fd, 0, FdFlags::empty())?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||||
|
|
||||||
if old_fd == new_fd {
|
if old_fd == new_fd {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let _ = file_table.get_file(old_fd)?;
|
let _ = file_table.get_file(old_fd)?;
|
||||||
return Ok(SyscallReturn::Return(new_fd as _));
|
return Ok(SyscallReturn::Return(new_fd as _));
|
||||||
}
|
}
|
||||||
|
|
||||||
do_dup3(old_fd, new_fd, FdFlags::empty())
|
do_dup3(old_fd, new_fd, FdFlags::empty(), ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_dup3(
|
pub fn sys_dup3(
|
||||||
old_fd: FileDesc,
|
old_fd: FileDesc,
|
||||||
new_fd: FileDesc,
|
new_fd: FileDesc,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||||
|
|
||||||
@ -44,15 +42,20 @@ pub fn sys_dup3(
|
|||||||
_ => return_errno_with_message!(Errno::EINVAL, "flags must be O_CLOEXEC or 0"),
|
_ => return_errno_with_message!(Errno::EINVAL, "flags must be O_CLOEXEC or 0"),
|
||||||
};
|
};
|
||||||
|
|
||||||
do_dup3(old_fd, new_fd, fdflag)
|
do_dup3(old_fd, new_fd, fdflag, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: FdFlags) -> Result<SyscallReturn> {
|
fn do_dup3(
|
||||||
|
old_fd: FileDesc,
|
||||||
|
new_fd: FileDesc,
|
||||||
|
flags: FdFlags,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
if old_fd == new_fd {
|
if old_fd == new_fd {
|
||||||
return_errno!(Errno::EINVAL);
|
return_errno!(Errno::EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current!();
|
let current = ctx.process;
|
||||||
if new_fd
|
if new_fd
|
||||||
>= current
|
>= current
|
||||||
.resource_limits()
|
.resource_limits()
|
||||||
|
@ -21,7 +21,7 @@ pub fn sys_epoll_create(size: i32, ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
sys_epoll_create1(0, ctx)
|
sys_epoll_create1(0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_epoll_create1(flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_epoll_create1(flags: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("flags = 0x{:x}", flags);
|
debug!("flags = 0x{:x}", flags);
|
||||||
|
|
||||||
let fd_flags = {
|
let fd_flags = {
|
||||||
@ -37,9 +37,8 @@ pub fn sys_epoll_create1(flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let epoll_file: Arc<EpollFile> = EpollFile::new();
|
let epoll_file: Arc<EpollFile> = EpollFile::new();
|
||||||
let mut file_table = current.file_table().lock();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let fd = file_table.insert(epoll_file, fd_flags);
|
let fd = file_table.insert(epoll_file, fd_flags);
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
@ -49,7 +48,7 @@ pub fn sys_epoll_ctl(
|
|||||||
op: i32,
|
op: i32,
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
event_addr: Vaddr,
|
event_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, op = {}, fd = {}, event_addr = 0x{:x}",
|
"epfd = {}, op = {}, fd = {}, event_addr = 0x{:x}",
|
||||||
@ -77,9 +76,8 @@ pub fn sys_epoll_ctl(
|
|||||||
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
|
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let file = {
|
let file = {
|
||||||
let file_table = current.file_table().lock();
|
let file_table = ctx.process.file_table().lock();
|
||||||
file_table.get_file(epfd)?.clone()
|
file_table.get_file(epfd)?.clone()
|
||||||
};
|
};
|
||||||
let epoll_file = file
|
let epoll_file = file
|
||||||
@ -90,7 +88,12 @@ pub fn sys_epoll_ctl(
|
|||||||
Ok(SyscallReturn::Return(0 as _))
|
Ok(SyscallReturn::Return(0 as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_epoll_wait(epfd: FileDesc, max_events: i32, timeout: i32) -> Result<Vec<EpollEvent>> {
|
fn do_epoll_wait(
|
||||||
|
epfd: FileDesc,
|
||||||
|
max_events: i32,
|
||||||
|
timeout: i32,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<Vec<EpollEvent>> {
|
||||||
let max_events = {
|
let max_events = {
|
||||||
if max_events <= 0 {
|
if max_events <= 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "max_events is not positive");
|
return_errno_with_message!(Errno::EINVAL, "max_events is not positive");
|
||||||
@ -103,8 +106,7 @@ fn do_epoll_wait(epfd: FileDesc, max_events: i32, timeout: i32) -> Result<Vec<Ep
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let epoll_file = file_table
|
let epoll_file = file_table
|
||||||
.get_file(epfd)?
|
.get_file(epfd)?
|
||||||
.downcast_ref::<EpollFile>()
|
.downcast_ref::<EpollFile>()
|
||||||
@ -129,14 +131,14 @@ pub fn sys_epoll_wait(
|
|||||||
events_addr: Vaddr,
|
events_addr: Vaddr,
|
||||||
max_events: i32,
|
max_events: i32,
|
||||||
timeout: i32,
|
timeout: i32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}",
|
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}",
|
||||||
epfd, events_addr, max_events, timeout
|
epfd, events_addr, max_events, timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
let epoll_events = do_epoll_wait(epfd, max_events, timeout)?;
|
let epoll_events = do_epoll_wait(epfd, max_events, timeout, ctx)?;
|
||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
let mut write_addr = events_addr;
|
let mut write_addr = events_addr;
|
||||||
@ -184,7 +186,7 @@ pub fn sys_epoll_pwait(
|
|||||||
timeout: i32,
|
timeout: i32,
|
||||||
sigmask: Vaddr,
|
sigmask: Vaddr,
|
||||||
sigset_size: usize,
|
sigset_size: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}, sigmask = 0x{:x}, sigset_size = {}",
|
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}, sigmask = 0x{:x}, sigset_size = {}",
|
||||||
@ -197,7 +199,7 @@ pub fn sys_epoll_pwait(
|
|||||||
|
|
||||||
let old_sig_mask_value = set_signal_mask(sigmask)?;
|
let old_sig_mask_value = set_signal_mask(sigmask)?;
|
||||||
|
|
||||||
let ready_events = match do_epoll_wait(epfd, max_events, timeout) {
|
let ready_events = match do_epoll_wait(epfd, max_events, timeout, ctx) {
|
||||||
Ok(events) => {
|
Ok(events) => {
|
||||||
restore_signal_mask(old_sig_mask_value);
|
restore_signal_mask(old_sig_mask_value);
|
||||||
events
|
events
|
||||||
|
@ -30,30 +30,29 @@ use crate::{
|
|||||||
time::clocks::RealTimeClock,
|
time::clocks::RealTimeClock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_eventfd(init_val: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_eventfd(init_val: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("init_val = 0x{:x}", init_val);
|
debug!("init_val = 0x{:x}", init_val);
|
||||||
|
|
||||||
let fd = do_sys_eventfd2(init_val, Flags::empty());
|
let fd = do_sys_eventfd2(init_val, Flags::empty(), ctx);
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_eventfd2(init_val: u64, flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_eventfd2(init_val: u64, flags: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
trace!("raw flags = {}", flags);
|
trace!("raw flags = {}", flags);
|
||||||
let flags = Flags::from_bits(flags)
|
let flags = Flags::from_bits(flags)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown flags"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown flags"))?;
|
||||||
debug!("init_val = 0x{:x}, flags = {:?}", init_val, flags);
|
debug!("init_val = 0x{:x}, flags = {:?}", init_val, flags);
|
||||||
|
|
||||||
let fd = do_sys_eventfd2(init_val, flags);
|
let fd = do_sys_eventfd2(init_val, flags, ctx);
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_sys_eventfd2(init_val: u64, flags: Flags) -> FileDesc {
|
fn do_sys_eventfd2(init_val: u64, flags: Flags, ctx: &Context) -> FileDesc {
|
||||||
let event_file = EventFile::new(init_val, flags);
|
let event_file = EventFile::new(init_val, flags);
|
||||||
let fd = {
|
let fd = {
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let fd_flags = if flags.contains(Flags::EFD_CLOEXEC) {
|
let fd_flags = if flags.contains(Flags::EFD_CLOEXEC) {
|
||||||
FdFlags::CLOEXEC
|
FdFlags::CLOEXEC
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,7 +28,7 @@ pub fn sys_execve(
|
|||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let elf_file = {
|
let elf_file = {
|
||||||
let executable_path = read_filename(filename_ptr)?;
|
let executable_path = read_filename(filename_ptr)?;
|
||||||
lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty())?
|
lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty(), ctx)?
|
||||||
};
|
};
|
||||||
|
|
||||||
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
||||||
@ -47,7 +47,7 @@ pub fn sys_execveat(
|
|||||||
let elf_file = {
|
let elf_file = {
|
||||||
let flags = OpenFlags::from_bits_truncate(flags);
|
let flags = OpenFlags::from_bits_truncate(flags);
|
||||||
let filename = read_filename(filename_ptr)?;
|
let filename = read_filename(filename_ptr)?;
|
||||||
lookup_executable_file(dfd, filename, flags)?
|
lookup_executable_file(dfd, filename, flags, ctx)?
|
||||||
};
|
};
|
||||||
|
|
||||||
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
||||||
@ -58,9 +58,9 @@ fn lookup_executable_file(
|
|||||||
dfd: FileDesc,
|
dfd: FileDesc,
|
||||||
filename: String,
|
filename: String,
|
||||||
flags: OpenFlags,
|
flags: OpenFlags,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<Arc<Dentry>> {
|
) -> Result<Arc<Dentry>> {
|
||||||
let current = current!();
|
let fs_resolver = ctx.process.fs().read();
|
||||||
let fs_resolver = current.fs().read();
|
|
||||||
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
|
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
|
||||||
fs_resolver.lookup_from_fd(dfd)
|
fs_resolver.lookup_from_fd(dfd)
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,18 +12,17 @@ pub fn sys_fallocate(
|
|||||||
mode: u64,
|
mode: u64,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
len: i64,
|
len: i64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, mode = {}, offset = {}, len = {}",
|
"fd = {}, mode = {}, offset = {}, len = {}",
|
||||||
fd, mode, offset, len
|
fd, mode, offset, len
|
||||||
);
|
);
|
||||||
|
|
||||||
check_offset_and_len(offset, len)?;
|
check_offset_and_len(offset, len, ctx)?;
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ pub fn sys_fallocate(
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_offset_and_len(offset: i64, len: i64) -> Result<()> {
|
fn check_offset_and_len(offset: i64, len: i64, ctx: &Context) -> Result<()> {
|
||||||
if offset < 0 || len <= 0 {
|
if offset < 0 || len <= 0 {
|
||||||
return_errno_with_message!(
|
return_errno_with_message!(
|
||||||
Errno::EINVAL,
|
Errno::EINVAL,
|
||||||
@ -48,8 +47,7 @@ fn check_offset_and_len(offset: i64, len: i64) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let max_file_size = {
|
let max_file_size = {
|
||||||
let current = current!();
|
let resource_limits = ctx.process.resource_limits().lock();
|
||||||
let resource_limits = current.resource_limits().lock();
|
|
||||||
resource_limits
|
resource_limits
|
||||||
.get_rlimit(ResourceType::RLIMIT_FSIZE)
|
.get_rlimit(ResourceType::RLIMIT_FSIZE)
|
||||||
.get_cur() as usize
|
.get_cur() as usize
|
||||||
|
@ -10,24 +10,22 @@ use crate::{
|
|||||||
process::Pid,
|
process::Pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let fcntl_cmd = FcntlCmd::try_from(cmd)?;
|
let fcntl_cmd = FcntlCmd::try_from(cmd)?;
|
||||||
debug!("fd = {}, cmd = {:?}, arg = {}", fd, fcntl_cmd, arg);
|
debug!("fd = {}, cmd = {:?}, arg = {}", fd, fcntl_cmd, arg);
|
||||||
|
let current = ctx.process;
|
||||||
match fcntl_cmd {
|
match fcntl_cmd {
|
||||||
FcntlCmd::F_DUPFD => {
|
FcntlCmd::F_DUPFD => {
|
||||||
let current = current!();
|
|
||||||
let mut file_table = current.file_table().lock();
|
let mut file_table = current.file_table().lock();
|
||||||
let new_fd = file_table.dup(fd, arg as FileDesc, FdFlags::empty())?;
|
let new_fd = file_table.dup(fd, arg as FileDesc, FdFlags::empty())?;
|
||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_DUPFD_CLOEXEC => {
|
FcntlCmd::F_DUPFD_CLOEXEC => {
|
||||||
let current = current!();
|
|
||||||
let mut file_table = current.file_table().lock();
|
let mut file_table = current.file_table().lock();
|
||||||
let new_fd = file_table.dup(fd, arg as FileDesc, FdFlags::CLOEXEC)?;
|
let new_fd = file_table.dup(fd, arg as FileDesc, FdFlags::CLOEXEC)?;
|
||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_GETFD => {
|
FcntlCmd::F_GETFD => {
|
||||||
let current = current!();
|
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
let entry = file_table.get_entry(fd)?;
|
let entry = file_table.get_entry(fd)?;
|
||||||
let fd_flags = entry.flags();
|
let fd_flags = entry.flags();
|
||||||
@ -41,14 +39,12 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<Sys
|
|||||||
FdFlags::from_bits(arg as u8)
|
FdFlags::from_bits(arg as u8)
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?
|
.ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?
|
||||||
};
|
};
|
||||||
let current = current!();
|
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
let entry = file_table.get_entry(fd)?;
|
let entry = file_table.get_entry(fd)?;
|
||||||
entry.set_flags(flags);
|
entry.set_flags(flags);
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_GETFL => {
|
FcntlCmd::F_GETFL => {
|
||||||
let current = current!();
|
|
||||||
let file = {
|
let file = {
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
@ -60,7 +56,6 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<Sys
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_SETFL => {
|
FcntlCmd::F_SETFL => {
|
||||||
let current = current!();
|
|
||||||
let file = {
|
let file = {
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
@ -82,7 +77,6 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<Sys
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_SETOWN => {
|
FcntlCmd::F_SETOWN => {
|
||||||
let current = current!();
|
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
let file_entry = file_table.get_entry(fd)?;
|
let file_entry = file_table.get_entry(fd)?;
|
||||||
// A process ID is specified as a positive value; a process group ID is specified as a negative value.
|
// A process ID is specified as a positive value; a process group ID is specified as a negative value.
|
||||||
@ -96,7 +90,6 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<Sys
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
FcntlCmd::F_GETOWN => {
|
FcntlCmd::F_GETOWN => {
|
||||||
let current = current!();
|
|
||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
let file_entry = file_table.get_entry(fd)?;
|
let file_entry = file_table.get_entry(fd)?;
|
||||||
let pid = file_entry.owner().unwrap_or(0);
|
let pid = file_entry.owner().unwrap_or(0);
|
||||||
|
@ -6,12 +6,11 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fsync(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fsync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let current = current!();
|
let file_table = ctx.process.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 inode_handle = file
|
let inode_handle = file
|
||||||
.downcast_ref::<InodeHandle>()
|
.downcast_ref::<InodeHandle>()
|
||||||
@ -22,12 +21,11 @@ pub fn sys_fsync(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_fdatasync(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fdatasync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let current = current!();
|
let file_table = ctx.process.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 inode_handle = file
|
let inode_handle = file
|
||||||
.downcast_ref::<InodeHandle>()
|
.downcast_ref::<InodeHandle>()
|
||||||
|
@ -16,7 +16,7 @@ pub fn sys_getdents(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
buf_addr: Vaddr,
|
buf_addr: Vaddr,
|
||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
@ -24,8 +24,7 @@ pub fn sys_getdents(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
let inode_handle = file
|
let inode_handle = file
|
||||||
@ -46,7 +45,7 @@ pub fn sys_getdents64(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
buf_addr: Vaddr,
|
buf_addr: Vaddr,
|
||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
@ -54,8 +53,7 @@ pub fn sys_getdents64(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
let inode_handle = file
|
let inode_handle = file
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getpgrp(_ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_getpgrp(ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current = current!();
|
Ok(SyscallReturn::Return(ctx.process.pgid() as _))
|
||||||
Ok(SyscallReturn::Return(current.pgid() as _))
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getppid(_ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_getppid(ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current = current!();
|
let parent = ctx.process.parent();
|
||||||
let parent = current.parent();
|
|
||||||
match parent {
|
match parent {
|
||||||
None => Ok(SyscallReturn::Return(0)),
|
None => Ok(SyscallReturn::Return(0)),
|
||||||
Some(parent) => Ok(SyscallReturn::Return(parent.pid() as _)),
|
Some(parent) => Ok(SyscallReturn::Return(parent.pid() as _)),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use int_to_c_enum::TryFromInt;
|
use int_to_c_enum::TryFromInt;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::posix_thread::PosixThreadExt, time::timeval_t};
|
use crate::{prelude::*, time::timeval_t};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)]
|
#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
@ -14,7 +14,7 @@ enum RusageTarget {
|
|||||||
Thread = 1,
|
Thread = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let rusage_target = RusageTarget::try_from(target)?;
|
let rusage_target = RusageTarget::try_from(target)?;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
@ -25,7 +25,7 @@ pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, _ctx: &Context) -> Result<
|
|||||||
if rusage_addr != 0 {
|
if rusage_addr != 0 {
|
||||||
let rusage = match rusage_target {
|
let rusage = match rusage_target {
|
||||||
RusageTarget::ForSelf => {
|
RusageTarget::ForSelf => {
|
||||||
let process = current!();
|
let process = ctx.process;
|
||||||
rusage_t {
|
rusage_t {
|
||||||
ru_utime: process.prof_clock().user_clock().read_time().into(),
|
ru_utime: process.prof_clock().user_clock().read_time().into(),
|
||||||
ru_stime: process.prof_clock().kernel_clock().read_time().into(),
|
ru_stime: process.prof_clock().kernel_clock().read_time().into(),
|
||||||
@ -33,8 +33,7 @@ pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, _ctx: &Context) -> Result<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RusageTarget::Thread => {
|
RusageTarget::Thread => {
|
||||||
let thread = current_thread!();
|
let posix_thread = ctx.posix_thread;
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
|
||||||
rusage_t {
|
rusage_t {
|
||||||
ru_utime: posix_thread.prof_clock().user_clock().read_time().into(),
|
ru_utime: posix_thread.prof_clock().user_clock().read_time().into(),
|
||||||
ru_stime: posix_thread.prof_clock().kernel_clock().read_time().into(),
|
ru_stime: posix_thread.prof_clock().kernel_clock().read_time().into(),
|
||||||
|
@ -6,10 +6,10 @@ use crate::{
|
|||||||
process::{process_table, Pid},
|
process::{process_table, Pid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getsid(pid: Pid, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_getsid(pid: Pid, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("pid = {}", pid);
|
debug!("pid = {}", pid);
|
||||||
|
|
||||||
let session = current!().session().unwrap();
|
let session = ctx.process.session().unwrap();
|
||||||
let sid = session.sid();
|
let sid = session.sid();
|
||||||
|
|
||||||
if pid == 0 {
|
if pid == 0 {
|
||||||
|
@ -9,14 +9,13 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let ioctl_cmd = IoctlCmd::try_from(cmd)?;
|
let ioctl_cmd = IoctlCmd::try_from(cmd)?;
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, ioctl_cmd = {:?}, arg = 0x{:x}",
|
"fd = {}, ioctl_cmd = {:?}, arg = 0x{:x}",
|
||||||
fd, ioctl_cmd, arg
|
fd, ioctl_cmd, arg
|
||||||
);
|
);
|
||||||
let current = current!();
|
let file_table = ctx.process.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 = match ioctl_cmd {
|
let res = match ioctl_cmd {
|
||||||
IoctlCmd::FIONBIO => {
|
IoctlCmd::FIONBIO => {
|
||||||
|
@ -29,10 +29,8 @@ pub fn sys_kill(process_filter: u64, sig_num: u64, ctx: &Context) -> Result<Sysc
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_kill(filter: ProcessFilter, sig_num: Option<SigNum>, ctx: &Context) -> Result<()> {
|
pub fn do_sys_kill(filter: ProcessFilter, sig_num: Option<SigNum>, ctx: &Context) -> Result<()> {
|
||||||
let current = current!();
|
|
||||||
|
|
||||||
let signal = sig_num.map(|sig_num| {
|
let signal = sig_num.map(|sig_num| {
|
||||||
let pid = current.pid();
|
let pid = ctx.process.pid();
|
||||||
let uid = ctx.posix_thread.credentials().ruid();
|
let uid = ctx.posix_thread.credentials().ruid();
|
||||||
UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid)
|
UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid)
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,7 @@ pub fn sys_linkat(
|
|||||||
new_dirfd: FileDesc,
|
new_dirfd: FileDesc,
|
||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ pub fn sys_linkat(
|
|||||||
old_dirfd, old_path, new_dirfd, new_path, flags
|
old_dirfd, old_path, new_dirfd, new_path, flags
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let (old_dentry, new_dir_dentry, new_name) = {
|
let (old_dentry, new_dir_dentry, new_name) = {
|
||||||
let old_path = old_path.to_string_lossy();
|
let old_path = old_path.to_string_lossy();
|
||||||
if old_path.ends_with('/') {
|
if old_path.ends_with('/') {
|
||||||
@ -45,7 +44,7 @@ pub fn sys_linkat(
|
|||||||
|
|
||||||
let old_fs_path = FsPath::new(old_dirfd, old_path.as_ref())?;
|
let old_fs_path = FsPath::new(old_dirfd, old_path.as_ref())?;
|
||||||
let new_fs_path = FsPath::new(new_dirfd, new_path.as_ref())?;
|
let new_fs_path = FsPath::new(new_dirfd, new_path.as_ref())?;
|
||||||
let fs = current.fs().read();
|
let fs = ctx.process.fs().read();
|
||||||
let old_dentry = if flags.contains(LinkFlags::AT_SYMLINK_FOLLOW) {
|
let old_dentry = if flags.contains(LinkFlags::AT_SYMLINK_FOLLOW) {
|
||||||
fs.lookup(&old_fs_path)?
|
fs.lookup(&old_fs_path)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,12 +6,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_lseek(
|
pub fn sys_lseek(fd: FileDesc, offset: isize, whence: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
fd: FileDesc,
|
|
||||||
offset: isize,
|
|
||||||
whence: u32,
|
|
||||||
_ctx: &Context,
|
|
||||||
) -> Result<SyscallReturn> {
|
|
||||||
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
||||||
let seek_from = match whence {
|
let seek_from = match whence {
|
||||||
0 => {
|
0 => {
|
||||||
@ -24,8 +19,7 @@ pub fn sys_lseek(
|
|||||||
2 => SeekFrom::End(offset),
|
2 => SeekFrom::End(offset),
|
||||||
_ => return_errno!(Errno::EINVAL),
|
_ => return_errno!(Errno::EINVAL),
|
||||||
};
|
};
|
||||||
let current = current!();
|
let file_table = ctx.process.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 offset = file.seek(seek_from)?;
|
let offset = file.seek(seek_from)?;
|
||||||
Ok(SyscallReturn::Return(offset as _))
|
Ok(SyscallReturn::Return(offset as _))
|
||||||
|
@ -7,7 +7,7 @@ pub fn sys_madvise(
|
|||||||
start: Vaddr,
|
start: Vaddr,
|
||||||
len: usize,
|
len: usize,
|
||||||
behavior: i32,
|
behavior: i32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let behavior = MadviseBehavior::try_from(behavior)?;
|
let behavior = MadviseBehavior::try_from(behavior)?;
|
||||||
debug!(
|
debug!(
|
||||||
@ -26,18 +26,17 @@ pub fn sys_madvise(
|
|||||||
MadviseBehavior::MADV_DONTNEED => {
|
MadviseBehavior::MADV_DONTNEED => {
|
||||||
warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
|
warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
|
||||||
}
|
}
|
||||||
MadviseBehavior::MADV_FREE => madv_free(start, len)?,
|
MadviseBehavior::MADV_FREE => madv_free(start, len, ctx)?,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn madv_free(start: Vaddr, len: usize) -> Result<()> {
|
fn madv_free(start: Vaddr, len: usize, ctx: &Context) -> Result<()> {
|
||||||
debug_assert!(start % PAGE_SIZE == 0);
|
debug_assert!(start % PAGE_SIZE == 0);
|
||||||
debug_assert!(len % PAGE_SIZE == 0);
|
debug_assert!(len % PAGE_SIZE == 0);
|
||||||
|
|
||||||
let current = current!();
|
let root_vmar = ctx.process.root_vmar();
|
||||||
let root_vmar = current.root_vmar();
|
|
||||||
let advised_range = start..start + len;
|
let advised_range = start..start + len;
|
||||||
let _ = root_vmar.destroy(advised_range);
|
let _ = root_vmar.destroy(advised_range);
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@ pub fn sys_mkdirat(
|
|||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path = {:?}, mode = {}", dirfd, path, mode);
|
debug!("dirfd = {}, path = {:?}, mode = {}", dirfd, path, mode);
|
||||||
|
|
||||||
let current = current!();
|
let current = ctx.process;
|
||||||
let (dir_dentry, name) = {
|
let (dir_dentry, name) = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
|
@ -17,10 +17,10 @@ pub fn sys_mknodat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
dev: usize,
|
dev: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
let current = current!();
|
let current = ctx.process;
|
||||||
let inode_mode = {
|
let inode_mode = {
|
||||||
let mask_mode = mode & !current.umask().read().get();
|
let mask_mode = mode & !current.umask().read().get();
|
||||||
InodeMode::from_bits_truncate(mask_mode)
|
InodeMode::from_bits_truncate(mask_mode)
|
||||||
|
@ -22,7 +22,7 @@ pub fn sys_mmap(
|
|||||||
flags: u64,
|
flags: u64,
|
||||||
fd: u64,
|
fd: u64,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let perms = VmPerms::from_posix_prot_bits(perms as u32).unwrap();
|
let perms = VmPerms::from_posix_prot_bits(perms as u32).unwrap();
|
||||||
let option = MMapOptions::try_from(flags as u32)?;
|
let option = MMapOptions::try_from(flags as u32)?;
|
||||||
@ -33,6 +33,7 @@ pub fn sys_mmap(
|
|||||||
option,
|
option,
|
||||||
fd as _,
|
fd as _,
|
||||||
offset as usize,
|
offset as usize,
|
||||||
|
ctx,
|
||||||
)?;
|
)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
@ -44,6 +45,7 @@ fn do_sys_mmap(
|
|||||||
option: MMapOptions,
|
option: MMapOptions,
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<Vaddr> {
|
) -> Result<Vaddr> {
|
||||||
debug!(
|
debug!(
|
||||||
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}, option = {:?}, fd = {}, offset = 0x{:x}",
|
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}, option = {:?}, fd = {}, offset = 0x{:x}",
|
||||||
@ -64,11 +66,10 @@ fn do_sys_mmap(
|
|||||||
}
|
}
|
||||||
alloc_anonyous_vmo(len)?
|
alloc_anonyous_vmo(len)?
|
||||||
} else {
|
} else {
|
||||||
alloc_filebacked_vmo(fd, len, offset, &option)?
|
alloc_filebacked_vmo(fd, len, offset, &option, ctx)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
let root_vmar = ctx.process.root_vmar();
|
||||||
let root_vmar = current.root_vmar();
|
|
||||||
let vm_map_options = {
|
let vm_map_options = {
|
||||||
let mut options = root_vmar.new_map(vmo.to_dyn(), vm_perms)?;
|
let mut options = root_vmar.new_map(vmo.to_dyn(), vm_perms)?;
|
||||||
let flags = option.flags;
|
let flags = option.flags;
|
||||||
@ -101,10 +102,10 @@ fn alloc_filebacked_vmo(
|
|||||||
len: usize,
|
len: usize,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
option: &MMapOptions,
|
option: &MMapOptions,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<Vmo> {
|
) -> Result<Vmo> {
|
||||||
let current = current!();
|
|
||||||
let page_cache_vmo = {
|
let page_cache_vmo = {
|
||||||
let fs_resolver = current.fs().read();
|
let fs_resolver = ctx.process.fs().read();
|
||||||
let dentry = fs_resolver.lookup_from_fd(fd)?;
|
let dentry = fs_resolver.lookup_from_fd(fd)?;
|
||||||
let inode = dentry.inode();
|
let inode = dentry.inode();
|
||||||
inode
|
inode
|
||||||
|
@ -23,7 +23,7 @@ pub fn sys_mount(
|
|||||||
fstype_addr: Vaddr,
|
fstype_addr: Vaddr,
|
||||||
flags: u64,
|
flags: u64,
|
||||||
data: Vaddr,
|
data: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
|
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -34,14 +34,13 @@ pub fn sys_mount(
|
|||||||
devname, dirname, fstype_addr, mount_flags, data,
|
devname, dirname, fstype_addr, mount_flags, data,
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dst_dentry = {
|
let dst_dentry = {
|
||||||
let dirname = dirname.to_string_lossy();
|
let dirname = dirname.to_string_lossy();
|
||||||
if dirname.is_empty() {
|
if dirname.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dirname is empty");
|
return_errno_with_message!(Errno::ENOENT, "dirname is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(AT_FDCWD, dirname.as_ref())?;
|
let fs_path = FsPath::new(AT_FDCWD, dirname.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if mount_flags.contains(MountFlags::MS_REMOUNT) && mount_flags.contains(MountFlags::MS_BIND) {
|
if mount_flags.contains(MountFlags::MS_REMOUNT) && mount_flags.contains(MountFlags::MS_BIND) {
|
||||||
@ -53,6 +52,7 @@ pub fn sys_mount(
|
|||||||
devname,
|
devname,
|
||||||
dst_dentry,
|
dst_dentry,
|
||||||
mount_flags.contains(MountFlags::MS_REC),
|
mount_flags.contains(MountFlags::MS_REC),
|
||||||
|
ctx,
|
||||||
)?;
|
)?;
|
||||||
} else if mount_flags.contains(MountFlags::MS_SHARED)
|
} else if mount_flags.contains(MountFlags::MS_SHARED)
|
||||||
| mount_flags.contains(MountFlags::MS_PRIVATE)
|
| mount_flags.contains(MountFlags::MS_PRIVATE)
|
||||||
@ -61,7 +61,7 @@ pub fn sys_mount(
|
|||||||
{
|
{
|
||||||
do_change_type()?;
|
do_change_type()?;
|
||||||
} else if mount_flags.contains(MountFlags::MS_MOVE) {
|
} else if mount_flags.contains(MountFlags::MS_MOVE) {
|
||||||
do_move_mount_old(devname, dst_dentry)?;
|
do_move_mount_old(devname, dst_dentry, ctx)?;
|
||||||
} else {
|
} else {
|
||||||
do_new_mount(devname, fstype_addr, dst_dentry)?;
|
do_new_mount(devname, fstype_addr, dst_dentry)?;
|
||||||
}
|
}
|
||||||
@ -81,15 +81,19 @@ fn do_remount() -> Result<()> {
|
|||||||
///
|
///
|
||||||
/// If recursive is true, then bind the mount recursively.
|
/// If recursive is true, then bind the mount recursively.
|
||||||
/// Such as use user command `mount --rbind src dst`.
|
/// Such as use user command `mount --rbind src dst`.
|
||||||
fn do_bind_mount(src_name: CString, dst_dentry: Arc<Dentry>, recursive: bool) -> Result<()> {
|
fn do_bind_mount(
|
||||||
let current = current!();
|
src_name: CString,
|
||||||
|
dst_dentry: Arc<Dentry>,
|
||||||
|
recursive: bool,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<()> {
|
||||||
let src_dentry = {
|
let src_dentry = {
|
||||||
let src_name = src_name.to_string_lossy();
|
let src_name = src_name.to_string_lossy();
|
||||||
if src_name.is_empty() {
|
if src_name.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "src_name is empty");
|
return_errno_with_message!(Errno::ENOENT, "src_name is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(AT_FDCWD, src_name.as_ref())?;
|
let fs_path = FsPath::new(AT_FDCWD, src_name.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if src_dentry.type_() != InodeType::Dir {
|
if src_dentry.type_() != InodeType::Dir {
|
||||||
@ -105,15 +109,14 @@ fn do_change_type() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Move a mount from src location to dst location.
|
/// Move a mount from src location to dst location.
|
||||||
fn do_move_mount_old(src_name: CString, dst_dentry: Arc<Dentry>) -> Result<()> {
|
fn do_move_mount_old(src_name: CString, dst_dentry: Arc<Dentry>, ctx: &Context) -> Result<()> {
|
||||||
let current = current!();
|
|
||||||
let src_dentry = {
|
let src_dentry = {
|
||||||
let src_name = src_name.to_string_lossy();
|
let src_name = src_name.to_string_lossy();
|
||||||
if src_name.is_empty() {
|
if src_name.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "src_name is empty");
|
return_errno_with_message!(Errno::ENOENT, "src_name is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(AT_FDCWD, src_name.as_ref())?;
|
let fs_path = FsPath::new(AT_FDCWD, src_name.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if !src_dentry.is_root_of_mount() {
|
if !src_dentry.is_root_of_mount() {
|
||||||
|
@ -5,14 +5,13 @@ use align_ext::AlignExt;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, vm::perms::VmPerms};
|
use crate::{prelude::*, vm::perms::VmPerms};
|
||||||
|
|
||||||
pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let vm_perms = VmPerms::from_bits_truncate(perms as u32);
|
let vm_perms = VmPerms::from_bits_truncate(perms as u32);
|
||||||
debug!(
|
debug!(
|
||||||
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}",
|
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}",
|
||||||
addr, len, vm_perms
|
addr, len, vm_perms
|
||||||
);
|
);
|
||||||
let current = current!();
|
let root_vmar = ctx.process.root_vmar();
|
||||||
let root_vmar = current.root_vmar();
|
|
||||||
debug_assert!(addr % PAGE_SIZE == 0);
|
debug_assert!(addr % PAGE_SIZE == 0);
|
||||||
let len = len.align_up(PAGE_SIZE);
|
let len = len.align_up(PAGE_SIZE);
|
||||||
let range = addr..(addr + len);
|
let range = addr..(addr + len);
|
||||||
|
@ -5,10 +5,9 @@ use align_ext::AlignExt;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_munmap(addr: Vaddr, len: usize, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_munmap(addr: Vaddr, len: usize, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("addr = 0x{:x}, len = {}", addr, len);
|
debug!("addr = 0x{:x}, len = {}", addr, len);
|
||||||
let current = current!();
|
let root_vmar = ctx.process.root_vmar();
|
||||||
let root_vmar = current.root_vmar();
|
|
||||||
let len = len.align_up(PAGE_SIZE);
|
let len = len.align_up(PAGE_SIZE);
|
||||||
debug!("unmap range = 0x{:x} - 0x{:x}", addr, addr + len);
|
debug!("unmap range = 0x{:x} - 0x{:x}", addr, addr + len);
|
||||||
root_vmar.destroy(addr..addr + len)?;
|
root_vmar.destroy(addr..addr + len)?;
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
pub fn sys_nanosleep(
|
pub fn sys_nanosleep(
|
||||||
request_timespec_addr: Vaddr,
|
request_timespec_addr: Vaddr,
|
||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let clockid = ClockId::CLOCK_MONOTONIC;
|
let clockid = ClockId::CLOCK_MONOTONIC;
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ pub fn sys_nanosleep(
|
|||||||
false,
|
false,
|
||||||
request_timespec_addr,
|
request_timespec_addr,
|
||||||
remain_timespec_addr,
|
remain_timespec_addr,
|
||||||
|
ctx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ pub fn sys_clock_nanosleep(
|
|||||||
flags: i32,
|
flags: i32,
|
||||||
request_timespec_addr: Vaddr,
|
request_timespec_addr: Vaddr,
|
||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let is_abs_time = if flags == 0 {
|
let is_abs_time = if flags == 0 {
|
||||||
false
|
false
|
||||||
@ -44,6 +45,7 @@ pub fn sys_clock_nanosleep(
|
|||||||
is_abs_time,
|
is_abs_time,
|
||||||
request_timespec_addr,
|
request_timespec_addr,
|
||||||
remain_timespec_addr,
|
remain_timespec_addr,
|
||||||
|
ctx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +54,7 @@ fn do_clock_nanosleep(
|
|||||||
is_abs_time: bool,
|
is_abs_time: bool,
|
||||||
request_timespec_addr: Vaddr,
|
request_timespec_addr: Vaddr,
|
||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let request_time = {
|
let request_time = {
|
||||||
let timespec = CurrentUserSpace::get().read_val::<timespec_t>(request_timespec_addr)?;
|
let timespec = CurrentUserSpace::get().read_val::<timespec_t>(request_timespec_addr)?;
|
||||||
@ -63,7 +66,7 @@ fn do_clock_nanosleep(
|
|||||||
clockid, is_abs_time, request_time, remain_timespec_addr
|
clockid, is_abs_time, request_time, remain_timespec_addr
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_time = read_clock(clockid)?;
|
let start_time = read_clock(clockid, ctx)?;
|
||||||
let timeout = if is_abs_time {
|
let timeout = if is_abs_time {
|
||||||
if request_time < start_time {
|
if request_time < start_time {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
@ -82,7 +85,7 @@ fn do_clock_nanosleep(
|
|||||||
match res {
|
match res {
|
||||||
Err(e) if e.error() == Errno::ETIME => Ok(SyscallReturn::Return(0)),
|
Err(e) if e.error() == Errno::ETIME => Ok(SyscallReturn::Return(0)),
|
||||||
Err(e) if e.error() == Errno::EINTR => {
|
Err(e) if e.error() == Errno::EINTR => {
|
||||||
let end_time = read_clock(clockid)?;
|
let end_time = read_clock(clockid, ctx)?;
|
||||||
|
|
||||||
if end_time >= start_time + timeout {
|
if end_time >= start_time + timeout {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
|
@ -16,7 +16,7 @@ pub fn sys_openat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
@ -24,7 +24,7 @@ pub fn sys_openat(
|
|||||||
dirfd, path, flags, mode
|
dirfd, path, flags, mode
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
let current = ctx.process;
|
||||||
let file_handle = {
|
let file_handle = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_pipe2(fds: Vaddr, flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_pipe2(fds: Vaddr, flags: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("flags: {:?}", flags);
|
debug!("flags: {:?}", flags);
|
||||||
|
|
||||||
let (pipe_reader, pipe_writer) = {
|
let (pipe_reader, pipe_writer) = {
|
||||||
@ -30,8 +30,7 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32, _ctx: &Context) -> Result<SyscallReturn
|
|||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
|
|
||||||
let pipe_fds = PipeFds {
|
let pipe_fds = PipeFds {
|
||||||
reader_fd: file_table.insert(pipe_reader, fd_flags),
|
reader_fd: file_table.insert(pipe_reader, fd_flags),
|
||||||
|
@ -5,7 +5,7 @@ use core::{cell::Cell, time::Duration};
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller};
|
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller};
|
||||||
|
|
||||||
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let poll_fds = {
|
let poll_fds = {
|
||||||
let mut read_addr = fds;
|
let mut read_addr = fds;
|
||||||
@ -31,7 +31,7 @@ pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, _ctx: &Context) -> Result<S
|
|||||||
poll_fds, nfds, timeout
|
poll_fds, nfds, timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
let num_revents = do_poll(&poll_fds, timeout)?;
|
let num_revents = do_poll(&poll_fds, timeout, ctx)?;
|
||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
let mut write_addr = fds;
|
let mut write_addr = fds;
|
||||||
@ -45,7 +45,7 @@ pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, _ctx: &Context) -> Result<S
|
|||||||
Ok(SyscallReturn::Return(num_revents as _))
|
Ok(SyscallReturn::Return(num_revents as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_poll(poll_fds: &[PollFd], timeout: Option<Duration>) -> Result<usize> {
|
pub fn do_poll(poll_fds: &[PollFd], timeout: Option<Duration>, ctx: &Context) -> Result<usize> {
|
||||||
// The main loop of polling
|
// The main loop of polling
|
||||||
let mut poller = Poller::new();
|
let mut poller = Poller::new();
|
||||||
loop {
|
loop {
|
||||||
@ -59,9 +59,8 @@ pub fn do_poll(poll_fds: &[PollFd], timeout: Option<Duration>) -> Result<usize>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Poll the file
|
// Poll the file
|
||||||
let current = current!();
|
|
||||||
let file = {
|
let file = {
|
||||||
let file_table = current.file_table().lock();
|
let file_table = ctx.process.file_table().lock();
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
let need_poller = if num_revents == 0 {
|
let need_poller = if num_revents == 0 {
|
||||||
|
@ -15,7 +15,7 @@ pub fn sys_prctl(
|
|||||||
arg3: u64,
|
arg3: u64,
|
||||||
arg4: u64,
|
arg4: u64,
|
||||||
arg5: u64,
|
arg5: u64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let prctl_cmd = PrctlCmd::from_args(option, arg2, arg3, arg4, arg5)?;
|
let prctl_cmd = PrctlCmd::from_args(option, arg2, arg3, arg4, arg5)?;
|
||||||
debug!("prctl cmd = {:x?}", prctl_cmd);
|
debug!("prctl cmd = {:x?}", prctl_cmd);
|
||||||
@ -23,14 +23,11 @@ pub fn sys_prctl(
|
|||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||||
match prctl_cmd {
|
match prctl_cmd {
|
||||||
PrctlCmd::PR_SET_PDEATHSIG(signum) => {
|
PrctlCmd::PR_SET_PDEATHSIG(signum) => {
|
||||||
let current = current!();
|
ctx.process.set_parent_death_signal(signum);
|
||||||
current.set_parent_death_signal(signum);
|
|
||||||
}
|
}
|
||||||
PrctlCmd::PR_GET_PDEATHSIG(write_to_addr) => {
|
PrctlCmd::PR_GET_PDEATHSIG(write_to_addr) => {
|
||||||
let write_val = {
|
let write_val = {
|
||||||
let current = current!();
|
match ctx.process.parent_death_signal() {
|
||||||
|
|
||||||
match current.parent_death_signal() {
|
|
||||||
None => 0i32,
|
None => 0i32,
|
||||||
Some(signum) => signum.as_u8() as i32,
|
Some(signum) => signum.as_u8() as i32,
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ pub fn sys_pread64(
|
|||||||
user_buf_ptr: Vaddr,
|
user_buf_ptr: Vaddr,
|
||||||
user_buf_len: usize,
|
user_buf_len: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, buf = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
||||||
@ -19,8 +19,7 @@ pub fn sys_pread64(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait
|
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait
|
||||||
|
@ -11,9 +11,9 @@ pub fn sys_readv(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_readv(fd, io_vec_ptr, io_vec_count)?;
|
let res = do_sys_readv(fd, io_vec_ptr, io_vec_count, ctx)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,9 +22,9 @@ pub fn sys_preadv(
|
|||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
let res = do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty(), ctx)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,16 +34,16 @@ pub fn sys_preadv2(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = match RWFFlag::from_bits(flags) {
|
let flags = match RWFFlag::from_bits(flags) {
|
||||||
Some(flags) => flags,
|
Some(flags) => flags,
|
||||||
None => return_errno_with_message!(Errno::EINVAL, "invalid flags"),
|
None => return_errno_with_message!(Errno::EINVAL, "invalid flags"),
|
||||||
};
|
};
|
||||||
let res = if offset == -1 {
|
let res = if offset == -1 {
|
||||||
do_sys_readv(fd, io_vec_ptr, io_vec_count)?
|
do_sys_readv(fd, io_vec_ptr, io_vec_count, ctx)?
|
||||||
} else {
|
} else {
|
||||||
do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, flags)?
|
do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, flags, ctx)?
|
||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
@ -54,6 +54,7 @@ fn do_sys_preadv(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_flags: RWFFlag,
|
_flags: RWFFlag,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
debug!(
|
debug!(
|
||||||
"preadv: fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}, offset = 0x{:x}",
|
"preadv: fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}, offset = 0x{:x}",
|
||||||
@ -65,8 +66,7 @@ fn do_sys_preadv(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,15 +125,19 @@ fn do_sys_preadv(
|
|||||||
Ok(total_len)
|
Ok(total_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_sys_readv(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result<usize> {
|
fn do_sys_readv(
|
||||||
|
fd: FileDesc,
|
||||||
|
io_vec_ptr: Vaddr,
|
||||||
|
io_vec_count: usize,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<usize> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
||||||
fd, io_vec_ptr, io_vec_count
|
fd, io_vec_ptr, io_vec_count
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,15 +11,14 @@ pub fn sys_prlimit64(
|
|||||||
resource: u32,
|
resource: u32,
|
||||||
new_rlim_addr: Vaddr,
|
new_rlim_addr: Vaddr,
|
||||||
old_rlim_addr: Vaddr,
|
old_rlim_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let resource = ResourceType::try_from(resource)?;
|
let resource = ResourceType::try_from(resource)?;
|
||||||
debug!(
|
debug!(
|
||||||
"pid = {}, resource = {:?}, new_rlim_addr = 0x{:x}, old_rlim_addr = 0x{:x}",
|
"pid = {}, resource = {:?}, new_rlim_addr = 0x{:x}, old_rlim_addr = 0x{:x}",
|
||||||
pid, resource, new_rlim_addr, old_rlim_addr
|
pid, resource, new_rlim_addr, old_rlim_addr
|
||||||
);
|
);
|
||||||
let current = current!();
|
let mut resource_limits = ctx.process.resource_limits().lock();
|
||||||
let mut resource_limits = current.resource_limits().lock();
|
|
||||||
if old_rlim_addr != 0 {
|
if old_rlim_addr != 0 {
|
||||||
let rlimit = resource_limits.get_rlimit(resource);
|
let rlimit = resource_limits.get_rlimit(resource);
|
||||||
CurrentUserSpace::get().write_val(old_rlim_addr, rlimit)?;
|
CurrentUserSpace::get().write_val(old_rlim_addr, rlimit)?;
|
||||||
|
@ -4,10 +4,7 @@ use core::{sync::atomic::Ordering, time::Duration};
|
|||||||
|
|
||||||
use super::{select::do_sys_select, SyscallReturn};
|
use super::{select::do_sys_select, SyscallReturn};
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::FileDesc, prelude::*, process::signal::sig_mask::SigMask, time::timespec_t,
|
||||||
prelude::*,
|
|
||||||
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
|
||||||
time::timespec_t,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_pselect6(
|
pub fn sys_pselect6(
|
||||||
@ -17,11 +14,8 @@ pub fn sys_pselect6(
|
|||||||
exceptfds_addr: Vaddr,
|
exceptfds_addr: Vaddr,
|
||||||
timespec_addr: Vaddr,
|
timespec_addr: Vaddr,
|
||||||
sigmask_addr: Vaddr,
|
sigmask_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let current_thread = current_thread!();
|
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
|
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let old_simask = if sigmask_addr != 0 {
|
let old_simask = if sigmask_addr != 0 {
|
||||||
let sigmask_with_size: SigMaskWithSize = user_space.read_val(sigmask_addr)?;
|
let sigmask_with_size: SigMaskWithSize = user_space.read_val(sigmask_addr)?;
|
||||||
@ -29,7 +23,8 @@ pub fn sys_pselect6(
|
|||||||
if !sigmask_with_size.is_valid() {
|
if !sigmask_with_size.is_valid() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "sigmask size is invalid")
|
return_errno_with_message!(Errno::EINVAL, "sigmask size is invalid")
|
||||||
}
|
}
|
||||||
let old_sigmask = posix_thread
|
let old_sigmask = ctx
|
||||||
|
.posix_thread
|
||||||
.sig_mask()
|
.sig_mask()
|
||||||
.swap(sigmask_with_size.sigmask, Ordering::Relaxed);
|
.swap(sigmask_with_size.sigmask, Ordering::Relaxed);
|
||||||
|
|
||||||
@ -45,10 +40,19 @@ pub fn sys_pselect6(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = do_sys_select(nfds, readfds_addr, writefds_addr, exceptfds_addr, timeout);
|
let res = do_sys_select(
|
||||||
|
nfds,
|
||||||
|
readfds_addr,
|
||||||
|
writefds_addr,
|
||||||
|
exceptfds_addr,
|
||||||
|
timeout,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(old_mask) = old_simask {
|
if let Some(old_mask) = old_simask {
|
||||||
posix_thread.sig_mask().store(old_mask, Ordering::Relaxed);
|
ctx.posix_thread
|
||||||
|
.sig_mask()
|
||||||
|
.store(old_mask, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -8,7 +8,7 @@ pub fn sys_pwrite64(
|
|||||||
user_buf_ptr: Vaddr,
|
user_buf_ptr: Vaddr,
|
||||||
user_buf_len: usize,
|
user_buf_len: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
||||||
@ -18,8 +18,7 @@ pub fn sys_pwrite64(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
// TODO: Check (f.file->f_mode & FMODE_PWRITE); We don't have f_mode in our FileLike trait
|
// TODO: Check (f.file->f_mode & FMODE_PWRITE); We don't have f_mode in our FileLike trait
|
||||||
|
@ -7,9 +7,9 @@ pub fn sys_writev(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_writev(fd, io_vec_ptr, io_vec_count)?;
|
let res = do_sys_writev(fd, io_vec_ptr, io_vec_count, ctx)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ pub fn sys_pwritev(
|
|||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
let res = do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty(), ctx)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,16 +30,16 @@ pub fn sys_pwritev2(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = match RWFFlag::from_bits(flags) {
|
let flags = match RWFFlag::from_bits(flags) {
|
||||||
Some(flags) => flags,
|
Some(flags) => flags,
|
||||||
None => return_errno_with_message!(Errno::EINVAL, "invalid flags"),
|
None => return_errno_with_message!(Errno::EINVAL, "invalid flags"),
|
||||||
};
|
};
|
||||||
let res = if offset == -1 {
|
let res = if offset == -1 {
|
||||||
do_sys_writev(fd, io_vec_ptr, io_vec_count)?
|
do_sys_writev(fd, io_vec_ptr, io_vec_count, ctx)?
|
||||||
} else {
|
} else {
|
||||||
do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, flags)?
|
do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, flags, ctx)?
|
||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
@ -50,6 +50,7 @@ fn do_sys_pwritev(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
_flags: RWFFlag,
|
_flags: RWFFlag,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
// TODO: Implement flags support
|
// TODO: Implement flags support
|
||||||
debug!(
|
debug!(
|
||||||
@ -60,8 +61,7 @@ fn do_sys_pwritev(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait
|
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait
|
||||||
@ -110,14 +110,18 @@ fn do_sys_pwritev(
|
|||||||
Ok(total_len)
|
Ok(total_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_sys_writev(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result<usize> {
|
fn do_sys_writev(
|
||||||
|
fd: FileDesc,
|
||||||
|
io_vec_ptr: Vaddr,
|
||||||
|
io_vec_count: usize,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<usize> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
||||||
fd, io_vec_ptr, io_vec_count
|
fd, io_vec_ptr, io_vec_count
|
||||||
);
|
);
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let filetable = ctx.process.file_table().lock();
|
||||||
let filetable = current.file_table().lock();
|
|
||||||
filetable.get_file(fd)?.clone()
|
filetable.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
let mut total_len = 0;
|
let mut total_len = 0;
|
||||||
|
@ -9,7 +9,7 @@ pub fn sys_read(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
user_buf_addr: Vaddr,
|
user_buf_addr: Vaddr,
|
||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, user_buf_ptr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
@ -17,8 +17,7 @@ pub fn sys_read(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub fn sys_readlinkat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
usr_buf_addr: Vaddr,
|
usr_buf_addr: Vaddr,
|
||||||
usr_buf_len: usize,
|
usr_buf_len: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -24,14 +24,13 @@ pub fn sys_readlinkat(
|
|||||||
dirfd, path, usr_buf_addr, usr_buf_len
|
dirfd, path, usr_buf_addr, usr_buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
current.fs().read().lookup_no_follow(&fs_path)?
|
ctx.process.fs().read().lookup_no_follow(&fs_path)?
|
||||||
};
|
};
|
||||||
let linkpath = dentry.inode().read_link()?;
|
let linkpath = dentry.inode().read_link()?;
|
||||||
let bytes = linkpath.as_bytes();
|
let bytes = linkpath.as_bytes();
|
||||||
|
@ -16,7 +16,7 @@ pub fn sys_renameat(
|
|||||||
old_path_addr: Vaddr,
|
old_path_addr: Vaddr,
|
||||||
new_dirfd: FileDesc,
|
new_dirfd: FileDesc,
|
||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -26,8 +26,7 @@ pub fn sys_renameat(
|
|||||||
old_dirfd, old_path, new_dirfd, new_path
|
old_dirfd, old_path, new_dirfd, new_path
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
let fs = ctx.process.fs().read();
|
||||||
let fs = current.fs().read();
|
|
||||||
|
|
||||||
let (old_dir_dentry, old_name) = {
|
let (old_dir_dentry, old_name) = {
|
||||||
let old_path = old_path.to_string_lossy();
|
let old_path = old_path.to_string_lossy();
|
||||||
|
@ -17,19 +17,18 @@ pub fn sys_rmdir(path_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
pub(super) fn sys_rmdirat(
|
pub(super) fn sys_rmdirat(
|
||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path_addr = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path_addr = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path_addr = {:?}", dirfd, path_addr);
|
debug!("dirfd = {}, path_addr = {:?}", dirfd, path_addr);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let (dir_dentry, name) = {
|
let (dir_dentry, name) = {
|
||||||
let path_addr = path_addr.to_string_lossy();
|
let path_addr = path_addr.to_string_lossy();
|
||||||
if path_addr == "/" {
|
if path_addr == "/" {
|
||||||
return_errno_with_message!(Errno::EBUSY, "is root directory");
|
return_errno_with_message!(Errno::EBUSY, "is root directory");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(dirfd, path_addr.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path_addr.as_ref())?;
|
||||||
current.fs().read().lookup_dir_and_base_name(&fs_path)?
|
ctx.process.fs().read().lookup_dir_and_base_name(&fs_path)?
|
||||||
};
|
};
|
||||||
dir_dentry.rmdir(name.trim_end_matches('/'))?;
|
dir_dentry.rmdir(name.trim_end_matches('/'))?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
@ -11,7 +11,7 @@ pub fn sys_rt_sigaction(
|
|||||||
sig_action_addr: Vaddr,
|
sig_action_addr: Vaddr,
|
||||||
old_sig_action_addr: Vaddr,
|
old_sig_action_addr: Vaddr,
|
||||||
sigset_size: u64,
|
sigset_size: u64,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let sig_num = SigNum::try_from(sig_num)?;
|
let sig_num = SigNum::try_from(sig_num)?;
|
||||||
debug!(
|
debug!(
|
||||||
@ -21,8 +21,7 @@ pub fn sys_rt_sigaction(
|
|||||||
old_sig_action_addr,
|
old_sig_action_addr,
|
||||||
sigset_size
|
sigset_size
|
||||||
);
|
);
|
||||||
let current = current!();
|
let mut sig_dispositions = ctx.process.sig_dispositions().lock();
|
||||||
let mut sig_dispositions = current.sig_dispositions().lock();
|
|
||||||
let old_action = sig_dispositions.get(sig_num);
|
let old_action = sig_dispositions.get(sig_num);
|
||||||
let old_action_c = old_action.as_c_type();
|
let old_action_c = old_action.as_c_type();
|
||||||
if old_sig_action_addr != 0 {
|
if old_sig_action_addr != 0 {
|
||||||
|
@ -14,7 +14,7 @@ pub fn sys_select(
|
|||||||
writefds_addr: Vaddr,
|
writefds_addr: Vaddr,
|
||||||
exceptfds_addr: Vaddr,
|
exceptfds_addr: Vaddr,
|
||||||
timeval_addr: Vaddr,
|
timeval_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let timeout = if timeval_addr == 0 {
|
let timeout = if timeval_addr == 0 {
|
||||||
None
|
None
|
||||||
@ -23,7 +23,14 @@ pub fn sys_select(
|
|||||||
Some(Duration::from(timeval))
|
Some(Duration::from(timeval))
|
||||||
};
|
};
|
||||||
|
|
||||||
do_sys_select(nfds, readfds_addr, writefds_addr, exceptfds_addr, timeout)
|
do_sys_select(
|
||||||
|
nfds,
|
||||||
|
readfds_addr,
|
||||||
|
writefds_addr,
|
||||||
|
exceptfds_addr,
|
||||||
|
timeout,
|
||||||
|
ctx,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_select(
|
pub fn do_sys_select(
|
||||||
@ -32,6 +39,7 @@ pub fn do_sys_select(
|
|||||||
writefds_addr: Vaddr,
|
writefds_addr: Vaddr,
|
||||||
exceptfds_addr: Vaddr,
|
exceptfds_addr: Vaddr,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
if nfds < 0 || nfds as usize > FD_SETSIZE {
|
if nfds < 0 || nfds as usize > FD_SETSIZE {
|
||||||
return_errno_with_message!(Errno::EINVAL, "nfds is negative or exceeds the FD_SETSIZE");
|
return_errno_with_message!(Errno::EINVAL, "nfds is negative or exceeds the FD_SETSIZE");
|
||||||
@ -62,6 +70,7 @@ pub fn do_sys_select(
|
|||||||
writefds.as_mut(),
|
writefds.as_mut(),
|
||||||
exceptfds.as_mut(),
|
exceptfds.as_mut(),
|
||||||
timeout,
|
timeout,
|
||||||
|
ctx,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// FIXME: The Linux select() and pselect6() system call
|
// FIXME: The Linux select() and pselect6() system call
|
||||||
@ -89,6 +98,7 @@ fn do_select(
|
|||||||
mut writefds: Option<&mut FdSet>,
|
mut writefds: Option<&mut FdSet>,
|
||||||
mut exceptfds: Option<&mut FdSet>,
|
mut exceptfds: Option<&mut FdSet>,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
// Convert the FdSet to an array of PollFd
|
// Convert the FdSet to an array of PollFd
|
||||||
let poll_fds = {
|
let poll_fds = {
|
||||||
@ -123,7 +133,7 @@ fn do_select(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do the poll syscall that is equivalent to the select syscall
|
// Do the poll syscall that is equivalent to the select syscall
|
||||||
let num_revents = do_poll(&poll_fds, timeout)?;
|
let num_revents = do_poll(&poll_fds, timeout, ctx)?;
|
||||||
if num_revents == 0 {
|
if num_revents == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ pub fn sys_sendfile(
|
|||||||
in_fd: FileDesc,
|
in_fd: FileDesc,
|
||||||
offset_ptr: Vaddr,
|
offset_ptr: Vaddr,
|
||||||
count: isize,
|
count: isize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
trace!("raw offset ptr = 0x{:x}", offset_ptr);
|
trace!("raw offset ptr = 0x{:x}", offset_ptr);
|
||||||
|
|
||||||
@ -34,8 +34,7 @@ pub fn sys_sendfile(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (out_file, in_file) = {
|
let (out_file, in_file) = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let out_file = file_table.get_file(out_fd)?.clone();
|
let out_file = file_table.get_file(out_fd)?.clone();
|
||||||
// FIXME: the in_file must support mmap-like operations (i.e., it cannot be a socket).
|
// FIXME: the in_file must support mmap-like operations (i.e., it cannot be a socket).
|
||||||
let in_file = file_table.get_file(in_fd)?.clone();
|
let in_file = file_table.get_file(in_fd)?.clone();
|
||||||
|
@ -9,8 +9,8 @@ use crate::{
|
|||||||
sched::nice::Nice,
|
sched::nice::Nice,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_set_priority(which: i32, who: u32, prio: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_set_priority(which: i32, who: u32, prio: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let prio_target = PriorityTarget::new(which, who)?;
|
let prio_target = PriorityTarget::new(which, who, ctx)?;
|
||||||
let new_nice = {
|
let new_nice = {
|
||||||
let norm_prio = prio.clamp(i8::MIN as i32, i8::MAX as i32) as i8;
|
let norm_prio = prio.clamp(i8::MIN as i32, i8::MAX as i32) as i8;
|
||||||
Nice::new(norm_prio)
|
Nice::new(norm_prio)
|
||||||
@ -29,8 +29,8 @@ pub fn sys_set_priority(which: i32, who: u32, prio: i32, _ctx: &Context) -> Resu
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_get_priority(which: i32, who: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_get_priority(which: i32, who: u32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let prio_target = PriorityTarget::new(which, who)?;
|
let prio_target = PriorityTarget::new(which, who, ctx)?;
|
||||||
debug!("get_priority prio_target: {:?}", prio_target);
|
debug!("get_priority prio_target: {:?}", prio_target);
|
||||||
|
|
||||||
let processes = get_processes(prio_target)?;
|
let processes = get_processes(prio_target)?;
|
||||||
@ -98,13 +98,13 @@ enum PriorityTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PriorityTarget {
|
impl PriorityTarget {
|
||||||
fn new(which: i32, who: u32) -> Result<Self> {
|
fn new(which: i32, who: u32, ctx: &Context) -> Result<Self> {
|
||||||
let which = Which::try_from(which)
|
let which = Which::try_from(which)
|
||||||
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid which value"))?;
|
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid which value"))?;
|
||||||
Ok(match which {
|
Ok(match which {
|
||||||
Which::PRIO_PROCESS => {
|
Which::PRIO_PROCESS => {
|
||||||
let pid = if who == 0 {
|
let pid = if who == 0 {
|
||||||
current!().pid()
|
ctx.process.pid()
|
||||||
} else {
|
} else {
|
||||||
who as Pid
|
who as Pid
|
||||||
};
|
};
|
||||||
@ -112,7 +112,7 @@ impl PriorityTarget {
|
|||||||
}
|
}
|
||||||
Which::PRIO_PGRP => {
|
Which::PRIO_PGRP => {
|
||||||
let pgid = if who == 0 {
|
let pgid = if who == 0 {
|
||||||
current!().pgid()
|
ctx.process.pgid()
|
||||||
} else {
|
} else {
|
||||||
who as Pgid
|
who as Pgid
|
||||||
};
|
};
|
||||||
@ -120,11 +120,7 @@ impl PriorityTarget {
|
|||||||
}
|
}
|
||||||
Which::PRIO_USER => {
|
Which::PRIO_USER => {
|
||||||
let uid = if who == 0 {
|
let uid = if who == 0 {
|
||||||
current_thread!()
|
ctx.posix_thread.credentials().ruid()
|
||||||
.as_posix_thread()
|
|
||||||
.unwrap()
|
|
||||||
.credentials()
|
|
||||||
.ruid()
|
|
||||||
} else {
|
} else {
|
||||||
Uid::new(who)
|
Uid::new(who)
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ pub fn sys_setitimer(
|
|||||||
itimer_type: i32,
|
itimer_type: i32,
|
||||||
new_itimerval_addr: Vaddr,
|
new_itimerval_addr: Vaddr,
|
||||||
old_itimerval_addr: Vaddr,
|
old_itimerval_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"itimer_type = {}, new_itimerval_addr = 0x{:x}, old_itimerval_addr = 0x{:x}, ",
|
"itimer_type = {}, new_itimerval_addr = 0x{:x}, old_itimerval_addr = 0x{:x}, ",
|
||||||
@ -32,13 +32,12 @@ pub fn sys_setitimer(
|
|||||||
if new_itimerval_addr == 0 {
|
if new_itimerval_addr == 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
||||||
}
|
}
|
||||||
let current = current!();
|
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let new_itimerval = user_space.read_val::<itimerval_t>(new_itimerval_addr)?;
|
let new_itimerval = user_space.read_val::<itimerval_t>(new_itimerval_addr)?;
|
||||||
let interval = Duration::from(new_itimerval.it_interval);
|
let interval = Duration::from(new_itimerval.it_interval);
|
||||||
let expire_time = Duration::from(new_itimerval.it_value);
|
let expire_time = Duration::from(new_itimerval.it_value);
|
||||||
|
|
||||||
let process_timer_manager = current.timer_manager();
|
let process_timer_manager = ctx.process.timer_manager();
|
||||||
let timer = match ItimerType::try_from(itimer_type)? {
|
let timer = match ItimerType::try_from(itimer_type)? {
|
||||||
ItimerType::ITIMER_REAL => process_timer_manager.alarm_timer(),
|
ItimerType::ITIMER_REAL => process_timer_manager.alarm_timer(),
|
||||||
ItimerType::ITIMER_VIRTUAL => process_timer_manager.virtual_timer(),
|
ItimerType::ITIMER_VIRTUAL => process_timer_manager.virtual_timer(),
|
||||||
@ -69,7 +68,7 @@ pub fn sys_setitimer(
|
|||||||
pub fn sys_getitimer(
|
pub fn sys_getitimer(
|
||||||
itimer_type: i32,
|
itimer_type: i32,
|
||||||
itimerval_addr: Vaddr,
|
itimerval_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"itimer_type = {}, itimerval_addr = 0x{:x}",
|
"itimer_type = {}, itimerval_addr = 0x{:x}",
|
||||||
@ -80,8 +79,7 @@ pub fn sys_getitimer(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to itimerval");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to itimerval");
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current!();
|
let process_timer_manager = ctx.process.timer_manager();
|
||||||
let process_timer_manager = current.timer_manager();
|
|
||||||
let timer = match ItimerType::try_from(itimer_type)? {
|
let timer = match ItimerType::try_from(itimer_type)? {
|
||||||
ItimerType::ITIMER_REAL => process_timer_manager.alarm_timer(),
|
ItimerType::ITIMER_REAL => process_timer_manager.alarm_timer(),
|
||||||
ItimerType::ITIMER_VIRTUAL => process_timer_manager.virtual_timer(),
|
ItimerType::ITIMER_VIRTUAL => process_timer_manager.virtual_timer(),
|
||||||
|
@ -6,8 +6,8 @@ use crate::{
|
|||||||
process::{process_table, Pgid, Pid},
|
process::{process_table, Pgid, Pid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_setpgid(pid: Pid, pgid: Pgid, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_setpgid(pid: Pid, pgid: Pgid, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current = current!();
|
let current = ctx.process;
|
||||||
// if pid is 0, pid should be the pid of current process
|
// if pid is 0, pid should be the pid of current process
|
||||||
let pid = if pid == 0 { current.pid() } else { pid };
|
let pid = if pid == 0 { current.pid() } else { pid };
|
||||||
// if pgid is 0, pgid should be pid
|
// if pgid is 0, pgid should be pid
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
util::net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK},
|
util::net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_socket(domain: i32, type_: i32, protocol: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_socket(domain: i32, type_: i32, protocol: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let domain = CSocketAddrFamily::try_from(domain)?;
|
let domain = CSocketAddrFamily::try_from(domain)?;
|
||||||
let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?;
|
let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?;
|
||||||
let sock_flags = SockFlags::from_bits_truncate(type_ & !SOCK_TYPE_MASK);
|
let sock_flags = SockFlags::from_bits_truncate(type_ & !SOCK_TYPE_MASK);
|
||||||
@ -43,8 +43,7 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32, _ctx: &Context) -> Res
|
|||||||
_ => return_errno_with_message!(Errno::EAFNOSUPPORT, "unsupported domain"),
|
_ => return_errno_with_message!(Errno::EAFNOSUPPORT, "unsupported domain"),
|
||||||
};
|
};
|
||||||
let fd = {
|
let fd = {
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
|
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
|
||||||
FdFlags::CLOEXEC
|
FdFlags::CLOEXEC
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,7 +13,7 @@ pub fn sys_socketpair(
|
|||||||
type_: i32,
|
type_: i32,
|
||||||
protocol: i32,
|
protocol: i32,
|
||||||
sv: Vaddr,
|
sv: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let domain = CSocketAddrFamily::try_from(domain)?;
|
let domain = CSocketAddrFamily::try_from(domain)?;
|
||||||
let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?;
|
let sock_type = SockType::try_from(type_ & SOCK_TYPE_MASK)?;
|
||||||
@ -37,8 +37,7 @@ pub fn sys_socketpair(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let socket_fds = {
|
let socket_fds = {
|
||||||
let current = current!();
|
let mut file_table = ctx.process.file_table().lock();
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
|
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
|
||||||
FdFlags::CLOEXEC
|
FdFlags::CLOEXEC
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,11 +12,10 @@ use crate::{
|
|||||||
time::timespec_t,
|
time::timespec_t,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, stat_buf_addr = 0x{:x}", fd, stat_buf_ptr);
|
debug!("fd = {}, stat_buf_addr = 0x{:x}", fd, stat_buf_ptr);
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.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 stat = Stat::from(file.metadata());
|
let stat = Stat::from(file.metadata());
|
||||||
CurrentUserSpace::get().write_val(stat_buf_ptr, &stat)?;
|
CurrentUserSpace::get().write_val(stat_buf_ptr, &stat)?;
|
||||||
@ -61,11 +60,10 @@ pub fn sys_fstatat(
|
|||||||
return self::sys_fstat(dirfd, stat_buf_ptr, ctx);
|
return self::sys_fstat(dirfd, stat_buf_ptr, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let filename = filename.to_string_lossy();
|
let filename = filename.to_string_lossy();
|
||||||
let fs_path = FsPath::new(dirfd, filename.as_ref())?;
|
let fs_path = FsPath::new(dirfd, filename.as_ref())?;
|
||||||
let fs = current.fs().read();
|
let fs = ctx.process.fs().read();
|
||||||
if flags.contains(StatFlags::AT_SYMLINK_NOFOLLOW) {
|
if flags.contains(StatFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
fs.lookup_no_follow(&fs_path)?
|
fs.lookup_no_follow(&fs_path)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,27 +11,25 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let path = user_space.read_cstring(path_ptr, PATH_MAX)?;
|
let path = user_space.read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,);
|
debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
let fs_path = FsPath::try_from(path.as_ref())?;
|
let fs_path = FsPath::try_from(path.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
let statfs = Statfs::from(dentry.fs().sb());
|
let statfs = Statfs::from(dentry.fs().sb());
|
||||||
user_space.write_val(statfs_buf_ptr, &statfs)?;
|
user_space.write_val(statfs_buf_ptr, &statfs)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr);
|
debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr);
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.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 inode_handle = file
|
let inode_handle = file
|
||||||
.downcast_ref::<InodeHandle>()
|
.downcast_ref::<InodeHandle>()
|
||||||
|
@ -15,7 +15,7 @@ pub fn sys_symlinkat(
|
|||||||
target_addr: Vaddr,
|
target_addr: Vaddr,
|
||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
linkpath_addr: Vaddr,
|
linkpath_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let target = user_space.read_cstring(target_addr, MAX_FILENAME_LEN)?;
|
let target = user_space.read_cstring(target_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -25,7 +25,6 @@ pub fn sys_symlinkat(
|
|||||||
target, dirfd, linkpath
|
target, dirfd, linkpath
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let target = target.to_string_lossy();
|
let target = target.to_string_lossy();
|
||||||
if target.is_empty() {
|
if target.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "target is empty");
|
return_errno_with_message!(Errno::ENOENT, "target is empty");
|
||||||
@ -36,7 +35,7 @@ pub fn sys_symlinkat(
|
|||||||
return_errno_with_message!(Errno::ENOENT, "linkpath is empty");
|
return_errno_with_message!(Errno::ENOENT, "linkpath is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(dirfd, linkpath.as_ref())?;
|
let fs_path = FsPath::new(dirfd, linkpath.as_ref())?;
|
||||||
current
|
ctx.process
|
||||||
.fs()
|
.fs()
|
||||||
.read()
|
.read()
|
||||||
.lookup_dir_and_new_basename(&fs_path, false)?
|
.lookup_dir_and_new_basename(&fs_path, false)?
|
||||||
|
@ -24,7 +24,7 @@ pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8, ctx: &Context) -> Result<Sys
|
|||||||
debug!("tgid = {}, pid = {}, sig_num = {:?}", tgid, tid, sig_num);
|
debug!("tgid = {}, pid = {}, sig_num = {:?}", tgid, tid, sig_num);
|
||||||
|
|
||||||
let signal = sig_num.map(|sig_num| {
|
let signal = sig_num.map(|sig_num| {
|
||||||
let pid = current!().pid();
|
let pid = ctx.process.pid();
|
||||||
let uid = ctx.posix_thread.credentials().ruid();
|
let uid = ctx.posix_thread.credentials().ruid();
|
||||||
UserSignal::new(sig_num, UserSignalKind::Tkill, pid, uid)
|
UserSignal::new(sig_num, UserSignalKind::Tkill, pid, uid)
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,7 @@ pub fn sys_timer_settime(
|
|||||||
flags: i32,
|
flags: i32,
|
||||||
new_itimerspec_addr: Vaddr,
|
new_itimerspec_addr: Vaddr,
|
||||||
old_itimerspec_addr: Vaddr,
|
old_itimerspec_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
if new_itimerspec_addr == 0 {
|
if new_itimerspec_addr == 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
||||||
@ -24,8 +24,7 @@ pub fn sys_timer_settime(
|
|||||||
let interval = Duration::try_from(new_itimerspec.it_interval)?;
|
let interval = Duration::try_from(new_itimerspec.it_interval)?;
|
||||||
let expire_time = Duration::try_from(new_itimerspec.it_value)?;
|
let expire_time = Duration::try_from(new_itimerspec.it_value)?;
|
||||||
|
|
||||||
let current_process = current!();
|
let Some(timer) = ctx.process.timer_manager().find_posix_timer(timer_id) else {
|
||||||
let Some(timer) = current_process.timer_manager().find_posix_timer(timer_id) else {
|
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid timer ID");
|
return_errno_with_message!(Errno::EINVAL, "invalid timer ID");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,13 +59,12 @@ pub fn sys_timer_settime(
|
|||||||
pub fn sys_timer_gettime(
|
pub fn sys_timer_gettime(
|
||||||
timer_id: usize,
|
timer_id: usize,
|
||||||
itimerspec_addr: Vaddr,
|
itimerspec_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
if itimerspec_addr == 0 {
|
if itimerspec_addr == 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to return value");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to return value");
|
||||||
}
|
}
|
||||||
let current_process = current!();
|
let Some(timer) = ctx.process.timer_manager().find_posix_timer(timer_id) else {
|
||||||
let Some(timer) = current_process.timer_manager().find_posix_timer(timer_id) else {
|
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid timer ID");
|
return_errno_with_message!(Errno::EINVAL, "invalid timer ID");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,46 +11,43 @@ use crate::{
|
|||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_ftruncate(fd: FileDesc, len: isize, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, lentgh = {}", fd, len);
|
debug!("fd = {}, lentgh = {}", fd, len);
|
||||||
|
|
||||||
check_length(len)?;
|
check_length(len, ctx)?;
|
||||||
|
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
file.resize(len as usize)?;
|
file.resize(len as usize)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_truncate(path_ptr: Vaddr, len: isize, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_truncate(path_ptr: Vaddr, len: isize, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("path = {:?}, length = {}", path, len);
|
debug!("path = {:?}, length = {}", path, len);
|
||||||
|
|
||||||
check_length(len)?;
|
check_length(len, ctx)?;
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let dir_dentry = {
|
let dir_dentry = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(AT_FDCWD, path.as_ref())?;
|
let fs_path = FsPath::new(AT_FDCWD, path.as_ref())?;
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
dir_dentry.resize(len as usize)?;
|
dir_dentry.resize(len as usize)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_length(len: isize) -> Result<()> {
|
fn check_length(len: isize, ctx: &Context) -> Result<()> {
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "length is negative");
|
return_errno_with_message!(Errno::EINVAL, "length is negative");
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_file_size = {
|
let max_file_size = {
|
||||||
let current = current!();
|
let resource_limits = ctx.process.resource_limits().lock();
|
||||||
let resource_limits = current.resource_limits().lock();
|
|
||||||
resource_limits
|
resource_limits
|
||||||
.get_rlimit(ResourceType::RLIMIT_FSIZE)
|
.get_rlimit(ResourceType::RLIMIT_FSIZE)
|
||||||
.get_cur() as usize
|
.get_cur() as usize
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_umask(mask: u16, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_umask(mask: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("mask = 0o{:o}", mask);
|
debug!("mask = 0o{:o}", mask);
|
||||||
let current = current!();
|
let old_mask = ctx.process.umask().write().set(mask);
|
||||||
let old_mask = current.umask().write().set(mask);
|
|
||||||
Ok(SyscallReturn::Return(old_mask as _))
|
Ok(SyscallReturn::Return(old_mask as _))
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,13 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_umount(path_addr: Vaddr, flags: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_umount(path_addr: Vaddr, flags: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
let umount_flags = UmountFlags::from_bits_truncate(flags as u32);
|
let umount_flags = UmountFlags::from_bits_truncate(flags as u32);
|
||||||
debug!("path = {:?}, flags = {:?}", path, umount_flags);
|
debug!("path = {:?}, flags = {:?}", path, umount_flags);
|
||||||
|
|
||||||
umount_flags.check_unsupported_flags()?;
|
umount_flags.check_unsupported_flags()?;
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||||
@ -22,9 +21,9 @@ pub fn sys_umount(path_addr: Vaddr, flags: u64, _ctx: &Context) -> Result<Syscal
|
|||||||
let fs_path = FsPath::new(AT_FDCWD, path.as_ref())?;
|
let fs_path = FsPath::new(AT_FDCWD, path.as_ref())?;
|
||||||
|
|
||||||
let target_dentry = if umount_flags.contains(UmountFlags::UMOUNT_NOFOLLOW) {
|
let target_dentry = if umount_flags.contains(UmountFlags::UMOUNT_NOFOLLOW) {
|
||||||
current.fs().read().lookup_no_follow(&fs_path)?
|
ctx.process.fs().read().lookup_no_follow(&fs_path)?
|
||||||
} else {
|
} else {
|
||||||
current.fs().read().lookup(&fs_path)?
|
ctx.process.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
target_dentry.unmount()?;
|
target_dentry.unmount()?;
|
||||||
|
@ -25,7 +25,6 @@ pub fn sys_unlinkat(
|
|||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path = {:?}", dirfd, path);
|
debug!("dirfd = {}, path = {:?}", dirfd, path);
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
let (dir_dentry, name) = {
|
let (dir_dentry, name) = {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
@ -35,7 +34,7 @@ pub fn sys_unlinkat(
|
|||||||
return_errno_with_message!(Errno::EISDIR, "unlink on directory");
|
return_errno_with_message!(Errno::EISDIR, "unlink on directory");
|
||||||
}
|
}
|
||||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
current.fs().read().lookup_dir_and_base_name(&fs_path)?
|
ctx.process.fs().read().lookup_dir_and_base_name(&fs_path)?
|
||||||
};
|
};
|
||||||
dir_dentry.unlink(&name)?;
|
dir_dentry.unlink(&name)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
@ -23,7 +23,7 @@ pub fn sys_utimensat(
|
|||||||
pathname_ptr: Vaddr,
|
pathname_ptr: Vaddr,
|
||||||
timespecs_ptr: Vaddr,
|
timespecs_ptr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"utimensat: dirfd: {}, pathname_ptr: {:#x}, timespecs_ptr: {:#x}, flags: {:#x}",
|
"utimensat: dirfd: {}, pathname_ptr: {:#x}, timespecs_ptr: {:#x}, flags: {:#x}",
|
||||||
@ -41,7 +41,7 @@ pub fn sys_utimensat(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
do_utimes(dirfd, pathname_ptr, times, flags)
|
do_utimes(dirfd, pathname_ptr, times, flags, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 'sys_futimesat' system call sets the access and modification times of a file.
|
/// The 'sys_futimesat' system call sets the access and modification times of a file.
|
||||||
@ -51,32 +51,28 @@ pub fn sys_futimesat(
|
|||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
pathname_ptr: Vaddr,
|
pathname_ptr: Vaddr,
|
||||||
timeval_ptr: Vaddr,
|
timeval_ptr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"futimesat: dirfd: {}, pathname_ptr: {:#x}, timeval_ptr: {:#x}",
|
"futimesat: dirfd: {}, pathname_ptr: {:#x}, timeval_ptr: {:#x}",
|
||||||
dirfd, pathname_ptr, timeval_ptr
|
dirfd, pathname_ptr, timeval_ptr
|
||||||
);
|
);
|
||||||
do_futimesat(dirfd, pathname_ptr, timeval_ptr)
|
do_futimesat(dirfd, pathname_ptr, timeval_ptr, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 'sys_utimes' system call sets the access and modification times of a file.
|
/// The 'sys_utimes' system call sets the access and modification times of a file.
|
||||||
/// It receives time values in the form of timeval structures like 'sys_futimesat',
|
/// It receives time values in the form of timeval structures like 'sys_futimesat',
|
||||||
/// but it uses the current working directory as the base directory.
|
/// but it uses the current working directory as the base directory.
|
||||||
pub fn sys_utimes(
|
pub fn sys_utimes(pathname_ptr: Vaddr, timeval_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
pathname_ptr: Vaddr,
|
|
||||||
timeval_ptr: Vaddr,
|
|
||||||
_ctx: &Context,
|
|
||||||
) -> Result<SyscallReturn> {
|
|
||||||
debug!(
|
debug!(
|
||||||
"utimes: pathname_ptr: {:#x}, timeval_ptr: {:#x}",
|
"utimes: pathname_ptr: {:#x}, timeval_ptr: {:#x}",
|
||||||
pathname_ptr, timeval_ptr
|
pathname_ptr, timeval_ptr
|
||||||
);
|
);
|
||||||
do_futimesat(AT_FDCWD, pathname_ptr, timeval_ptr)
|
do_futimesat(AT_FDCWD, pathname_ptr, timeval_ptr, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 'sys_utime' system call is similar to 'sys_utimes' but uses the older 'utimbuf' structure to specify times.
|
/// The 'sys_utime' system call is similar to 'sys_utimes' but uses the older 'utimbuf' structure to specify times.
|
||||||
pub fn sys_utime(pathname_ptr: Vaddr, utimbuf_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_utime(pathname_ptr: Vaddr, utimbuf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"utime: pathname_ptr: {:#x}, utimbuf_ptr: {:#x}",
|
"utime: pathname_ptr: {:#x}, utimbuf_ptr: {:#x}",
|
||||||
pathname_ptr, utimbuf_ptr
|
pathname_ptr, utimbuf_ptr
|
||||||
@ -95,7 +91,7 @@ pub fn sys_utime(pathname_ptr: Vaddr, utimbuf_ptr: Vaddr, _ctx: &Context) -> Res
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
do_utimes(AT_FDCWD, pathname_ptr, times, 0)
|
do_utimes(AT_FDCWD, pathname_ptr, times, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structure to hold access and modification times
|
// Structure to hold access and modification times
|
||||||
@ -156,6 +152,7 @@ fn do_utimes(
|
|||||||
pathname_ptr: Vaddr,
|
pathname_ptr: Vaddr,
|
||||||
times: Option<TimeSpecPair>,
|
times: Option<TimeSpecPair>,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = UtimensFlags::from_bits(flags)
|
let flags = UtimensFlags::from_bits(flags)
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
.ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
||||||
@ -166,11 +163,10 @@ fn do_utimes(
|
|||||||
let cstring = CurrentUserSpace::get().read_cstring(pathname_ptr, MAX_FILENAME_LEN)?;
|
let cstring = CurrentUserSpace::get().read_cstring(pathname_ptr, MAX_FILENAME_LEN)?;
|
||||||
cstring.to_string_lossy().into_owned()
|
cstring.to_string_lossy().into_owned()
|
||||||
};
|
};
|
||||||
let current = current!();
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
// Determine the file system path and the corresponding entry
|
// Determine the file system path and the corresponding entry
|
||||||
let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
|
let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
|
||||||
let fs = current.fs().read();
|
let fs = ctx.process.fs().read();
|
||||||
if flags.contains(UtimensFlags::AT_SYMLINK_NOFOLLOW) {
|
if flags.contains(UtimensFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
fs.lookup_no_follow(&fs_path)?
|
fs.lookup_no_follow(&fs_path)?
|
||||||
} else {
|
} else {
|
||||||
@ -183,7 +179,12 @@ fn do_utimes(
|
|||||||
|
|
||||||
// Sets the access and modification times for a file,
|
// Sets the access and modification times for a file,
|
||||||
// specified by a pathname relative to the directory file descriptor `dirfd`.
|
// specified by a pathname relative to the directory file descriptor `dirfd`.
|
||||||
fn do_futimesat(dirfd: FileDesc, pathname_ptr: Vaddr, timeval_ptr: Vaddr) -> Result<SyscallReturn> {
|
fn do_futimesat(
|
||||||
|
dirfd: FileDesc,
|
||||||
|
pathname_ptr: Vaddr,
|
||||||
|
timeval_ptr: Vaddr,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let times = if timeval_ptr != 0 {
|
let times = if timeval_ptr != 0 {
|
||||||
let (autime, mutime) = read_time_from_user::<timeval_t>(timeval_ptr)?;
|
let (autime, mutime) = read_time_from_user::<timeval_t>(timeval_ptr)?;
|
||||||
if autime.usec >= 1000000 || autime.usec < 0 || mutime.usec >= 1000000 || mutime.usec < 0 {
|
if autime.usec >= 1000000 || autime.usec < 0 || mutime.usec >= 1000000 || mutime.usec < 0 {
|
||||||
@ -197,7 +198,7 @@ fn do_futimesat(dirfd: FileDesc, pathname_ptr: Vaddr, timeval_ptr: Vaddr) -> Res
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
do_utimes(dirfd, pathname_ptr, times, 0)
|
do_utimes(dirfd, pathname_ptr, times, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_time_from_user<T: Pod>(time_ptr: Vaddr) -> Result<(T, T)> {
|
fn read_time_from_user<T: Pod>(time_ptr: Vaddr) -> Result<(T, T)> {
|
||||||
|
@ -11,7 +11,7 @@ pub fn sys_wait4(
|
|||||||
exit_status_ptr: u64,
|
exit_status_ptr: u64,
|
||||||
wait_options: u32,
|
wait_options: u32,
|
||||||
rusage_addr: Vaddr,
|
rusage_addr: Vaddr,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let wait_options = WaitOptions::from_bits(wait_options)
|
let wait_options = WaitOptions::from_bits(wait_options)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown wait option"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown wait option"))?;
|
||||||
@ -19,7 +19,7 @@ pub fn sys_wait4(
|
|||||||
"pid = {}, exit_status_ptr = {}, wait_options: {:?}",
|
"pid = {}, exit_status_ptr = {}, wait_options: {:?}",
|
||||||
wait_pid as i32, exit_status_ptr, wait_options
|
wait_pid as i32, exit_status_ptr, wait_options
|
||||||
);
|
);
|
||||||
debug!("wait4 current pid = {}", current!().pid());
|
debug!("wait4 current pid = {}", ctx.process.pid());
|
||||||
let process_filter = ProcessFilter::from_id(wait_pid as _);
|
let process_filter = ProcessFilter::from_id(wait_pid as _);
|
||||||
|
|
||||||
let waited_process = wait_child_exit(process_filter, wait_options)?;
|
let waited_process = wait_child_exit(process_filter, wait_options)?;
|
||||||
|
@ -7,7 +7,7 @@ pub fn sys_write(
|
|||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
user_buf_ptr: Vaddr,
|
user_buf_ptr: Vaddr,
|
||||||
user_buf_len: usize,
|
user_buf_len: usize,
|
||||||
_ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}",
|
||||||
@ -15,8 +15,7 @@ pub fn sys_write(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let current = current!();
|
let file_table = ctx.process.file_table().lock();
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
file_table.get_file(fd)?.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user