From bc5ddaf6144f7c1ee2b7453d94261cc8aedb7339 Mon Sep 17 00:00:00 2001 From: lhw2002426 <1466397747@qq.com> Date: Tue, 17 Sep 2024 16:38:02 +0800 Subject: [PATCH] fix bug of sys_rt_sigaction, sys_poll, add sys_clock_nanosleep, sys_getsockopt --- api/ruxos_posix_api/build.rs | 2 + api/ruxos_posix_api/src/imp/io_mpx/poll.rs | 4 ++ api/ruxos_posix_api/src/imp/net.rs | 82 ++++++++++++++++++++-- api/ruxos_posix_api/src/imp/rt_sig.rs | 18 +++-- api/ruxos_posix_api/src/imp/time.rs | 49 ++++++++++++- api/ruxos_posix_api/src/lib.rs | 7 +- modules/ruxnet/src/lwip_impl/tcp.rs | 6 ++ modules/ruxnet/src/smoltcp_impl/tcp.rs | 11 +-- ulib/ruxlibc/src/time.rs | 15 +++- ulib/ruxmusl/src/aarch64/mod.rs | 14 ++++ ulib/ruxmusl/src/aarch64/syscall_id.rs | 3 + ulib/ruxmusl/src/riscv64/mod.rs | 14 ++++ ulib/ruxmusl/src/riscv64/syscall_id.rs | 3 + ulib/ruxmusl/src/x86_64/mod.rs | 16 +++++ ulib/ruxmusl/src/x86_64/syscall_id.rs | 5 ++ 15 files changed, 226 insertions(+), 23 deletions(-) diff --git a/api/ruxos_posix_api/build.rs b/api/ruxos_posix_api/build.rs index a5b17661b..554cf15c6 100644 --- a/api/ruxos_posix_api/build.rs +++ b/api/ruxos_posix_api/build.rs @@ -110,7 +110,9 @@ typedef struct {{ let allow_vars = [ "O_.*", "AF_.*", + "SO_.*", "SOCK_.*", + "SOL_.*", "IPPROTO_.*", "FD_.*", "F_.*", diff --git a/api/ruxos_posix_api/src/imp/io_mpx/poll.rs b/api/ruxos_posix_api/src/imp/io_mpx/poll.rs index d9aa4ff70..bef195137 100644 --- a/api/ruxos_posix_api/src/imp/io_mpx/poll.rs +++ b/api/ruxos_posix_api/src/imp/io_mpx/poll.rs @@ -71,6 +71,10 @@ pub unsafe fn sys_poll(fds: *mut ctypes::pollfd, nfds: ctypes::nfds_t, timeout: let fds = core::slice::from_raw_parts_mut(fds, nfds as usize); let deadline = (!timeout.is_negative()) .then(|| current_time() + Duration::from_millis(timeout as u64)); + for pollfd_item in fds.iter_mut() { + let revents = &mut pollfd_item.revents; + *revents &= 0; + } loop { #[cfg(feature = "net")] ruxnet::poll_interfaces(); diff --git a/api/ruxos_posix_api/src/imp/net.rs b/api/ruxos_posix_api/src/imp/net.rs index ef8465aba..80c0bbab6 100644 --- a/api/ruxos_posix_api/src/imp/net.rs +++ b/api/ruxos_posix_api/src/imp/net.rs @@ -1,11 +1,11 @@ /* Copyright (c) [2023] [Syswonder Community] - * [Ruxos] is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ use alloc::{sync::Arc, vec, vec::Vec}; use core::ffi::{c_char, c_int, c_void}; @@ -601,6 +601,74 @@ pub unsafe fn sys_getsockname( }) } +/// get socket option +/// +/// TODO: some options not impl, just return 0, like SO_RCVBUF SO_SNDBUF +pub fn sys_getsockopt( + socket_fd: c_int, + level: c_int, + optname: c_int, + optval: *mut c_void, + optlen: *mut ctypes::socklen_t, +) -> c_int { + unsafe { + info!( + "sys_getsockopt <= fd: {}, level: {}, optname: {}, optlen: {}, IGNORED", + socket_fd, + level, + optname, + core::ptr::read(optlen as *mut usize) + ); + } + syscall_body!(sys_getsockopt, { + return Ok(0); + if optval.is_null() { + return Err(LinuxError::EFAULT); + } + let socket = Socket::from_fd(socket_fd)?; + match level as u32 { + ctypes::SOL_SOCKET => { + let val = match optname as u32 { + ctypes::SO_ACCEPTCONN => match &*socket { + Socket::Udp(_) => 0, + Socket::Tcp(tcpsocket) => { + if tcpsocket.lock().is_listening() { + 1 + } else { + 0 + } + } + }, + ctypes::SO_TYPE => match &*socket { + Socket::Udp(_) => ctypes::SOCK_DGRAM, + Socket::Tcp(_) => ctypes::SOCK_STREAM, + }, + ctypes::SO_RCVLOWAT | ctypes::SO_SNDLOWAT | ctypes::SO_BROADCAST => 1, + ctypes::SO_ERROR + | ctypes::SO_DONTROUTE + | ctypes::SO_KEEPALIVE + | ctypes::SO_LINGER + | ctypes::SO_OOBINLINE + | ctypes::SO_RCVBUF + | ctypes::SO_RCVTIMEO + | ctypes::SO_REUSEADDR + | ctypes::SO_SNDBUF + | ctypes::SO_SNDTIMEO => 0, + _ => return Err(LinuxError::ENOPROTOOPT), + }; + + unsafe { + core::ptr::write(optlen as *mut usize, core::mem::size_of::()); + core::ptr::write(optval as *mut i32, val as i32); + } + + Ok(0) + } + _ => Err(LinuxError::ENOSYS), + } + }) +} + /// Get peer address to which the socket sockfd is connected. pub unsafe fn sys_getpeername( sock_fd: c_int, diff --git a/api/ruxos_posix_api/src/imp/rt_sig.rs b/api/ruxos_posix_api/src/imp/rt_sig.rs index 9387a3a7b..8d89cf6aa 100644 --- a/api/ruxos_posix_api/src/imp/rt_sig.rs +++ b/api/ruxos_posix_api/src/imp/rt_sig.rs @@ -87,6 +87,8 @@ pub fn sys_rt_sigprocmask( } /// sigaction syscall for A64 musl +/// +/// TODO: if sa is 0, return now action pub unsafe fn sys_rt_sigaction( sig: c_int, sa: *const ctypes::sigaction, @@ -95,12 +97,16 @@ pub unsafe fn sys_rt_sigaction( ) -> c_int { debug!("sys_rt_sigaction <= sig: {}", sig); syscall_body!(sys_rt_sigaction, { - let sa = unsafe { *sa }; - let old = unsafe { *old }; - let sa = k_sigaction::from(sa); - let mut old_sa = k_sigaction::from(old); - sys_sigaction(sig as _, Some(&sa), Some(&mut old_sa)); - Ok(0) + if sa as u64 == 0 || old as u64 == 0 { + Err(LinuxError::EFAULT) + } else { + let sa = unsafe { *sa }; + let old = unsafe { *old }; + let sa = k_sigaction::from(sa); + let mut old_sa = k_sigaction::from(old); + sys_sigaction(sig as _, Some(&sa), Some(&mut old_sa)); + Ok(0) + } }) } diff --git a/api/ruxos_posix_api/src/imp/time.rs b/api/ruxos_posix_api/src/imp/time.rs index 2fa61c80e..99b0a2027 100644 --- a/api/ruxos_posix_api/src/imp/time.rs +++ b/api/ruxos_posix_api/src/imp/time.rs @@ -14,6 +14,9 @@ use crate::ctypes; use axerrno::LinuxError; +// nanoseconds per a second +const NANO_PER_SECOND: i64 = 1000000000; + impl From for Duration { fn from(ts: ctypes::timespec) -> Self { Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32) @@ -74,13 +77,57 @@ pub unsafe fn sys_clock_settime(_clk: ctypes::clockid_t, ts: *const ctypes::time }) } +/// Sleep until some nanoseconds +/// +/// TODO: should be woken by signals, and set errno +/// TODO: deal with flags +pub unsafe fn sys_clock_nanosleep( + which_clock: ctypes::clockid_t, + flags: c_int, + req: *const ctypes::timespec, + rem: *mut ctypes::timespec, +) -> c_int { + syscall_body!(sys_clock_nanosleep, { + unsafe { + if req.is_null() || (*req).tv_nsec < 0 || (*req).tv_nsec >= NANO_PER_SECOND { + return Err(LinuxError::EINVAL); + } + } + + let deadline = unsafe { Duration::from(*req) }; + + let now = ruxhal::time::current_time(); + + if now >= deadline { + return Ok(0); + } + + #[cfg(feature = "multitask")] + ruxtask::sleep_until(deadline); + #[cfg(not(feature = "multitask"))] + ruxhal::time::busy_wait_until(deadline); + + let after = ruxhal::time::current_time(); + let actual = after - now; + let due = deadline - now; + + if let Some(diff) = due.checked_sub(actual) { + if !rem.is_null() { + unsafe { (*rem) = diff.into() }; + } + return Err(LinuxError::EINTR); + } + Ok(0) + }) +} + /// Sleep some nanoseconds /// /// TODO: should be woken by signals, and set errno pub unsafe fn sys_nanosleep(req: *const ctypes::timespec, rem: *mut ctypes::timespec) -> c_int { syscall_body!(sys_nanosleep, { unsafe { - if req.is_null() || (*req).tv_nsec < 0 || (*req).tv_nsec > 999999999 { + if req.is_null() || (*req).tv_nsec < 0 || (*req).tv_nsec >= NANO_PER_SECOND { return Err(LinuxError::EINVAL); } } diff --git a/api/ruxos_posix_api/src/lib.rs b/api/ruxos_posix_api/src/lib.rs index 4e1c44086..4c6517d85 100644 --- a/api/ruxos_posix_api/src/lib.rs +++ b/api/ruxos_posix_api/src/lib.rs @@ -58,7 +58,8 @@ pub use imp::sys::{sys_sysinfo, sys_uname}; pub use imp::sys_invalid; pub use imp::task::{sys_exit, sys_getpid, sys_getppid, sys_gettid, sys_sched_yield}; pub use imp::time::{ - sys_clock_gettime, sys_clock_settime, sys_gettimeofday, sys_nanosleep, sys_times, + sys_clock_gettime, sys_clock_nanosleep, sys_clock_settime, sys_gettimeofday, sys_nanosleep, + sys_times, }; #[cfg(all(feature = "fd", feature = "musl"))] @@ -85,8 +86,8 @@ pub use imp::mmap::{sys_madvise, sys_mmap, sys_mprotect, sys_mremap, sys_msync, #[cfg(feature = "net")] pub use imp::net::{ sys_accept, sys_bind, sys_connect, sys_freeaddrinfo, sys_getaddrinfo, sys_getpeername, - sys_getsockname, sys_listen, sys_recv, sys_recvfrom, sys_send, sys_sendmsg, sys_sendto, - sys_setsockopt, sys_shutdown, sys_socket, + sys_getsockname, sys_getsockopt, sys_listen, sys_recv, sys_recvfrom, sys_send, sys_sendmsg, + sys_sendto, sys_setsockopt, sys_shutdown, sys_socket, }; #[cfg(feature = "pipe")] pub use imp::pipe::{sys_pipe, sys_pipe2}; diff --git a/modules/ruxnet/src/lwip_impl/tcp.rs b/modules/ruxnet/src/lwip_impl/tcp.rs index 2c621f0eb..15a09961f 100644 --- a/modules/ruxnet/src/lwip_impl/tcp.rs +++ b/modules/ruxnet/src/lwip_impl/tcp.rs @@ -191,6 +191,12 @@ impl TcpSocket { } } + /// Returens if this socket is listening + #[inline] + pub fn is_listening(&self) -> bool { + unsafe { (*self.pcb.get()).state == tcp_state_LISTEN } + } + /// Returns whether this socket is in nonblocking mode. #[inline] pub fn is_nonblocking(&self) -> bool { diff --git a/modules/ruxnet/src/smoltcp_impl/tcp.rs b/modules/ruxnet/src/smoltcp_impl/tcp.rs index de9c14fd5..fb2c43690 100644 --- a/modules/ruxnet/src/smoltcp_impl/tcp.rs +++ b/modules/ruxnet/src/smoltcp_impl/tcp.rs @@ -108,6 +108,12 @@ impl TcpSocket { } } + /// Returens if this socket is listening + #[inline] + pub fn is_listening(&self) -> bool { + self.get_state() == STATE_LISTENING + } + /// Returns whether this socket is in nonblocking mode. #[inline] pub fn is_nonblocking(&self) -> bool { @@ -423,11 +429,6 @@ impl TcpSocket { self.get_state() == STATE_CONNECTED } - #[inline] - fn is_listening(&self) -> bool { - self.get_state() == STATE_LISTENING - } - fn bound_endpoint(&self) -> AxResult { // SAFETY: no other threads can read or write `self.local_addr`. let local_addr = unsafe { self.local_addr.get().read() }; diff --git a/ulib/ruxlibc/src/time.rs b/ulib/ruxlibc/src/time.rs index d124a1c32..ff26e5ace 100644 --- a/ulib/ruxlibc/src/time.rs +++ b/ulib/ruxlibc/src/time.rs @@ -8,7 +8,7 @@ */ use core::ffi::c_int; -use ruxos_posix_api::{sys_clock_gettime, sys_clock_settime, sys_nanosleep}; +use ruxos_posix_api::{sys_clock_gettime, sys_clock_nanosleep, sys_clock_settime, sys_nanosleep}; #[cfg(feature = "signal")] use ruxos_posix_api::{sys_getitimer, sys_setitimer}; @@ -26,6 +26,19 @@ pub unsafe extern "C" fn clock_settime(clk: ctypes::clockid_t, ts: *mut ctypes:: e(sys_clock_settime(clk, ts)) } +/// Sleep until some nanoseconds +/// +/// TODO: should be woken by signals, and set errno +#[no_mangle] +pub unsafe extern "C" fn clock_nanosleep( + which_clock: ctypes::clockid_t, + flags: c_int, + req: *const ctypes::timespec, + rem: *mut ctypes::timespec, +) -> c_int { + e(sys_clock_nanosleep(which_clock, flags, req, rem)) +} + /// Sleep some nanoseconds /// /// TODO: should be woken by signals, and set errno diff --git a/ulib/ruxmusl/src/aarch64/mod.rs b/ulib/ruxmusl/src/aarch64/mod.rs index 519972584..fd8697d67 100644 --- a/ulib/ruxmusl/src/aarch64/mod.rs +++ b/ulib/ruxmusl/src/aarch64/mod.rs @@ -224,6 +224,12 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[0] as ctypes::clockid_t, args[1] as *mut ctypes::timespec, ) as _, + SyscallId::CLOCK_NANOSLEEP => ruxos_posix_api::sys_clock_nanosleep( + args[0] as ctypes::clockid_t, + args[1] as c_int, + args[2] as *const ctypes::timespec, + args[3] as *mut ctypes::timespec, + ) as _, SyscallId::SCHED_YIELD => ruxos_posix_api::sys_sched_yield() as _, #[cfg(feature = "signal")] SyscallId::KILL => ruxos_posix_api::sys_kill(args[0] as pid_t, args[1] as c_int) as _, @@ -338,6 +344,14 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[4] as ctypes::socklen_t, ) as _, #[cfg(feature = "net")] + SyscallId::GETSOCKOPT => ruxos_posix_api::sys_getsockopt( + args[0] as c_int, + args[1] as c_int, + args[2] as c_int, + args[3] as *mut core::ffi::c_void, + args[4] as *mut ctypes::socklen_t, + ) as _, + #[cfg(feature = "net")] SyscallId::SHUTDOWN => { ruxos_posix_api::sys_shutdown(args[0] as c_int, args[1] as c_int) as _ } diff --git a/ulib/ruxmusl/src/aarch64/syscall_id.rs b/ulib/ruxmusl/src/aarch64/syscall_id.rs index 2eff2855b..123561255 100644 --- a/ulib/ruxmusl/src/aarch64/syscall_id.rs +++ b/ulib/ruxmusl/src/aarch64/syscall_id.rs @@ -80,6 +80,7 @@ pub enum SyscallId { NANO_SLEEP = 101, CLOCK_SETTIME = 112, CLOCK_GETTIME = 113, + CLOCK_NANOSLEEP = 115, SCHED_YIELD = 124, #[cfg(feature = "signal")] KILL = 129, @@ -130,6 +131,8 @@ pub enum SyscallId { #[cfg(feature = "net")] SETSOCKOPT = 208, #[cfg(feature = "net")] + GETSOCKOPT = 209, + #[cfg(feature = "net")] SHUTDOWN = 210, #[cfg(feature = "net")] SENDMSG = 211, diff --git a/ulib/ruxmusl/src/riscv64/mod.rs b/ulib/ruxmusl/src/riscv64/mod.rs index 186d8c147..87e9add8a 100644 --- a/ulib/ruxmusl/src/riscv64/mod.rs +++ b/ulib/ruxmusl/src/riscv64/mod.rs @@ -191,6 +191,12 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[0] as ctypes::clockid_t, args[1] as *mut ctypes::timespec, ) as _, + SyscallId::CLOCK_NANOSLEEP => ruxos_posix_api::sys_clock_nanosleep( + args[0] as ctypes::clockid_t, + args[1] as c_int, + args[2] as *const ctypes::timespec, + args[3] as *mut ctypes::timespec, + ) as _, SyscallId::SCHED_YIELD => ruxos_posix_api::sys_sched_yield() as _, #[cfg(feature = "signal")] SyscallId::SIGALTSTACK => ruxos_posix_api::sys_sigaltstack( @@ -292,6 +298,14 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[4] as ctypes::socklen_t, ) as _, #[cfg(feature = "net")] + SyscallId::GETSOCKOPT => ruxos_posix_api::sys_getsockopt( + args[0] as c_int, + args[1] as c_int, + args[2] as c_int, + args[3] as *mut core::ffi::c_void, + args[4] as *mut ctypes::socklen_t, + ) as _, + #[cfg(feature = "net")] SyscallId::SHUTDOWN => { ruxos_posix_api::sys_shutdown(args[0] as c_int, args[1] as c_int) as _ } diff --git a/ulib/ruxmusl/src/riscv64/syscall_id.rs b/ulib/ruxmusl/src/riscv64/syscall_id.rs index ed5087e4b..769945f33 100644 --- a/ulib/ruxmusl/src/riscv64/syscall_id.rs +++ b/ulib/ruxmusl/src/riscv64/syscall_id.rs @@ -69,6 +69,7 @@ pub enum SyscallId { NANO_SLEEP = 101, CLOCK_SETTIME = 112, CLOCK_GETTIME = 113, + CLOCK_NANOSLEEP = 115, SCHED_YIELD = 124, #[cfg(feature = "signal")] SIGALTSTACK = 132, @@ -106,6 +107,8 @@ pub enum SyscallId { #[cfg(feature = "net")] SETSOCKOPT = 208, #[cfg(feature = "net")] + GETSOCKOPT = 209, + #[cfg(feature = "net")] SHUTDOWN = 210, #[cfg(feature = "net")] SENDMSG = 211, diff --git a/ulib/ruxmusl/src/x86_64/mod.rs b/ulib/ruxmusl/src/x86_64/mod.rs index 16a467dfe..fd518e4aa 100644 --- a/ulib/ruxmusl/src/x86_64/mod.rs +++ b/ulib/ruxmusl/src/x86_64/mod.rs @@ -274,6 +274,15 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[4] as ctypes::socklen_t, ) as _, + #[cfg(feature = "net")] + SyscallId::GETSOCKOPT => ruxos_posix_api::sys_getsockopt( + args[0] as c_int, + args[1] as c_int, + args[2] as c_int, + args[3] as *mut c_void, + args[4] as *mut ctypes::socklen_t, + ) as _, + #[cfg(feature = "multitask")] SyscallId::CLONE => ruxos_posix_api::sys_clone( args[0] as c_int, @@ -445,6 +454,13 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize { args[1] as *mut ctypes::timespec, ) as _, + SyscallId::CLOCK_NANOSLEEP => ruxos_posix_api::sys_clock_nanosleep( + args[0] as ctypes::clockid_t, + args[1] as c_int, + args[2] as *const ctypes::timespec, + args[3] as *mut ctypes::timespec, + ) as _, + #[cfg(feature = "epoll")] SyscallId::EPOLL_WAIT => ruxos_posix_api::sys_epoll_wait( args[0] as c_int, diff --git a/ulib/ruxmusl/src/x86_64/syscall_id.rs b/ulib/ruxmusl/src/x86_64/syscall_id.rs index 1526154cb..cd7b5e704 100644 --- a/ulib/ruxmusl/src/x86_64/syscall_id.rs +++ b/ulib/ruxmusl/src/x86_64/syscall_id.rs @@ -126,6 +126,9 @@ pub enum SyscallId { #[cfg(feature = "net")] SETSOCKOPT = 54, + #[cfg(feature = "net")] + GETSOCKOPT = 55, + // TODO: check clone #[cfg(feature = "multitask")] CLONE = 56, @@ -223,6 +226,8 @@ pub enum SyscallId { CLOCK_GETTIME = 228, + CLOCK_NANOSLEEP = 230, + #[cfg(feature = "epoll")] EPOLL_WAIT = 232,