mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-14 07:46:48 +00:00
Enable syscall restart
This commit is contained in:
parent
ced0023d6b
commit
1b56a8b600
@ -49,7 +49,11 @@ fn do_accept(
|
|||||||
) -> 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)?;
|
||||||
socket.accept()?
|
socket.accept().map_err(|err| match err.error() {
|
||||||
|
// FIXME: `accept` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
if flags.contains(Flags::SOCK_NONBLOCK) {
|
if flags.contains(Flags::SOCK_NONBLOCK) {
|
||||||
|
@ -17,6 +17,12 @@ pub fn sys_connect(
|
|||||||
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
|
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
|
||||||
|
|
||||||
let socket = get_socket_from_fd(sockfd)?;
|
let socket = get_socket_from_fd(sockfd)?;
|
||||||
socket.connect(socket_addr)?;
|
socket
|
||||||
|
.connect(socket_addr)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
// FIXME: `connect` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,10 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, ctx: &Context) -> Result<Sysc
|
|||||||
FcntlCmd::F_SETFL => handle_setfl(fd, arg, ctx),
|
FcntlCmd::F_SETFL => handle_setfl(fd, arg, ctx),
|
||||||
FcntlCmd::F_GETLK => handle_getlk(fd, arg, ctx),
|
FcntlCmd::F_GETLK => handle_getlk(fd, arg, ctx),
|
||||||
FcntlCmd::F_SETLK => handle_setlk(fd, arg, true, ctx),
|
FcntlCmd::F_SETLK => handle_setlk(fd, arg, true, ctx),
|
||||||
FcntlCmd::F_SETLKW => handle_setlk(fd, arg, false, ctx),
|
FcntlCmd::F_SETLKW => handle_setlk(fd, arg, false, ctx).map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
}),
|
||||||
FcntlCmd::F_GETOWN => handle_getown(fd, ctx),
|
FcntlCmd::F_GETOWN => handle_getown(fd, ctx),
|
||||||
FcntlCmd::F_SETOWN => handle_setown(fd, arg, ctx),
|
FcntlCmd::F_SETOWN => handle_setown(fd, arg, ctx),
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,12 @@ pub fn sys_flock(fd: FileDesc, ops: i32, ctx: &Context) -> Result<SyscallReturn>
|
|||||||
let type_ = FlockType::from(ops);
|
let type_ = FlockType::from(ops);
|
||||||
FlockItem::new(&file, type_)
|
FlockItem::new(&file, type_)
|
||||||
};
|
};
|
||||||
inode_file.set_flock(flock, is_nonblocking)?;
|
inode_file
|
||||||
|
.set_flock(flock, is_nonblocking)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -136,13 +136,10 @@ pub fn sys_futex(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "unsupported futex op");
|
return_errno_with_message!(Errno::EINVAL, "unsupported futex op");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map_err(|e| {
|
.map_err(|err| match err.error() {
|
||||||
// From Linux manual, Futex returns `ETIMEDOUT` instead of `ETIME`
|
Errno::ETIME => Error::new(Errno::ETIMEDOUT),
|
||||||
if e.error() == Errno::ETIME {
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
Error::with_message(Errno::ETIMEDOUT, "futex wait timeout")
|
_ => err,
|
||||||
} else {
|
|
||||||
e
|
|
||||||
}
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
debug!("futex returns, tid= {} ", ctx.posix_thread.tid());
|
debug!("futex returns, tid= {} ", ctx.posix_thread.tid());
|
||||||
|
@ -56,6 +56,7 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<Sy
|
|||||||
entry.set_flags(entry.flags() & (!FdFlags::CLOEXEC));
|
entry.set_flags(entry.flags() & (!FdFlags::CLOEXEC));
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
// FIXME: ioctl operations involving blocking I/O should be able to restart if interrupted
|
||||||
_ => file.ioctl(ioctl_cmd, arg)?,
|
_ => file.ioctl(ioctl_cmd, arg)?,
|
||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
|
@ -33,7 +33,11 @@ pub fn sys_openat(
|
|||||||
.fs()
|
.fs()
|
||||||
.resolver()
|
.resolver()
|
||||||
.read()
|
.read()
|
||||||
.open(&fs_path, flags, mask_mode)?;
|
.open(&fs_path, flags, mask_mode)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
Arc::new(inode_handle)
|
Arc::new(inode_handle)
|
||||||
};
|
};
|
||||||
let mut file_table = current.file_table().lock();
|
let mut file_table = current.file_table().lock();
|
||||||
|
@ -22,16 +22,22 @@ pub fn sys_read(
|
|||||||
// According to <https://man7.org/linux/man-pages/man2/read.2.html>, if
|
// According to <https://man7.org/linux/man-pages/man2/read.2.html>, if
|
||||||
// the user specified an empty buffer, we should detect errors by checking
|
// the user specified an empty buffer, we should detect errors by checking
|
||||||
// the file descriptor. If no errors detected, return 0 successfully.
|
// the file descriptor. If no errors detected, return 0 successfully.
|
||||||
let read_len = if buf_len != 0 {
|
let read_len = {
|
||||||
let mut writer = ctx
|
if buf_len != 0 {
|
||||||
.process
|
let mut writer = ctx
|
||||||
.root_vmar()
|
.process
|
||||||
.vm_space()
|
.root_vmar()
|
||||||
.writer(user_buf_addr, buf_len)?;
|
.vm_space()
|
||||||
file.read(&mut writer)?
|
.writer(user_buf_addr, buf_len)?;
|
||||||
} else {
|
file.read(&mut writer)
|
||||||
file.read_bytes(&mut [])?
|
} else {
|
||||||
};
|
file.read_bytes(&mut [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(read_len as _))
|
Ok(SyscallReturn::Return(read_len as _))
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,14 @@ pub fn sys_recvfrom(
|
|||||||
vm_space.writer(buf, len)?
|
vm_space.writer(buf, len)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let (recv_size, message_header) = socket.recvmsg(&mut writers, flags)?;
|
let (recv_size, message_header) =
|
||||||
|
socket
|
||||||
|
.recvmsg(&mut writers, flags)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
// FIXME: `recvfrom` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
|
|
||||||
if let Some(socket_addr) = message_header.addr()
|
if let Some(socket_addr) = message_header.addr()
|
||||||
&& src_addr != 0
|
&& src_addr != 0
|
||||||
|
@ -25,7 +25,13 @@ pub fn sys_recvmsg(
|
|||||||
let (total_bytes, message_header) = {
|
let (total_bytes, message_header) = {
|
||||||
let socket = get_socket_from_fd(sockfd)?;
|
let socket = get_socket_from_fd(sockfd)?;
|
||||||
let mut io_vec_writer = c_user_msghdr.copy_writer_array_from_user(ctx)?;
|
let mut io_vec_writer = c_user_msghdr.copy_writer_array_from_user(ctx)?;
|
||||||
socket.recvmsg(&mut io_vec_writer, flags)?
|
socket
|
||||||
|
.recvmsg(&mut io_vec_writer, flags)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
// FIXME: `recvmsg` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(addr) = message_header.addr() {
|
if let Some(addr) = message_header.addr() {
|
||||||
|
@ -39,7 +39,13 @@ pub fn sys_sendmsg(
|
|||||||
(io_vec_reader, MessageHeader::new(addr, control_message))
|
(io_vec_reader, MessageHeader::new(addr, control_message))
|
||||||
};
|
};
|
||||||
|
|
||||||
let total_bytes = socket.sendmsg(&mut io_vec_reader, message_header, flags)?;
|
let total_bytes = socket
|
||||||
|
.sendmsg(&mut io_vec_reader, message_header, flags)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
// FIXME: `sendmsg` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(total_bytes as _))
|
Ok(SyscallReturn::Return(total_bytes as _))
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,13 @@ pub fn sys_sendto(
|
|||||||
let vm_space = ctx.process.root_vmar().vm_space();
|
let vm_space = ctx.process.root_vmar().vm_space();
|
||||||
vm_space.reader(buf, len)?
|
vm_space.reader(buf, len)?
|
||||||
};
|
};
|
||||||
let send_size = socket.sendmsg(&mut reader, message_header, flags)?;
|
let send_size = socket
|
||||||
|
.sendmsg(&mut reader, message_header, flags)
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
// FIXME: `sendto` should not be restarted if a timeout has been set on the socket using `setsockopt`.
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(send_size as _))
|
Ok(SyscallReturn::Return(send_size as _))
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,11 @@ pub fn sys_wait4(
|
|||||||
debug!("wait4 current pid = {}", ctx.process.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, ctx)?;
|
let waited_process =
|
||||||
|
wait_child_exit(process_filter, wait_options, ctx).map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
let Some(process) = waited_process else {
|
let Some(process) = waited_process else {
|
||||||
return Ok(SyscallReturn::Return(0 as _));
|
return Ok(SyscallReturn::Return(0 as _));
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,11 @@ pub fn sys_waitid(
|
|||||||
let process_filter = ProcessFilter::from_which_and_id(which, upid)?;
|
let process_filter = ProcessFilter::from_which_and_id(which, upid)?;
|
||||||
let wait_options = WaitOptions::from_bits(options as u32)
|
let wait_options = WaitOptions::from_bits(options as u32)
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "invalid options"))?;
|
.ok_or(Error::with_message(Errno::EINVAL, "invalid options"))?;
|
||||||
let waited_process = wait_child_exit(process_filter, wait_options, ctx)?;
|
let waited_process =
|
||||||
|
wait_child_exit(process_filter, wait_options, ctx).map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
let pid = waited_process.map_or(0, |process| process.pid());
|
let pid = waited_process.map_or(0, |process| process.pid());
|
||||||
Ok(SyscallReturn::Return(pid as _))
|
Ok(SyscallReturn::Return(pid as _))
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,22 @@ pub fn sys_write(
|
|||||||
// According to <https://man7.org/linux/man-pages/man2/write.2.html>, if
|
// According to <https://man7.org/linux/man-pages/man2/write.2.html>, if
|
||||||
// the user specified an empty buffer, we should detect errors by checking
|
// the user specified an empty buffer, we should detect errors by checking
|
||||||
// the file descriptor. If no errors detected, return 0 successfully.
|
// the file descriptor. If no errors detected, return 0 successfully.
|
||||||
let write_len = if user_buf_len != 0 {
|
let write_len = {
|
||||||
let mut reader = ctx
|
if user_buf_len != 0 {
|
||||||
.process
|
let mut reader = ctx
|
||||||
.root_vmar()
|
.process
|
||||||
.vm_space()
|
.root_vmar()
|
||||||
.reader(user_buf_ptr, user_buf_len)?;
|
.vm_space()
|
||||||
file.write(&mut reader)?
|
.reader(user_buf_ptr, user_buf_len)?;
|
||||||
} else {
|
file.write(&mut reader)
|
||||||
file.write_bytes(&[])?
|
} else {
|
||||||
};
|
file.write_bytes(&[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map_err(|err| match err.error() {
|
||||||
|
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||||
|
_ => err,
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(write_len as _))
|
Ok(SyscallReturn::Return(write_len as _))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user