Skip to content

Commit

Permalink
fix bug of sys_rt_sigaction, sys_poll, add sys_clock_nanosleep, sys_g…
Browse files Browse the repository at this point in the history
…etsockopt
  • Loading branch information
lhw2002426 committed Sep 17, 2024
1 parent 0d5ebe0 commit bc5ddaf
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 23 deletions.
2 changes: 2 additions & 0 deletions api/ruxos_posix_api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ typedef struct {{
let allow_vars = [
"O_.*",
"AF_.*",
"SO_.*",
"SOCK_.*",
"SOL_.*",
"IPPROTO_.*",
"FD_.*",
"F_.*",
Expand Down
4 changes: 4 additions & 0 deletions api/ruxos_posix_api/src/imp/io_mpx/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
82 changes: 75 additions & 7 deletions api/ruxos_posix_api/src/imp/net.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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::<i32>());
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,
Expand Down
18 changes: 12 additions & 6 deletions api/ruxos_posix_api/src/imp/rt_sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
}
})
}

Expand Down
49 changes: 48 additions & 1 deletion api/ruxos_posix_api/src/imp/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use crate::ctypes;

use axerrno::LinuxError;

// nanoseconds per a second
const NANO_PER_SECOND: i64 = 1000000000;

impl From<ctypes::timespec> for Duration {
fn from(ts: ctypes::timespec) -> Self {
Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32)
Expand Down Expand Up @@ -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);
}
}
Expand Down
7 changes: 4 additions & 3 deletions api/ruxos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand All @@ -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};
Expand Down
6 changes: 6 additions & 0 deletions modules/ruxnet/src/lwip_impl/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
11 changes: 6 additions & 5 deletions modules/ruxnet/src/smoltcp_impl/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<IpListenEndpoint> {
// SAFETY: no other threads can read or write `self.local_addr`.
let local_addr = unsafe { self.local_addr.get().read() };
Expand Down
15 changes: 14 additions & 1 deletion ulib/ruxlibc/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions ulib/ruxmusl/src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 _,
Expand Down Expand Up @@ -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 _
}
Expand Down
3 changes: 3 additions & 0 deletions ulib/ruxmusl/src/aarch64/syscall_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions ulib/ruxmusl/src/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 _
}
Expand Down
3 changes: 3 additions & 0 deletions ulib/ruxmusl/src/riscv64/syscall_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit bc5ddaf

Please sign in to comment.