Fix os error printing in unix_shmem (#1406) (#1935)

Use `std::io::Error::last_os_error` instead of `libc::perror` for error printing in unix_shmem.
Add a new enum item `OSError` to enum Error.
This commit is contained in:
am009 2024-03-14 20:07:04 +08:00 committed by GitHub
parent afa2965f3c
commit 93f67aa405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 27 deletions

View File

@ -316,6 +316,9 @@ pub enum Error {
Unsupported(String, ErrorBacktrace),
/// Shutting down, not really an error.
ShuttingDown,
/// OS error from `std::io::Error::last_os_error`;
#[cfg(feature = "std")]
OSError(io::Error, String, ErrorBacktrace),
/// Something else happened
Unknown(String, ErrorBacktrace),
}
@ -410,6 +413,15 @@ impl Error {
{
Error::Unsupported(arg.into(), ErrorBacktrace::new())
}
#[cfg(feature = "std")]
/// OS error from `std::io::Error::last_os_error`;
#[must_use]
pub fn os_error<S>(err: io::Error, msg: S) -> Self
where
S: Into<String>,
{
Error::OSError(err, msg.into(), ErrorBacktrace::new())
}
/// Something else happened
#[must_use]
pub fn unknown<S>(arg: S) -> Self
@ -474,6 +486,11 @@ impl Display for Error {
display_error_backtrace(f, b)
}
Self::ShuttingDown => write!(f, "Shutting down!"),
#[cfg(feature = "std")]
Self::OSError(err, s, b) => {
write!(f, "OS error: {0}: {1}", &s, err)?;
display_error_backtrace(f, b)
}
Self::Unknown(s, b) => {
write!(f, "Unknown error: {0}", &s)?;
display_error_backtrace(f, b)

View File

@ -590,11 +590,11 @@ pub mod unix_shmem {
use alloc::string::ToString;
use core::{ptr, slice};
use std::{io::Write, process};
use std::{io, io::Write, process};
use libc::{
c_int, c_uchar, close, ftruncate, mmap, munmap, perror, shm_open, shm_unlink, shmat,
shmctl, shmdt, shmget,
c_int, c_uchar, close, ftruncate, mmap, munmap, shm_open, shm_unlink, shmat, shmctl,
shmdt, shmget,
};
use crate::{
@ -648,19 +648,21 @@ pub mod unix_shmem {
0o600,
);
if shm_fd == -1 {
perror(b"shm_open\0".as_ptr() as *const _);
return Err(Error::unknown(format!(
"Failed to shm_open map with id {filename_path:?}",
)));
return Err(Error::os_error(
io::Error::last_os_error(),
format!("Failed to shm_open map with id {filename_path:?}",),
));
}
/* configure the size of the shared memory segment */
if ftruncate(shm_fd, map_size.try_into()?) != 0 {
perror(b"ftruncate\0".as_ptr() as *const _);
shm_unlink(filename_path.as_ptr() as *const _);
return Err(Error::unknown(format!(
return Err(Error::os_error(
io::Error::last_os_error(),
format!(
"setup_shm(): ftruncate() failed for map with id {filename_path:?}",
)));
),
));
}
/* map the shared memory segment to the address space of the process */
@ -673,12 +675,12 @@ pub mod unix_shmem {
0,
);
if map == libc::MAP_FAILED || map.is_null() {
perror(b"mmap\0".as_ptr() as *const _);
close(shm_fd);
shm_unlink(filename_path.as_ptr() as *const _);
return Err(Error::unknown(format!(
"mmap() failed for map with id {filename_path:?}",
)));
return Err(Error::os_error(
io::Error::last_os_error(),
format!("mmap() failed for map with id {filename_path:?}",),
));
}
Ok(Self {
@ -705,11 +707,11 @@ pub mod unix_shmem {
0,
);
if map == libc::MAP_FAILED || map.is_null() {
perror(b"mmap\0".as_ptr() as *const _);
close(shm_fd);
return Err(Error::unknown(format!(
"mmap() failed for map with fd {shm_fd:?}"
)));
return Err(Error::os_error(
io::Error::last_os_error(),
format!("mmap() failed for map with fd {shm_fd:?}"),
));
}
Ok(Self {
@ -852,10 +854,9 @@ pub mod unix_shmem {
let map = shmat(os_id, ptr::null(), 0) as *mut c_uchar;
if map as c_int == -1 || map.is_null() {
perror(b"shmat\0".as_ptr() as *const _);
shmctl(os_id, libc::IPC_RMID, ptr::null_mut());
return Err(Error::unknown(
"Failed to map the shared mapping".to_string(),
return Err(Error::os_error(
io::Error::last_os_error(),
"Failed to map the shared mapping",
));
}
@ -874,10 +875,10 @@ pub mod unix_shmem {
let map = shmat(id_int, ptr::null(), 0) as *mut c_uchar;
if map.is_null() || map == ptr::null_mut::<c_uchar>().wrapping_sub(1) {
perror(b"shmat\0".as_ptr() as *const _);
return Err(Error::unknown(format!(
"Failed to map the shared mapping with id {id_int}"
)));
return Err(Error::os_error(
io::Error::last_os_error(),
format!("Failed to map the shared mapping with id {id_int}"),
));
}
Ok(Self { id, map, map_size })