mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 05: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> {
|
||||
let (connected_socket, socket_addr) = {
|
||||
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) {
|
||||
|
@ -17,6 +17,12 @@ pub fn sys_connect(
|
||||
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
|
||||
|
||||
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))
|
||||
}
|
||||
|
@ -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_GETLK => handle_getlk(fd, arg, 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_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);
|
||||
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))
|
||||
}
|
||||
|
@ -136,13 +136,10 @@ pub fn sys_futex(
|
||||
return_errno_with_message!(Errno::EINVAL, "unsupported futex op");
|
||||
}
|
||||
}
|
||||
.map_err(|e| {
|
||||
// From Linux manual, Futex returns `ETIMEDOUT` instead of `ETIME`
|
||||
if e.error() == Errno::ETIME {
|
||||
Error::with_message(Errno::ETIMEDOUT, "futex wait timeout")
|
||||
} else {
|
||||
e
|
||||
}
|
||||
.map_err(|err| match err.error() {
|
||||
Errno::ETIME => Error::new(Errno::ETIMEDOUT),
|
||||
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||
_ => err,
|
||||
})?;
|
||||
|
||||
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));
|
||||
0
|
||||
}
|
||||
// FIXME: ioctl operations involving blocking I/O should be able to restart if interrupted
|
||||
_ => file.ioctl(ioctl_cmd, arg)?,
|
||||
};
|
||||
Ok(SyscallReturn::Return(res as _))
|
||||
|
@ -33,7 +33,11 @@ pub fn sys_openat(
|
||||
.fs()
|
||||
.resolver()
|
||||
.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)
|
||||
};
|
||||
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
|
||||
// the user specified an empty buffer, we should detect errors by checking
|
||||
// the file descriptor. If no errors detected, return 0 successfully.
|
||||
let read_len = if buf_len != 0 {
|
||||
let mut writer = ctx
|
||||
.process
|
||||
.root_vmar()
|
||||
.vm_space()
|
||||
.writer(user_buf_addr, buf_len)?;
|
||||
file.read(&mut writer)?
|
||||
} else {
|
||||
file.read_bytes(&mut [])?
|
||||
};
|
||||
let read_len = {
|
||||
if buf_len != 0 {
|
||||
let mut writer = ctx
|
||||
.process
|
||||
.root_vmar()
|
||||
.vm_space()
|
||||
.writer(user_buf_addr, buf_len)?;
|
||||
file.read(&mut writer)
|
||||
} else {
|
||||
file.read_bytes(&mut [])
|
||||
}
|
||||
}
|
||||
.map_err(|err| match err.error() {
|
||||
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||
_ => err,
|
||||
})?;
|
||||
|
||||
Ok(SyscallReturn::Return(read_len as _))
|
||||
}
|
||||
|
@ -27,7 +27,14 @@ pub fn sys_recvfrom(
|
||||
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()
|
||||
&& src_addr != 0
|
||||
|
@ -25,7 +25,13 @@ pub fn sys_recvmsg(
|
||||
let (total_bytes, message_header) = {
|
||||
let socket = get_socket_from_fd(sockfd)?;
|
||||
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() {
|
||||
|
@ -39,7 +39,13 @@ pub fn sys_sendmsg(
|
||||
(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 _))
|
||||
}
|
||||
|
@ -34,7 +34,13 @@ pub fn sys_sendto(
|
||||
let vm_space = ctx.process.root_vmar().vm_space();
|
||||
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 _))
|
||||
}
|
||||
|
@ -22,7 +22,11 @@ pub fn sys_wait4(
|
||||
debug!("wait4 current pid = {}", ctx.process.pid());
|
||||
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 {
|
||||
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 wait_options = WaitOptions::from_bits(options as u32)
|
||||
.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());
|
||||
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
|
||||
// the user specified an empty buffer, we should detect errors by checking
|
||||
// the file descriptor. If no errors detected, return 0 successfully.
|
||||
let write_len = if user_buf_len != 0 {
|
||||
let mut reader = ctx
|
||||
.process
|
||||
.root_vmar()
|
||||
.vm_space()
|
||||
.reader(user_buf_ptr, user_buf_len)?;
|
||||
file.write(&mut reader)?
|
||||
} else {
|
||||
file.write_bytes(&[])?
|
||||
};
|
||||
let write_len = {
|
||||
if user_buf_len != 0 {
|
||||
let mut reader = ctx
|
||||
.process
|
||||
.root_vmar()
|
||||
.vm_space()
|
||||
.reader(user_buf_ptr, user_buf_len)?;
|
||||
file.write(&mut reader)
|
||||
} else {
|
||||
file.write_bytes(&[])
|
||||
}
|
||||
}
|
||||
.map_err(|err| match err.error() {
|
||||
Errno::EINTR => Error::new(Errno::ERESTARTSYS),
|
||||
_ => err,
|
||||
})?;
|
||||
|
||||
Ok(SyscallReturn::Return(write_len as _))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user