1
0
Fork 0
forked from wry/wry

all: simplify handling of Errno values

This commit is contained in:
Julian Orth 2026-04-02 18:34:12 +02:00
parent 9c605df692
commit 34914eccb0
58 changed files with 443 additions and 464 deletions

View file

@ -4,11 +4,15 @@ use {
client::ClientCaps,
security_context_acceptor::AcceptorMetadata,
state::State,
utils::{errorfmt::ErrorFmt, oserror::OsError, xrd::xrd},
utils::{
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt, OsErrorExt2},
xrd::xrd,
},
},
std::rc::Rc,
thiserror::Error,
uapi::{Errno, OwnedFd, Ustr, Ustring, c, format_ustr},
uapi::{OwnedFd, Ustr, Ustring, c, format_ustr},
};
#[derive(Debug, Error)]
@ -74,28 +78,22 @@ fn bind_socket(
if jay_path.len() + 1 > addr.sun_path.len() {
return Err(AcceptorError::XrdTooLong(xrd.to_string()));
}
let lock_fd = match uapi::open(&*lock_path, c::O_CREAT | c::O_CLOEXEC | c::O_RDWR, 0o644) {
Ok(l) => l,
Err(e) => return Err(AcceptorError::OpenLockFile(e.into())),
};
if let Err(e) = uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB) {
return Err(AcceptorError::LockLockFile(e.into()));
}
let lock_fd = uapi::open(&*lock_path, c::O_CREAT | c::O_CLOEXEC | c::O_RDWR, 0o644)
.map_os_err(AcceptorError::OpenLockFile)?;
uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB).map_os_err(AcceptorError::LockLockFile)?;
for (name, fd) in [(&path, insecure), (&jay_path, secure)] {
match uapi::lstat(name) {
match uapi::lstat(name).to_os_error() {
Ok(_) => {
log::info!("Unlinking {}", name.display());
let _ = uapi::unlink(name);
}
Err(Errno(c::ENOENT)) => {}
Err(e) => return Err(AcceptorError::SocketStat(e.into())),
Err(OsError(c::ENOENT)) => {}
Err(e) => return Err(AcceptorError::SocketStat(e)),
}
let sun_path = uapi::as_bytes_mut(&mut addr.sun_path[..]);
sun_path[..name.len()].copy_from_slice(name.as_bytes());
sun_path[name.len()] = 0;
if let Err(e) = uapi::bind(fd.raw(), &addr) {
return Err(AcceptorError::BindFailed(e.into()));
}
uapi::bind(fd.raw(), &addr).map_os_err(AcceptorError::BindFailed)?;
}
Ok(AllocatedSocket {
name,
@ -115,10 +113,9 @@ fn allocate_socket() -> Result<AllocatedSocket, AcceptorError> {
};
let mut fds = [None, None];
for fd in &mut fds {
let socket = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(f) => Rc::new(f),
Err(e) => return Err(AcceptorError::SocketFailed(e.into())),
};
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(AcceptorError::SocketFailed)?;
*fd = Some(socket);
}
let unsecure = fds[0].take().unwrap();
@ -141,9 +138,7 @@ impl Acceptor {
let socket = allocate_socket()?;
log::info!("bound to socket {}", socket.path.display());
for fd in [&socket.secure, &socket.insecure] {
if let Err(e) = uapi::listen(fd.raw(), 4096) {
return Err(AcceptorError::ListenFailed(e.into()));
}
uapi::listen(fd.raw(), 4096).map_os_err(AcceptorError::ListenFailed)?;
}
let acc = Rc::new(Acceptor { socket });
let futures = vec![

View file

@ -10,8 +10,13 @@ use {
state::State,
udev::{Udev, UdevDevice, UdevError, UdevMonitor},
utils::{
bitflags::BitflagsExt, clonecell::CloneCell, copyhashmap::CopyHashMap,
errorfmt::ErrorFmt, hash_map_ext::HashMapExt, on_change::OnChange, oserror::OsError,
bitflags::BitflagsExt,
clonecell::CloneCell,
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
on_change::OnChange,
oserror::{OsError, OsErrorExt2},
},
video::drm::{Drm, DrmError, DrmVersion, NodeType, get_drm_nodes_from_dev},
},
@ -90,8 +95,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<HeadlessBackend>, HeadlessBa
monitor.enable_receiving().map_err(EnableUdevReceiving)?;
let monitor_fd = uapi::fcntl_dupfd_cloexec(monitor.fd(), 0)
.map(Rc::new)
.map_err(Into::into)
.map_err(DupUdevMonitorFd)?;
.map_os_err(DupUdevMonitorFd)?;
Ok(Rc::new(HeadlessBackend {
state: state.clone(),
udev,
@ -200,9 +204,7 @@ impl HeadlessBackend {
.get(&NodeType::Render)
.or_else(|| nodes.get(&NodeType::Primary))
.ok_or(NoDrmNodes)?;
let fd = uapi::open(&**node, c::O_RDWR | c::O_CLOEXEC, 0)
.map_err(Into::into)
.map_err(OpenDrmNode)?;
let fd = uapi::open(&**node, c::O_RDWR | c::O_CLOEXEC, 0).map_os_err(OpenDrmNode)?;
let drm = Drm::open_existing(Rc::new(fd)).map_err(CreateDrm)?;
let dev = Rc::new(HeadlessDrmDevice {
backend: self.clone(),

View file

@ -48,7 +48,7 @@ use {
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
smallmap::SmallMap,
syncqueue::SyncQueue,
},
@ -253,10 +253,9 @@ impl Backend for MetalBackend {
}
fn dup_fd(fd: c::c_int) -> Result<Rc<OwnedFd>, MetalError> {
match uapi::fcntl_dupfd_cloexec(fd, 0) {
Ok(m) => Ok(Rc::new(m)),
Err(e) => Err(MetalError::Dup(e.into())),
}
uapi::fcntl_dupfd_cloexec(fd, 0)
.map(Rc::new)
.map_os_err(MetalError::Dup)
}
pub async fn create(state: &Rc<State>) -> Result<Rc<MetalBackend>, MetalError> {
@ -384,15 +383,11 @@ struct DeviceHolder {
impl LibInputAdapter for DeviceHolder {
fn open(&self, path: &CStr) -> Result<OwnedFd, LibInputError> {
let stat = match uapi::stat(path) {
Ok(s) => s,
Err(e) => return Err(LibInputError::Stat(e.into())),
};
let stat = uapi::stat(path).map_os_err(LibInputError::Stat)?;
if let Some(MetalDevice::Input(d)) = self.devices.get(&stat.st_rdev)
&& let Some(fd) = d.fd.get()
{
return uapi::fcntl_dupfd_cloexec(fd.raw(), 0)
.map_err(|e| LibInputError::DupFd(e.into()));
return uapi::fcntl_dupfd_cloexec(fd.raw(), 0).map_os_err(LibInputError::DupFd);
}
Err(LibInputError::DeviceUnavailable)
}

View file

@ -3,7 +3,7 @@ use {
cli::{GlobalArgs, RunPrivilegedArgs},
compositor::WAYLAND_DISPLAY,
logger::Logger,
utils::{errorfmt::ErrorFmt, oserror::OsError, xrd::xrd},
utils::{errorfmt::ErrorFmt, oserror::OsErrorExt, xrd::xrd},
},
std::path::PathBuf,
uapi::UstrPtr,
@ -30,10 +30,6 @@ pub fn main(global: GlobalArgs, args: RunPrivilegedArgs) {
argv.push(arg.as_str());
}
let program = args.program[0].as_str();
let res = uapi::execvp(program, &argv).unwrap_err();
fatal!(
"Could not execute `{}`: {}",
program,
ErrorFmt(OsError::from(res))
);
let res = uapi::execvp(program, &argv).to_os_error().unwrap_err();
fatal!("Could not execute `{}`: {}", program, ErrorFmt(res));
}

View file

@ -3,7 +3,7 @@ use {
cli::GlobalArgs,
compositor::WAYLAND_DISPLAY,
tools::tool_client::{Handle, ToolClient, with_tool_client},
utils::{errorfmt::ErrorFmt, oserror::OsError},
utils::{errorfmt::ErrorFmt, oserror::OsErrorExt},
wire::{jay_acceptor_request, jay_compositor},
},
clap::{Args, ValueHint},
@ -59,12 +59,8 @@ impl RunTagged {
argv.push(arg.as_str());
}
let program = args.program[0].as_str();
let res = uapi::execvp(program, &argv).unwrap_err();
fatal!(
"Could not execute `{}`: {}",
program,
ErrorFmt(OsError::from(res)),
);
let res = uapi::execvp(program, &argv).to_os_error().unwrap_err();
fatal!("Could not execute `{}`: {}", program, ErrorFmt(res));
}
Err(msg) => {
fatal!("Could not create acceptor: {}", msg);

View file

@ -3,7 +3,11 @@ use {
client::Client,
cpu_worker::{AsyncCpuWork, CpuJob, CpuWork, CpuWorker},
gfx_api::{ShmMemory, ShmMemoryBacking},
utils::{page_size::page_size, vec_ext::VecExt},
utils::{
oserror::{OsError, OsErrorExt2},
page_size::page_size,
vec_ext::VecExt,
},
},
std::{
cell::Cell,
@ -113,7 +117,7 @@ impl ClientMem {
unsafe {
let data = c::mmap64(ptr::null_mut(), len, prot, flags, fd.raw(), 0);
if data == c::MAP_FAILED {
return Err(ClientMemError::MmapFailed(uapi::Errno::default().into()));
return Err(ClientMemError::MmapFailed(OsError::default()));
}
std::slice::from_raw_parts_mut(data as *mut Cell<u8>, len)
}
@ -273,10 +277,9 @@ pub fn init() -> Result<(), ClientMemError> {
sigbus as unsafe extern "C" fn(i32, &c::siginfo_t, *mut c::c_void) as _;
action.sa_flags = c::SA_NODEFER | c::SA_SIGINFO;
let res = c::sigaction(c::SIGBUS, &action, ptr::null_mut());
match uapi::map_err!(res) {
Ok(_) => Ok(()),
Err(e) => Err(ClientMemError::SigactionFailed(e.into())),
}
uapi::map_err!(res)
.map(drop)
.map_os_err(ClientMemError::SigactionFailed)
}
}

View file

@ -74,7 +74,7 @@ use {
nice::{did_elevate_scheduler, elevate_scheduler},
numcell::NumCell,
object_drop_queue::ObjectDropQueue,
oserror::OsError,
oserror::{OsError, OsErrorExt},
queue::AsyncQueue,
rc_eq::RcEq,
refcounted::RefCounted,
@ -667,7 +667,7 @@ async fn create_backend(
fn init_fd_limit() {
let res = OsError::tri(|| {
let mut cur = uapi::getrlimit(c::RLIMIT_NOFILE as _)?;
let mut cur = uapi::getrlimit(c::RLIMIT_NOFILE as _).to_os_error()?;
if cur.rlim_cur < cur.rlim_max {
log::info!(
"Increasing file descriptor limit from {} to {}",
@ -675,7 +675,7 @@ fn init_fd_limit() {
cur.rlim_max
);
cur.rlim_cur = cur.rlim_max;
uapi::setrlimit(c::RLIMIT_NOFILE as _, &cur)?;
uapi::setrlimit(c::RLIMIT_NOFILE as _, &cur).to_os_error()?;
}
Ok(())
});

View file

@ -37,7 +37,7 @@ use {
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt},
stack::Stack,
timer::{TimerError, TimerFd},
toplevel_identifier::ToplevelIdentifier,
@ -1922,13 +1922,10 @@ impl ConfigProxyHandler {
}
fn handle_add_pollable(self: &Rc<Self>, fd: i32) -> Result<(), CphError> {
let fd = match fcntl_dupfd_cloexec(fd, 0) {
let fd = match fcntl_dupfd_cloexec(fd, 0).to_os_error() {
Ok(fd) => Rc::new(fd),
Err(e) => {
let err = format!(
"Could not invoke F_DUPFD_CLOEXEC: {}",
ErrorFmt(OsError::from(e))
);
let err = format!("Could not invoke F_DUPFD_CLOEXEC: {}", ErrorFmt(e));
log::error!("{}", err);
self.respond(Response::AddPollable { id: Err(err) });
return Ok(());

View file

@ -6,7 +6,7 @@ use {
combo_box_ui, grid, label, read_only_bool, tip,
},
state::State,
utils::{errorfmt::ErrorFmt, oserror::OsError, static_text::StaticText},
utils::{errorfmt::ErrorFmt, oserror::OsErrorExt, static_text::StaticText},
},
egui::Ui,
linearize::Linearize,
@ -80,9 +80,9 @@ impl XwaylandPane {
});
if let Some(client) = self.state.xwayland.client.get()
&& ui.button("Kill").clicked()
&& let Err(e) = uapi::kill(client.pid_info.pid, c::SIGTERM)
&& let Err(e) = uapi::kill(client.pid_info.pid, c::SIGTERM).to_os_error()
{
log::error!("Could not kill Xwayland: {}", ErrorFmt(OsError::from(e)));
log::error!("Could not kill Xwayland: {}", ErrorFmt(e));
}
if let Some(client) = self.state.xwayland.client.get() {
show_client_collapsible(behavior, ui, &client);

View file

@ -7,8 +7,13 @@ use {
io_uring::IoUring,
rect::{Rect, Region},
utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
queue::AsyncQueue, stack::Stack,
clonecell::CloneCell,
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::{OsError, OsErrorExt2},
queue::AsyncQueue,
stack::Stack,
},
video::{
LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier,
@ -72,7 +77,6 @@ use {
cell::{Cell, RefCell},
ffi::CStr,
fmt::{Debug, Formatter},
io,
ops::Deref,
rc::Rc,
slice,
@ -89,9 +93,9 @@ pub enum CopyDeviceError {
#[error("Could not create a semaphore")]
CreateSemaphore(#[source] vk::Result),
#[error("Could not dup a sync file")]
DupSyncFile(#[source] io::Error),
DupSyncFile(#[source] OsError),
#[error("Could not dup a dma buf")]
DupDmaBuf(#[source] io::Error),
DupDmaBuf(#[source] OsError),
#[error("Could not import a sync file")]
ImportSyncFile(#[source] vk::Result),
#[error("Could not submit the copy")]
@ -895,8 +899,7 @@ impl CopyDevice {
return Err(CopyDeviceError::NoMemoryTypeForImport);
}
let fd = uapi::fcntl_dupfd_cloexec(plane.fd.raw(), 0)
.map_err(Into::into)
.map_err(CopyDeviceError::DupDmaBuf)?;
.map_os_err(CopyDeviceError::DupDmaBuf)?;
let mut dedicated_allocation = MemoryDedicatedAllocateInfo::default().buffer(buffer);
let mut external_memory = ImportMemoryFdInfoKHR::default()
.handle_type(ExternalMemoryHandleTypeFlags::DMA_BUF_EXT)
@ -1032,8 +1035,7 @@ impl CopyDevice {
return Err(CopyDeviceError::NoMemoryTypeForImport);
}
let fd = uapi::fcntl_dupfd_cloexec(dma_buf_plane.fd.raw(), 0)
.map_err(Into::into)
.map_err(CopyDeviceError::DupDmaBuf)?;
.map_os_err(CopyDeviceError::DupDmaBuf)?;
let mut memory_dedicated_allocate_info =
MemoryDedicatedAllocateInfo::default().image(image);
let mut import_memory_fd_info = ImportMemoryFdInfoKHR::default()
@ -1714,8 +1716,7 @@ impl CopyDeviceCopy {
impl VulkanSemaphore {
fn import(&self, sync_file: &OwnedFd) -> Result<(), CopyDeviceError> {
let fd = uapi::fcntl_dupfd_cloexec(sync_file.raw(), 0)
.map_err(Into::into)
.map_err(CopyDeviceError::DupSyncFile)?;
.map_os_err(CopyDeviceError::DupSyncFile)?;
let info = ImportSemaphoreFdInfoKHR::default()
.flags(SemaphoreImportFlags::TEMPORARY)
.semaphore(self.semaphore)

View file

@ -10,7 +10,7 @@ use {
buf::TypedBuf,
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
pipe::{Pipe, pipe},
ptr_ext::MutPtrExt,
queue::AsyncQueue,
@ -271,19 +271,18 @@ impl CpuWorker {
read: stop_read,
write: stop_write,
} = pipe().map_err(CpuWorkerError::Pipe)?;
let have_new_jobs =
uapi::eventfd(0, c::EFD_CLOEXEC).map_err(|e| CpuWorkerError::EventFd(e.into()))?;
let have_new_jobs = uapi::eventfd(0, c::EFD_CLOEXEC).map_os_err(CpuWorkerError::EventFd)?;
let have_completed_jobs =
uapi::eventfd(0, c::EFD_CLOEXEC).map_err(|e| CpuWorkerError::EventFd(e.into()))?;
uapi::eventfd(0, c::EFD_CLOEXEC).map_os_err(CpuWorkerError::EventFd)?;
thread::Builder::new()
.name("cpu worker".to_string())
.spawn({
let new_jobs = new_jobs.clone();
let completed_jobs = completed_jobs.clone();
let have_new_jobs = uapi::fcntl_dupfd_cloexec(have_new_jobs.raw(), 0)
.map_err(|e| CpuWorkerError::Dup(e.into()))?;
.map_os_err(CpuWorkerError::Dup)?;
let have_completed_jobs = uapi::fcntl_dupfd_cloexec(have_completed_jobs.raw(), 0)
.map_err(|e| CpuWorkerError::Dup(e.into()))?;
.map_os_err(CpuWorkerError::Dup)?;
move || {
work(
new_jobs,

View file

@ -3,7 +3,10 @@ use {
async_engine::AsyncEngine,
dbus::{DbusError, DbusHolder, DbusSocket, auth::handle_auth},
io_uring::IoUring,
utils::{bufio::BufIo, errorfmt::ErrorFmt, numcell::NumCell, run_toplevel::RunToplevel},
utils::{
bufio::BufIo, errorfmt::ErrorFmt, numcell::NumCell, oserror::OsErrorExt2,
run_toplevel::RunToplevel,
},
wire_dbus::org,
},
std::{cell::Cell, rc::Rc},
@ -38,10 +41,9 @@ async fn connect(
name: &'static str,
run_toplevel: &Rc<RunToplevel>,
) -> Result<Rc<DbusSocket>, DbusError> {
let fd = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(s) => Rc::new(s),
Err(e) => return Err(DbusError::Socket(e.into())),
};
let fd = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(DbusError::Socket)?;
let mut sadr: c::sockaddr_un = uapi::pod_zeroed();
sadr.sun_family = c::AF_UNIX as _;
let sun_path = uapi::as_bytes_mut(&mut sadr.sun_path[..]);

View file

@ -27,7 +27,7 @@ use {
double_buffered::DoubleBuffered,
errorfmt::ErrorFmt,
object_drop_queue::ObjectDropQueue,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
pipe::{Pipe, pipe},
rc_eq::rc_eq,
},
@ -362,8 +362,7 @@ impl State {
return Err(EggError::NoRenderContext);
};
let (client1, client2) = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map_err(Into::into)
.map_err(EggError::CreateSocketPair)?;
.map_os_err(EggError::CreateSocketPair)?;
let allocator = ctx.allocator();
let dev = allocator.drm().map(|d| d.dev());
let renderer = EgvRenderer::new(&self.eng, &self.ring, &self.eventfd_cache, dev)

View file

@ -6,7 +6,11 @@ use {
format::XRGB8888,
gfx_api::{FdSync, SyncFile},
io_uring::IoUring,
utils::{errorfmt::ErrorFmt, queue::AsyncQueue},
utils::{
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt2},
queue::AsyncQueue,
},
video::{Modifier, dmabuf::PlaneVec, drm::syncobj::SyncobjCtx},
vulkan_core::{
VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, VulkanDeviceFeatures,
@ -197,11 +201,11 @@ pub enum EgvError {
#[error("Could not find a memory type for import")]
NoMemoryTypeForImport,
#[error("Could not dup a dma buf")]
DupDmaBuf(#[source] io::Error),
DupDmaBuf(#[source] OsError),
#[error("Could not import memory")]
ImportMemory(#[source] vk::Result),
#[error("Could not dup a sync file")]
DupSyncFile(#[source] io::Error),
DupSyncFile(#[source] OsError),
#[error("Could not import a sync file")]
ImportSyncFile(#[source] vk::Result),
}
@ -1367,8 +1371,7 @@ impl EgvContext {
return Err(EgvError::NoMemoryTypeForImport);
}
let fd = uapi::fcntl_dupfd_cloexec(dma_buf_plane.fd.raw(), 0)
.map_err(Into::into)
.map_err(EgvError::DupDmaBuf)?;
.map_os_err(EgvError::DupDmaBuf)?;
let mut memory_dedicated_allocate_info =
MemoryDedicatedAllocateInfo::default().image(image);
let mut import_memory_fd_info = ImportMemoryFdInfoKHR::default()
@ -1887,9 +1890,7 @@ impl EgvBuffer {
impl EgvSemaphore {
fn import(&self, sync_file: &SyncFile) -> Result<(), EgvError> {
let fd = uapi::fcntl_dupfd_cloexec(sync_file.raw(), 0)
.map_err(Into::into)
.map_err(EgvError::DupSyncFile)?;
let fd = uapi::fcntl_dupfd_cloexec(sync_file.raw(), 0).map_os_err(EgvError::DupSyncFile)?;
let info = ImportSemaphoreFdInfoKHR::default()
.flags(SemaphoreImportFlags::TEMPORARY)
.semaphore(self.semaphore)

View file

@ -2,11 +2,15 @@ use {
crate::{
async_engine::SpawnedFuture,
state::State,
utils::{errorfmt::ErrorFmt, oserror::OsError, xrd::xrd},
utils::{
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt, OsErrorExt2},
xrd::xrd,
},
},
std::rc::Rc,
thiserror::Error,
uapi::{Errno, OwnedFd, Ustring, c, format_ustr},
uapi::{OwnedFd, Ustring, c, format_ustr},
};
#[derive(Debug, Error)]
@ -66,27 +70,22 @@ fn bind_socket(
if path.len() + 1 > addr.sun_path.len() {
return Err(EiAcceptorError::XrdTooLong(xrd.to_string()));
}
let lock_fd = match uapi::open(&*lock_path, c::O_CREAT | c::O_CLOEXEC | c::O_RDWR, 0o644) {
Ok(l) => l,
Err(e) => return Err(EiAcceptorError::OpenLockFile(e.into())),
};
if let Err(e) = uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB) {
return Err(EiAcceptorError::LockLockFile(e.into()));
}
match uapi::lstat(&path) {
let lock_fd = uapi::open(&*lock_path, c::O_CREAT | c::O_CLOEXEC | c::O_RDWR, 0o644)
.map_os_err(EiAcceptorError::OpenLockFile)?;
uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB)
.map_os_err(EiAcceptorError::LockLockFile)?;
match uapi::lstat(&path).to_os_error() {
Ok(_) => {
log::info!("Unlinking {}", path.display());
let _ = uapi::unlink(&path);
}
Err(Errno(c::ENOENT)) => {}
Err(e) => return Err(EiAcceptorError::SocketStat(e.into())),
Err(OsError(c::ENOENT)) => {}
Err(e) => return Err(EiAcceptorError::SocketStat(e)),
}
let sun_path = uapi::as_bytes_mut(&mut addr.sun_path[..]);
sun_path[..path.len()].copy_from_slice(path.as_bytes());
sun_path[path.len()] = 0;
if let Err(e) = uapi::bind(insecure.raw(), &addr) {
return Err(EiAcceptorError::BindFailed(e.into()));
}
uapi::bind(insecure.raw(), &addr).map_os_err(EiAcceptorError::BindFailed)?;
Ok(EiAllocatedSocket {
name,
path,
@ -101,10 +100,9 @@ fn allocate_socket() -> Result<EiAllocatedSocket, EiAcceptorError> {
Some(d) => d,
_ => return Err(EiAcceptorError::XrdNotSet),
};
let socket = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(f) => Rc::new(f),
Err(e) => return Err(EiAcceptorError::SocketFailed(e.into())),
};
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(EiAcceptorError::SocketFailed)?;
for i in 1..1000 {
match bind_socket(&socket, &xrd, i) {
Ok(s) => return Ok(s),
@ -122,9 +120,7 @@ impl EiAcceptor {
) -> Result<(Rc<EiAcceptor>, SpawnedFuture<()>), EiAcceptorError> {
let socket = allocate_socket()?;
log::info!("bound to socket {}", socket.path.display());
if let Err(e) = uapi::listen(socket.insecure.raw(), 4096) {
return Err(EiAcceptorError::ListenFailed(e.into()));
}
uapi::listen(socket.insecure.raw(), 4096).map_os_err(EiAcceptorError::ListenFailed)?;
let acc = Rc::new(EiAcceptor { socket });
let future = state.eng.spawn(
"ei accept",

View file

@ -2,7 +2,13 @@ use {
crate::{
async_engine::{AsyncEngine, SpawnedFuture},
io_uring::{IoUring, IoUringError},
utils::{buf::Buf, errorfmt::ErrorFmt, oserror::OsError, queue::AsyncQueue, stack::Stack},
utils::{
buf::Buf,
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt, OsErrorExt2},
queue::AsyncQueue,
stack::Stack,
},
},
std::{cell::Cell, future::poll_fn, pin::Pin, rc::Rc, slice, task::Poll},
thiserror::Error,
@ -51,8 +57,7 @@ impl EventfdCache {
Some(fd) => fd,
_ => uapi::eventfd(0, c::EFD_CLOEXEC)
.map(Rc::new)
.map_err(Into::into)
.map_err(EventfdError::CreateEventfd)?,
.map_os_err(EventfdError::CreateEventfd)?,
};
Ok(Eventfd {
cache: self.inner.clone(),
@ -85,7 +90,7 @@ impl Eventfd {
events: c::POLLIN,
revents: 0,
};
uapi::poll(slice::from_mut(&mut pollfd), -1)?;
uapi::poll(slice::from_mut(&mut pollfd), -1).to_os_error()?;
self.signaled.set(true);
Ok(())
}

View file

@ -13,6 +13,7 @@ use {
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::OsErrorExt2,
pipe::{Pipe, pipe},
process_name::set_process_name,
queue::AsyncQueue,
@ -87,11 +88,8 @@ impl ForkerProxy {
}
pub fn create(reaper_pid: c::pid_t) -> Result<Self, ForkerError> {
let (parent, child) =
match uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(o) => o,
Err(e) => return Err(ForkerError::Socketpair(e.into())),
};
let (parent, child) = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map_os_err(ForkerError::Socketpair)?;
match double_fork()? {
Some(pidfd) => Ok(ForkerProxy {
pidfd: Rc::new(pidfd),
@ -496,12 +494,10 @@ impl Forker {
self.pending_spawns.set(pid, spawn);
}
Forked::Child { .. } => {
let err = (|| {
let err: Result<(), SpawnError> = (|| {
if let Some(max_desired) = fds.iter().map(|v| v.0).max() {
match uapi::fcntl_dupfd_cloexec(write.raw(), max_desired.wrapping_add(1)) {
Ok(new) => write = new,
Err(e) => return Err(SpawnError::Dupfd(e.into())),
}
write = uapi::fcntl_dupfd_cloexec(write.raw(), max_desired.wrapping_add(1))
.map_os_err(SpawnError::Dupfd)?;
}
let fds = map_fds(fds)?;
for fd in fds {
@ -510,9 +506,7 @@ impl Forker {
uapi::fcntl_setfd(fd, uapi::fcntl_getfd(fd)? & !c::FD_CLOEXEC)?;
Ok(())
})();
if let Err(e) = res {
return Err(SpawnError::Cloexec(e.into()));
}
res.map_os_err(SpawnError::Cloexec)?;
}
unsafe {
c::signal(c::SIGCHLD, c::SIG_DFL);
@ -531,9 +525,7 @@ impl Forker {
for arg in args {
argsnt.push(arg);
}
if let Err(e) = uapi::execvp(&prog, &argsnt) {
return Err(SpawnError::Exec(e.into()));
}
uapi::execvp(&prog, &argsnt).map_os_err(SpawnError::Exec)?;
Ok(())
})();
if let Err(e) = err {
@ -601,23 +593,15 @@ fn map_fds(fds: Vec<(i32, OwnedFd)>) -> Result<Vec<OwnedFd>, SpawnError> {
continue;
}
if let Some(conflict_desired) = existing_to_desired.get(&desired).copied() {
match uapi::fcntl_dupfd_cloexec(desired, 0) {
Ok(new) => {
let new = uapi::fcntl_dupfd_cloexec(desired, 0).map_os_err(SpawnError::Dupfd)?;
existing_to_desired.remove(&desired);
existing_to_desired.insert(new.raw(), conflict_desired);
desired_to_existing.insert(conflict_desired, new);
}
Err(e) => return Err(SpawnError::Dupfd(e.into())),
}
}
match uapi::dup3(existing, desired, c::O_CLOEXEC) {
Ok(_) => {
uapi::dup3(existing, desired, c::O_CLOEXEC).map_os_err(SpawnError::Dupfd)?;
existing_to_desired.remove(&existing);
existing_to_desired.insert(desired, desired);
desired_to_existing.insert(desired, OwnedFd::new(desired));
}
Err(e) => return Err(SpawnError::Dupfd(e.into())),
}
}
Ok(desired_to_existing.into_values().collect())
}

View file

@ -18,7 +18,10 @@ use {
state::State,
theme::Color,
tree::{Node, OutputNode, Transform},
utils::{clonecell::UnsafeCellCloneSafe, errorfmt::ErrorFmt, static_text::StaticText},
utils::{
clonecell::UnsafeCellCloneSafe, errorfmt::ErrorFmt, oserror::OsErrorExt,
static_text::StaticText,
},
video::{
Modifier,
dmabuf::DmaBuf,
@ -1169,7 +1172,7 @@ impl FdSync {
};
uapi::poll(slice::from_mut(&mut pollfd), -1)
.map(drop)
.map_err(Into::into)
.to_os_error()
}
};
if let Err(e) = res {

View file

@ -10,7 +10,7 @@ use {
device::VulkanDevice, format::VulkanFormat, renderer::image_barrier,
staging::VulkanStagingBuffer,
},
utils::errorfmt::ErrorFmt,
utils::{errorfmt::ErrorFmt, oserror::OsErrorExt2},
video::{
Modifier,
dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec},
@ -379,7 +379,7 @@ impl VulkanBoAllocator {
.find_memory_type(MemoryPropertyFlags::empty(), memory_type_bits)
.ok_or(VulkanError::MemoryType)?;
let fd = uapi::fcntl_dupfd_cloexec(dma_buf_plane.fd.raw(), 0)
.map_err(|e| VulkanError::Dupfd(e.into()))?;
.map_os_err(VulkanError::Dupfd)?;
let mut memory_dedicated_allocate_info =
MemoryDedicatedAllocateInfo::default().image(image);
let mut import_memory_fd_info = ImportMemoryFdInfoKHR::default()

View file

@ -8,7 +8,7 @@ use {
format::{VulkanBlendBufferLimits, VulkanFormat},
instance::VulkanInstance,
},
utils::bitflags::BitflagsExt,
utils::{bitflags::BitflagsExt, oserror::OsErrorExt2},
video::{
dmabuf::DmaBufIds,
drm::{Drm, syncobj::SyncobjCtx},
@ -484,8 +484,8 @@ impl VulkanInstance {
GBM_BO_USE_RENDERING,
)
.map_err(VulkanError::AllocGbm)?;
let fl = uapi::fcntl_getfl(bo.dmabuf().planes[0].fd.raw())
.map_err(|e| VulkanError::GetFl(e.into()))?;
let fl =
uapi::fcntl_getfl(bo.dmabuf().planes[0].fd.raw()).map_os_err(VulkanError::GetFl)?;
if fl.not_contains(O_RDWR) {
return Err(VulkanError::SoftwareRendererNotUsable);
}

View file

@ -3,6 +3,7 @@ use {
format::Format,
gfx_api::GfxBuffer,
gfx_apis::vulkan::{VulkanError, device::VulkanDevice},
utils::oserror::OsErrorExt2,
},
ash::{
Device,
@ -70,8 +71,7 @@ impl VulkanDevice {
let Some(memory_type) = memory_type else {
return Err(VulkanError::MemoryType);
};
let fd =
uapi::fcntl_dupfd_cloexec(dmabuf.raw(), 0).map_err(|e| VulkanError::Dupfd(e.into()))?;
let fd = uapi::fcntl_dupfd_cloexec(dmabuf.raw(), 0).map_os_err(VulkanError::Dupfd)?;
let memory = {
let mut dedicated = MemoryDedicatedAllocateInfo::default().buffer(buffer);
let mut import_info = ImportMemoryFdInfoKHR::default()

View file

@ -15,6 +15,7 @@ use {
},
rect::Region,
theme::Color,
utils::oserror::OsErrorExt2,
video::dmabuf::{DmaBuf, PlaneVec},
},
ash::vk::{
@ -403,7 +404,7 @@ impl VulkanDmaBufImageTemplate {
.find_memory_type(MemoryPropertyFlags::empty(), memory_type_bits)
.ok_or(VulkanError::MemoryType)?;
let fd = uapi::fcntl_dupfd_cloexec(dma_buf_plane.fd.raw(), 0)
.map_err(|e| VulkanError::Dupfd(e.into()))?;
.map_os_err(VulkanError::Dupfd)?;
let mut memory_dedicated_allocate_info =
MemoryDedicatedAllocateInfo::default().image(image);
let mut import_memory_fd_info = ImportMemoryFdInfoKHR::default()

View file

@ -37,7 +37,7 @@ use {
theme::Color,
utils::{
copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, ordered_float::F32,
stack::Stack,
oserror::OsErrorExt2, stack::Stack,
},
video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file},
vulkan_core::{
@ -1689,7 +1689,7 @@ impl VulkanRenderer {
AcquireSync::FdSync(sync) => {
if let Some(sync_file) = sync.get_sync_file() {
let fd = uapi::fcntl_dupfd_cloexec(sync_file.raw(), 0)
.map_err(|e| VulkanError::Dupfd(e.into()))?;
.map_os_err(VulkanError::Dupfd)?;
import_sync_file(fd)?;
}
}

View file

@ -5,7 +5,10 @@ use {
ifs::jay_ei_session::JayEiSession,
leaks::Tracker,
object::{Object, Version},
utils::{errorfmt::ErrorFmt, oserror::OsError},
utils::{
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt2},
},
wire::{
JayEiSessionBuilderId,
jay_ei_session_builder::{Commit, JayEiSessionBuilderRequestHandler, SetAppId},
@ -33,12 +36,10 @@ impl JayEiSessionBuilderRequestHandler for JayEiSessionBuilder {
if app_id.is_none() {
return Err(JayEiSessionBuilderError::NoAppId);
}
let res = (move || {
let con = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0);
let (server, client) = match con {
Ok(w) => w,
Err(e) => return Err(JayEiSessionBuilderError::SocketPair(e.into())),
};
let res: Result<_, JayEiSessionBuilderError> = (move || {
let (server, client) =
uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map_os_err(JayEiSessionBuilderError::SocketPair)?;
let ei_client_id = self
.client
.state

View file

@ -6,7 +6,7 @@ use {
utils::{
clone3::{Forked, fork_with_pidfd},
errorfmt::ErrorFmt,
oserror::OsError,
oserror::OsErrorExt,
pipe::{Pipe, pipe},
},
wire::{JayReexecId, jay_reexec::*},
@ -118,8 +118,8 @@ impl JayReexecRequestHandler for JayReexec {
args2.push(&**arg);
}
let _drop_after_exec = self.delay_close_input_fd();
if let Err(e) = uapi::execvp(req.path, &args2) {
self.send_failed(&OsError(e.0).to_string());
if let Err(e) = uapi::execvp(req.path, &args2).to_os_error() {
self.send_failed(&e.to_string());
}
Ok(())
}

View file

@ -10,7 +10,11 @@ use {
leaks::Tracker,
object::{Object, Version},
state::OutputData,
utils::{bindings::Bindings, errorfmt::ErrorFmt, oserror::OsError},
utils::{
bindings::Bindings,
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt2},
},
video::drm::{Drm, DrmError},
wire::{WpDrmLeaseDeviceV1Id, wp_drm_lease_device_v1::*},
},
@ -213,8 +217,7 @@ enum ReopenError {
}
fn reopen_card(devnode: &str) -> Result<Rc<OwnedFd>, ReopenError> {
let fd = uapi::open(devnode, c::O_RDWR | c::O_CLOEXEC, 0)
.map_err(|e| ReopenError::OpenNode(e.into()))?;
let fd = uapi::open(devnode, c::O_RDWR | c::O_CLOEXEC, 0).map_os_err(ReopenError::OpenNode)?;
let fd = Rc::new(fd);
let drm = Drm::open_existing(fd.clone()).map_err(ReopenError::CreateDrm)?;
if drm.is_master() {

View file

@ -27,8 +27,13 @@ use {
state::State,
udmabuf::Udmabuf,
utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
on_change::OnChange, oserror::OsError, syncqueue::SyncQueue,
clonecell::CloneCell,
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
numcell::NumCell,
on_change::OnChange,
oserror::{OsError, OsErrorExt2},
syncqueue::SyncQueue,
},
video::{
drm::{ConnectorType, Drm, DrmError},
@ -296,15 +301,11 @@ where
}
return Err(TestBackendError::NoDrmNode);
};
let file = match uapi::open(node.as_path(), c::O_RDWR | c::O_CLOEXEC, 0) {
Ok(f) => Rc::new(f),
Err(e) => {
return Err(TestBackendError::OpenDrmNode(
node.as_os_str().as_bytes().as_bstr().to_string(),
e.into(),
));
}
};
let file = uapi::open(node.as_path(), c::O_RDWR | c::O_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(|e| {
TestBackendError::OpenDrmNode(node.as_os_str().as_bytes().as_bstr().to_string(), e)
})?;
let drm = Drm::open_existing(file).map_err(TestBackendError::OpenDrmDevice)?;
f(drm)
}

View file

@ -3,7 +3,11 @@ use {
backend::KeyState,
ifs::wl_seat::WlSeatGlobal,
keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId, KeymapFd},
utils::{oserror::OsError, syncqueue::SyncQueue, vecset::VecSet},
utils::{
oserror::{OsError, OsErrorExt},
syncqueue::SyncQueue,
vecset::VecSet,
},
},
kbvm::{
Keycode,
@ -181,14 +185,16 @@ fn create_keymap_memfd(map: &Keymap, xwayland: bool) -> Result<(String, KeymapFd
format = format.lookup_only(true).rename_long_keys(true);
}
let str = format!("{}\n", format);
let mut memfd = uapi::memfd_create("keymap", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?;
let mut memfd =
uapi::memfd_create("keymap", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING).to_os_error()?;
memfd.write_all(str.as_bytes())?;
memfd.write_all(&[0])?;
uapi::lseek(memfd.raw(), 0, c::SEEK_SET)?;
uapi::lseek(memfd.raw(), 0, c::SEEK_SET).to_os_error()?;
uapi::fcntl_add_seals(
memfd.raw(),
c::F_SEAL_SEAL | c::F_SEAL_GROW | c::F_SEAL_SHRINK | c::F_SEAL_WRITE,
)?;
)
.to_os_error()?;
let fd = KeymapFd {
map: Rc::new(memfd),
len: str.len() + 1,

View file

@ -2,7 +2,11 @@ use {
crate::{
backend::{LED_CAPS_LOCK, LED_COMPOSE, LED_KANA, LED_NUM_LOCK, LED_SCROLL_LOCK, Leds},
kbvm::KbvmMap,
utils::{event_listener::EventSource, oserror::OsError, vecset::VecSet},
utils::{
event_listener::EventSource,
oserror::{OsError, OsErrorExt, OsErrorExt2},
vecset::VecSet,
},
},
kbvm::{Components, state_machine::Event},
std::{
@ -10,7 +14,7 @@ use {
rc::Rc,
},
thiserror::Error,
uapi::{Errno, OwnedFd, c},
uapi::{OwnedFd, c},
};
#[derive(Debug, Error)]
@ -91,18 +95,17 @@ pub struct KeymapFd {
impl KeymapFd {
pub fn create_unprotected_fd(&self) -> Result<Self, KeyboardError> {
let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) {
Ok(fd) => fd,
Err(e) => return Err(KeyboardError::KeymapMemfd(e.into())),
};
let fd = uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC)
.map_os_err(KeyboardError::KeymapMemfd)?;
let target = self.len as c::off_t;
let mut pos = 0;
while pos < target {
let rem = target - pos;
let res = uapi::sendfile(fd.raw(), self.map.raw(), Some(&mut pos), rem as usize);
let res = uapi::sendfile(fd.raw(), self.map.raw(), Some(&mut pos), rem as usize)
.to_os_error();
match res {
Ok(_) | Err(Errno(c::EINTR)) => {}
Err(e) => return Err(KeyboardError::KeymapCopy(e.into())),
Ok(_) | Err(OsError(c::EINTR)) => {}
Err(e) => return Err(KeyboardError::KeymapCopy(e)),
}
}
Ok(Self {

View file

@ -28,7 +28,7 @@ use {
isnt::std_1::primitive::IsntConstPtrExt,
std::{ffi::CStr, rc::Rc},
thiserror::Error,
uapi::{Errno, IntoUstr, OwnedFd, c},
uapi::{IntoUstr, OwnedFd, c},
};
static INTERFACE: libinput_interface = libinput_interface {
@ -141,7 +141,7 @@ impl LibInput {
pub fn dispatch(&self) -> Result<(), LibInputError> {
let res = unsafe { libinput_dispatch(self.li) };
if res < 0 {
Err(LibInputError::Dispatch(Errno(-res).into()))
Err(LibInputError::Dispatch(OsError(-res)))
} else {
Ok(())
}

View file

@ -1,7 +1,11 @@
use {
crate::{
compositor::LogLevel,
utils::{atomic_enum::AtomicEnum, errorfmt::ErrorFmt, oserror::OsError},
utils::{
atomic_enum::AtomicEnum,
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt, OsErrorExt2},
},
},
backtrace::Backtrace,
bstr::{BStr, BString, ByteSlice},
@ -21,7 +25,7 @@ use {
time::SystemTime,
},
thiserror::Error,
uapi::{AsUstr, Dirent, Errno, Fd, OwnedFd, Ustring, c, format_ustr},
uapi::{AsUstr, Dirent, Fd, OwnedFd, Ustring, c, format_ustr},
};
thread_local! {
@ -38,10 +42,9 @@ pub struct Logger {
impl Logger {
pub fn install_stderr(level: LogLevel) -> Arc<Self> {
let file = match uapi::fcntl_dupfd_cloexec(2, 0) {
let file = match uapi::fcntl_dupfd_cloexec(2, 0).to_os_error() {
Ok(fd) => fd,
Err(e) => {
let e = OsError::from(e);
fatal!("Error: Could not dup stderr: {}", ErrorFmt(e));
}
};
@ -130,7 +133,9 @@ pub fn open_log_file(ty: &str) -> (Ustring, OwnedFd) {
&file_name,
c::O_CREAT | c::O_EXCL | c::O_CLOEXEC | c::O_WRONLY,
0o644,
) {
)
.to_os_error()
{
Ok(f) => {
if let Err(e) = uapi::flock(f.raw(), c::LOCK_EX | c::LOCK_NB) {
log::warn!("Unable to flock just-opened logfile: {}", ErrorFmt(e));
@ -147,9 +152,8 @@ pub fn open_log_file(ty: &str) -> (Ustring, OwnedFd) {
}
return (file_name, f);
}
Err(Errno(c::EEXIST)) => {}
Err(OsError(c::EEXIST)) => {}
Err(e) => {
let e: OsError = e.into();
fatal!("Error: Could not create log file: {}", ErrorFmt(e));
}
}
@ -258,18 +262,15 @@ enum CleanLogsError {
fn clean_logs_older_than(current_log_path: &BStr, time: SystemTime) -> Result<(), CleanLogsError> {
let current_log_path = current_log_path.to_path_lossy();
let parent = current_log_path.parent().ok_or(CleanLogsError::NoParent)?;
let mut dir = uapi::opendir(parent)
.map_err(Into::into)
.map_err(CleanLogsError::OpenDir)?;
let mut dir = uapi::opendir(parent).map_os_err(CleanLogsError::OpenDir)?;
let parent = uapi::open(parent, c::O_PATH | c::O_CLOEXEC | c::O_DIRECTORY, 0)
.map_err(Into::into)
.map_err(CleanLogsError::OpenDir)?;
.map_os_err(CleanLogsError::OpenDir)?;
let time = time
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs() as c::time_t;
while let Some(entry) = uapi::readdir(&mut dir) {
let entry = entry.map_err(Into::into).map_err(CleanLogsError::ReadDir)?;
let entry = entry.map_os_err(CleanLogsError::ReadDir)?;
if let Err(err) = process_entry(parent.raw(), &entry, time) {
log::error!(
"Could not clean log file {}: {}",
@ -288,11 +289,8 @@ fn clean_logs_older_than(current_log_path: &BStr, time: SystemTime) -> Result<()
}
let name = entry.name();
let file = uapi::openat(parent, name, c::O_RDONLY | c::O_CLOEXEC, 0)
.map_err(Into::into)
.map_err(CleanLogsError::OpenFile)?;
let stat = uapi::fstat(*file)
.map_err(Into::into)
.map_err(CleanLogsError::Stat)?;
.map_os_err(CleanLogsError::OpenFile)?;
let stat = uapi::fstat(*file).map_os_err(CleanLogsError::Stat)?;
if stat.st_mtime >= time {
return Ok(());
}
@ -300,9 +298,7 @@ fn clean_logs_older_than(current_log_path: &BStr, time: SystemTime) -> Result<()
log::info!("Preserving file still in use: {}", name.as_ustr().display());
return Ok(());
}
uapi::unlinkat(parent, name, 0)
.map_err(Into::into)
.map_err(CleanLogsError::Unlink)?;
uapi::unlinkat(parent, name, 0).map_os_err(CleanLogsError::Unlink)?;
log::info!("Deleted {}", name.as_ustr().display());
Ok(())
}

View file

@ -25,7 +25,7 @@ use {
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
xrd::xrd,
},
},
@ -300,10 +300,9 @@ impl Drop for PwConHolder {
impl PwConHolder {
pub async fn new(eng: &Rc<AsyncEngine>, ring: &Rc<IoUring>) -> Result<Rc<Self>, PwConError> {
let fd = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(fd) => Rc::new(fd),
Err(e) => return Err(PwConError::CreateSocket(e.into())),
};
let fd = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(PwConError::CreateSocket)?;
let mut addr = c::sockaddr_un {
sun_family: c::AF_UNIX as _,
..uapi::pod_zeroed()

View file

@ -34,7 +34,7 @@ use {
errorfmt::ErrorFmt,
line_logger::log_lines,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt},
pipe::{Pipe, pipe},
process_name::set_process_name,
run_toplevel::RunToplevel,
@ -94,13 +94,13 @@ impl PortalStartup {
);
return;
}
let (_, status) = match uapi::waitpid(self.pid, 0) {
let (_, status) = match uapi::waitpid(self.pid, 0).to_os_error() {
Ok(r) => r,
Err(e) => {
log::error!(
"Could not retrieve exit status of portal ({}): {}",
self.pid,
ErrorFmt(OsError::from(e))
ErrorFmt(e),
);
return;
}
@ -175,12 +175,12 @@ fn run(logger: Arc<Logger>, freestanding: bool) -> ! {
drop(write);
let read = BufReader::new(read);
let Ok(log_file) = bincode::deserialize_from::<_, Vec<u8>>(read) else {
let (_, status) = match uapi::waitpid(pid, 0) {
let (_, status) = match uapi::waitpid(pid, 0).to_os_error() {
Ok(r) => r,
Err(e) => {
fatal!(
"Could not retrieve exit status of portal ({pid}): {}",
ErrorFmt(OsError::from(e)),
ErrorFmt(e),
);
}
};
@ -304,8 +304,8 @@ async fn init_dbus_session(dbus: &Dbus, logger: Arc<Logger>, path_sink: OwnedFd)
if let Err(e) = bincode::serialize_into(sink, log_file.as_bytes()) {
log::error!("Could not send log file to parent: {}", ErrorFmt(e));
}
if let Err(e) = uapi::setsid() {
log::error!("setsid failed: {}", ErrorFmt(OsError::from(e)));
if let Err(e) = uapi::setsid().to_os_error() {
log::error!("setsid failed: {}", ErrorFmt(e));
}
log::info!("pid = {}", getpid());
set_process_name("jay portal");

View file

@ -18,7 +18,7 @@ use {
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
opaque::{Opaque, opaque},
oserror::OsError,
oserror::OsErrorExt,
},
video::drm::Drm,
wire::{
@ -514,12 +514,10 @@ fn add_output(dpy: &Rc<PortalDisplay>, name: GlobalName, version: u32) {
pub(super) async fn watch_displays(state: Rc<PortalState>) {
let inotify = Rc::new(uapi::inotify_init1(c::IN_CLOEXEC).unwrap());
if let Err(e) = uapi::inotify_add_watch(inotify.raw(), state.xrd.as_str(), c::IN_CREATE) {
log::error!(
"Cannot watch directory `{}`: {}",
state.xrd,
ErrorFmt(OsError::from(e))
);
if let Err(e) =
uapi::inotify_add_watch(inotify.raw(), state.xrd.as_str(), c::IN_CREATE).to_os_error()
{
log::error!("Cannot watch directory `{}`: {}", state.xrd, ErrorFmt(e));
return;
}
let rd = match std::fs::read_dir(&state.xrd) {

View file

@ -4,7 +4,7 @@ use {
_LINUX_CAPABILITY_U32S_3, _LINUX_CAPABILITY_VERSION_3, CAP_SYS_NICE, cap_user_data_t,
cap_user_header_t,
},
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, oserror::OsError},
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, oserror::OsErrorExt},
},
opera::PhantomNotSend,
parking_lot::{Condvar, Mutex},
@ -54,11 +54,8 @@ pub fn pr_caps() -> PrCaps {
};
let mut caps = [cap_user_data_t::default(); _LINUX_CAPABILITY_U32S_3];
let ret = unsafe { syscall(SYS_capget, &mut hdr, &mut caps) };
if let Err(e) = map_err!(ret) {
eprintln!(
"Could not get process capabilities: {}",
ErrorFmt(OsError(e.0))
);
if let Err(e) = map_err!(ret).to_os_error() {
eprintln!("Could not get process capabilities: {}", ErrorFmt(e));
return PrCaps {
effective: 0,
permitted: 0,
@ -79,11 +76,8 @@ pub fn drop_all_pr_caps() {
};
let caps = [cap_user_data_t::default(); _LINUX_CAPABILITY_U32S_3];
let ret = unsafe { syscall(SYS_capset, &mut hdr, &caps) };
if let Err(e) = map_err!(ret) {
eprintln!(
"Could not get drop capabilities: {}",
ErrorFmt(OsError(e.0))
);
if let Err(e) = map_err!(ret).to_os_error() {
eprintln!("Could not get drop capabilities: {}", ErrorFmt(e));
}
}
@ -110,11 +104,8 @@ impl PrCaps {
data[0].permitted = caps_lo;
data[1].permitted = caps_hi;
let ret = unsafe { syscall(SYS_capset, &mut hdr, &data) };
if let Err(e) = map_err!(ret) {
eprintln!(
"Could not get set compositor capabilities: {}",
ErrorFmt(OsError(e.0))
);
if let Err(e) = map_err!(ret).to_os_error() {
eprintln!("Could not get set compositor capabilities: {}", ErrorFmt(e));
return PrCompCaps { caps: self };
}
self.effective = caps;

View file

@ -2,7 +2,11 @@ use {
crate::{
async_engine::{AsyncEngine, SpawnedFuture},
io_uring::IoUring,
utils::{buf::TypedBuf, errorfmt::ErrorFmt, oserror::OsError},
utils::{
buf::TypedBuf,
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt2},
},
},
std::rc::Rc,
thiserror::Error,
@ -25,13 +29,10 @@ pub fn install(
uapi::sigaddset(&mut set, c::SIGINT).unwrap();
uapi::sigaddset(&mut set, c::SIGTERM).unwrap();
uapi::sigaddset(&mut set, c::SIGPIPE).unwrap();
if let Err(e) = uapi::pthread_sigmask(c::SIG_BLOCK, Some(&set), None) {
return Err(SighandError::BlockFailed(e.into()));
}
let fd = match uapi::signalfd_new(&set, c::SFD_CLOEXEC) {
Ok(fd) => Rc::new(fd),
Err(e) => return Err(SighandError::CreateFailed(e.into())),
};
uapi::pthread_sigmask(c::SIG_BLOCK, Some(&set), None).map_os_err(SighandError::BlockFailed)?;
let fd = uapi::signalfd_new(&set, c::SFD_CLOEXEC)
.map(Rc::new)
.map_os_err(SighandError::CreateFailed)?;
Ok(eng.spawn("signal handler", handle_signals(fd, ring.clone())))
}

View file

@ -4,7 +4,12 @@ use {
client::ClientCaps,
security_context_acceptor::AcceptorMetadata,
state::State,
utils::{errorfmt::ErrorFmt, numcell::NumCell, oserror::OsError, xrd::xrd},
utils::{
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::{OsError, OsErrorExt, OsErrorExt2},
xrd::xrd,
},
},
ahash::AHashMap,
std::{
@ -12,7 +17,7 @@ use {
rc::Rc,
},
thiserror::Error,
uapi::{Errno, OwnedFd, Ustring, c, format_ustr},
uapi::{OwnedFd, Ustring, c, format_ustr},
};
#[derive(Debug, Error)]
@ -88,8 +93,7 @@ impl TaggedAcceptors {
let xrd = xrd().ok_or(TaggedAcceptorError::XrdNotSet)?;
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_err(Into::into)
.map_err(TaggedAcceptorError::SocketFailed)?;
.map_os_err(TaggedAcceptorError::SocketFailed)?;
loop {
let i = self.next_name.fetch_add(1) + 1000;
if let Some(s) = bind_socket(&socket, &xrd, i)? {
@ -165,31 +169,26 @@ fn bind_socket(
return Err(TaggedAcceptorError::XrdTooLong(xrd.to_string()));
}
let lock_fd = uapi::open(&*lock_path, c::O_CREAT | c::O_CLOEXEC | c::O_RDWR, 0o644)
.map_err(Into::into)
.map_err(TaggedAcceptorError::OpenLockFile)?;
if let Err(e) = uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB) {
.map_os_err(TaggedAcceptorError::OpenLockFile)?;
if let Err(e) = uapi::flock(lock_fd.raw(), c::LOCK_EX | c::LOCK_NB).to_os_error() {
if e.0 == c::EWOULDBLOCK {
return Ok(None);
}
return Err(TaggedAcceptorError::LockLockFile(e.into()));
return Err(TaggedAcceptorError::LockLockFile(e));
}
match uapi::lstat(&path) {
match uapi::lstat(&path).to_os_error() {
Ok(_) => {
log::info!("Unlinking {}", path.display());
let _ = uapi::unlink(&path);
}
Err(Errno(c::ENOENT)) => {}
Err(e) => return Err(TaggedAcceptorError::SocketStat(e.into())),
Err(OsError(c::ENOENT)) => {}
Err(e) => return Err(TaggedAcceptorError::SocketStat(e)),
}
let sun_path = uapi::as_bytes_mut(&mut addr.sun_path[..]);
sun_path[..path.len()].copy_from_slice(path.as_bytes());
sun_path[path.len()] = 0;
uapi::bind(fd.raw(), &addr)
.map_err(Into::into)
.map_err(TaggedAcceptorError::BindFailed)?;
if let Err(e) = uapi::listen(fd.raw(), 4096) {
return Err(TaggedAcceptorError::ListenFailed(e.into()));
}
uapi::bind(fd.raw(), &addr).map_os_err(TaggedAcceptorError::BindFailed)?;
uapi::listen(fd.raw(), 4096).map_os_err(TaggedAcceptorError::ListenFailed)?;
Ok(Some(AllocatedSocket {
name,
path,

View file

@ -20,8 +20,12 @@ use {
theme::Color,
udmabuf::UdmabufHolder,
utils::{
clonecell::CloneCell, double_buffered::DoubleBuffered, errorfmt::ErrorFmt,
on_drop_event::OnDropEvent, oserror::OsError, page_size::page_size,
clonecell::CloneCell,
double_buffered::DoubleBuffered,
errorfmt::ErrorFmt,
on_drop_event::OnDropEvent,
oserror::{OsError, OsErrorExt2},
page_size::page_size,
},
},
std::{
@ -691,9 +695,7 @@ impl Memfd {
let Ok(isize) = off_t::try_from(size) else {
return Err(TextError::SizeOverflow);
};
if let Err(e) = ftruncate(self.fd.raw(), isize) {
return Err(TextError::ResizeMemfd(e.into()));
}
ftruncate(self.fd.raw(), isize).map_os_err(TextError::ResizeMemfd)?;
let old_ptr = self.mapping.load(Relaxed);
let new_ptr = if old_ptr.is_null() {
unsafe {

View file

@ -16,7 +16,7 @@ use {
clonecell::CloneCell,
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
xrd::xrd,
},
wheel::{Wheel, WheelError},
@ -154,10 +154,9 @@ impl ToolClient {
if path.not_ends_with(suffix) {
path.push(suffix.as_slice());
}
let socket = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(s) => Rc::new(s),
Err(e) => return Err(ToolClientError::CreateSocket(e.into())),
};
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(ToolClientError::CreateSocket)?;
let mut addr: c::sockaddr_un = uapi::pod_zeroed();
addr.sun_family = c::AF_UNIX as _;
if path.len() >= addr.sun_path.len() {

View file

@ -4,7 +4,7 @@ use {
crate::utils::oserror::OsError,
std::{ffi::CStr, marker::PhantomData, ptr, rc::Rc},
thiserror::Error,
uapi::{Errno, IntoUstr, c},
uapi::{IntoUstr, c},
};
#[repr(transparent)]
@ -132,7 +132,7 @@ impl Udev {
pub fn new() -> Result<Self, UdevError> {
let res = unsafe { udev_new() };
if res.is_null() {
return Err(UdevError::New(Errno::default().into()));
return Err(UdevError::New(OsError::default()));
}
Ok(Self { udev: res })
}
@ -140,7 +140,7 @@ impl Udev {
pub fn create_monitor(self: &Rc<Self>) -> Result<UdevMonitor, UdevError> {
let res = unsafe { udev_monitor_new_from_netlink(self.udev, c"udev".as_ptr() as _) };
if res.is_null() {
return Err(UdevError::NewMonitor(Errno::default().into()));
return Err(UdevError::NewMonitor(OsError::default()));
}
Ok(UdevMonitor {
udev: self.clone(),
@ -151,7 +151,7 @@ impl Udev {
pub fn create_enumerate(self: &Rc<Self>) -> Result<UdevEnumerate, UdevError> {
let res = unsafe { udev_enumerate_new(self.udev) };
if res.is_null() {
return Err(UdevError::NewEnumerate(Errno::default().into()));
return Err(UdevError::NewEnumerate(OsError::default()));
}
Ok(UdevEnumerate {
_udev: self.clone(),
@ -166,7 +166,7 @@ impl Udev {
let syspath = syspath.into_ustr();
let res = unsafe { udev_device_new_from_syspath(self.udev, syspath.as_ptr()) };
if res.is_null() {
return Err(UdevError::DeviceFromSyspath(Errno::default().into()));
return Err(UdevError::DeviceFromSyspath(OsError::default()));
}
Ok(UdevDevice {
udev: self.clone(),
@ -185,7 +185,7 @@ impl Udev {
};
let res = unsafe { udev_device_new_from_devnum(self.udev, ty as _, devnum) };
if res.is_null() {
return Err(UdevError::DeviceFromDevnum(Errno::default().into()));
return Err(UdevError::DeviceFromDevnum(OsError::default()));
}
Ok(UdevDevice {
udev: self.clone(),
@ -210,7 +210,7 @@ impl UdevMonitor {
pub fn enable_receiving(&self) -> Result<(), UdevError> {
let res = unsafe { udev_monitor_enable_receiving(self.monitor) };
if res < 0 {
Err(UdevError::EnableReceiving(Errno(-res).into()))
Err(UdevError::EnableReceiving(OsError(-res)))
} else {
Ok(())
}
@ -234,7 +234,7 @@ impl UdevMonitor {
)
};
if res < 0 {
Err(UdevError::MonitorAddMatch(Errno(-res).into()))
Err(UdevError::MonitorAddMatch(OsError(-res)))
} else {
Ok(())
}
@ -266,7 +266,7 @@ impl UdevEnumerate {
let subsystem = subsystem.into_ustr();
let res = unsafe { udev_enumerate_add_match_subsystem(self.enumerate, subsystem.as_ptr()) };
if res < 0 {
Err(UdevError::EnumerateAddMatch(Errno(-res).into()))
Err(UdevError::EnumerateAddMatch(OsError(-res)))
} else {
Ok(())
}
@ -275,7 +275,7 @@ impl UdevEnumerate {
pub fn scan_devices(&self) -> Result<(), UdevError> {
let res = unsafe { udev_enumerate_scan_devices(self.enumerate) };
if res < 0 {
Err(UdevError::ScanDevices(Errno(-res).into()))
Err(UdevError::ScanDevices(OsError(-res)))
} else {
Ok(())
}
@ -284,11 +284,11 @@ impl UdevEnumerate {
pub fn get_list_entry(&mut self) -> Result<Option<UdevListEntry<'_>>, UdevError> {
let res = unsafe { udev_enumerate_get_list_entry(self.enumerate) };
if res.is_null() {
let err = Errno::default();
let err = OsError::default();
if err.0 == c::ENODATA {
Ok(None)
} else {
Err(UdevError::EnumerateGetListEntry(err.into()))
Err(UdevError::EnumerateGetListEntry(err))
}
} else {
Ok(Some(UdevListEntry {
@ -358,7 +358,7 @@ impl UdevDevice {
pub fn parent(&self) -> Result<UdevDevice, UdevError> {
let res = unsafe { udev_device_get_parent(self.device) };
if res.is_null() {
return Err(UdevError::DeviceParent(Errno::default().into()));
return Err(UdevError::DeviceParent(OsError::default()));
}
unsafe {
udev_device_ref(res);

View file

@ -3,8 +3,12 @@ use {
allocator::{Allocator, AllocatorError, BufferObject, BufferUsage, MappedBuffer},
format::Format,
utils::{
clonecell::CloneCell, compat::IoctlNumber, errorfmt::ErrorFmt, once::Once,
oserror::OsError, page_size::page_size,
clonecell::CloneCell,
compat::IoctlNumber,
errorfmt::ErrorFmt,
once::Once,
oserror::{OsError, OsErrorExt, OsErrorExt2},
page_size::page_size,
},
video::{
LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier,
@ -89,10 +93,7 @@ pub struct Udmabuf {
impl Udmabuf {
pub fn new() -> Result<Self, UdmabufError> {
let fd = match open("/dev/udmabuf", O_RDONLY, 0) {
Ok(b) => b,
Err(e) => return Err(UdmabufError::Open(e.into())),
};
let fd = open("/dev/udmabuf", O_RDONLY, 0).map_os_err(UdmabufError::Open)?;
Ok(Self { fd })
}
@ -109,10 +110,9 @@ impl Udmabuf {
size: size as u64,
};
let dmabuf = unsafe { ioctl(self.fd.raw(), UDMABUF_CREATE, &mut cmd) };
let dmabuf = match map_err!(dmabuf) {
Ok(d) => OwnedFd::new(d),
Err(e) => return Err(UdmabufError::CreateDmabuf(e.into())),
};
let dmabuf = map_err!(dmabuf)
.map(OwnedFd::new)
.map_os_err(UdmabufError::CreateDmabuf)?;
Ok(dmabuf)
}
@ -141,16 +141,10 @@ impl Udmabuf {
let stride = (width * format.bpp as u64).next_multiple_of(LINEAR_STRIDE_ALIGN);
let size_mask = page_size() as u64 - 1;
let size = (height * stride + size_mask) & !size_mask;
let memfd = match uapi::memfd_create("udmabuf", MFD_ALLOW_SEALING) {
Ok(f) => f,
Err(e) => return Err(UdmabufError::Memfd(e.into())),
};
if let Err(e) = uapi::ftruncate(memfd.raw(), size as _) {
return Err(UdmabufError::Truncate(e.into()));
}
if let Err(e) = uapi::fcntl_add_seals(memfd.raw(), F_SEAL_SHRINK) {
return Err(UdmabufError::Seal(e.into()));
}
let memfd =
uapi::memfd_create("udmabuf", MFD_ALLOW_SEALING).map_os_err(UdmabufError::Memfd)?;
uapi::ftruncate(memfd.raw(), size as _).map_os_err(UdmabufError::Truncate)?;
uapi::fcntl_add_seals(memfd.raw(), F_SEAL_SHRINK).map_os_err(UdmabufError::Seal)?;
let dmabuf = self.create_dmabuf_from_memfd(&memfd, 0, size as _)?;
let mut planes = PlaneVec::new();
planes.push(DmaBufPlane {
@ -225,10 +219,7 @@ impl Allocator for Udmabuf {
if usize::try_from(size).is_err() {
return Err(UdmabufError::Overflow.into());
}
let stat = match uapi::fstat(plane.fd.raw()) {
Ok(s) => s,
Err(e) => return Err(UdmabufError::Stat(e.into()).into()),
};
let stat = uapi::fstat(plane.fd.raw()).map_os_err(UdmabufError::Stat)?;
if (stat.st_size as u64) < size {
return Err(UdmabufError::Size.into());
}
@ -293,8 +284,8 @@ impl Drop for UdmabufMap {
fn drop(&mut self) {
unsafe {
let res = munmap(self.ptr, self.len);
if let Err(e) = map_err!(res) {
log::error!("Could not unmap udmabuf: {}", OsError::from(e));
if let Err(e) = map_err!(res).to_os_error() {
log::error!("Could not unmap udmabuf: {}", e);
}
}
}

View file

@ -2,7 +2,7 @@ use {
crate::{
forker::ForkerError,
pr_caps::drop_all_pr_caps,
utils::{errorfmt::ErrorFmt, process_name::set_process_name},
utils::{errorfmt::ErrorFmt, oserror::OsErrorExt2, process_name::set_process_name},
},
run_on_drop::on_drop,
std::{env, mem::MaybeUninit, process, slice, str::FromStr},
@ -22,9 +22,9 @@ pub fn fork_with_pidfd(pidfd_for_child: bool) -> Result<Forked, ForkerError> {
child_pidfd = Some(uapi::pidfd_open(uapi::getpid(), 0).unwrap());
}
let (p, c) = uapi::socketpair(c::AF_UNIX, c::SOCK_DGRAM | c::SOCK_CLOEXEC, 0)
.map_err(|e| ForkerError::Socketpair(e.into()))?;
.map_os_err(ForkerError::Socketpair)?;
unsafe {
let pid = uapi::fork().map_err(|e| ForkerError::Fork(e.into()))?;
let pid = uapi::fork().map_os_err(ForkerError::Fork)?;
let res = if pid == 0 {
drop(p);
env::remove_var(REAPER_VAR);
@ -44,7 +44,7 @@ pub fn fork_with_pidfd(pidfd_for_child: bool) -> Result<Forked, ForkerError> {
pub fn double_fork() -> Result<Option<OwnedFd>, ForkerError> {
let (p, c) = uapi::socketpair(c::AF_UNIX, c::SOCK_DGRAM | c::SOCK_CLOEXEC, 0)
.map_err(|e| ForkerError::Socketpair(e.into()))?;
.map_os_err(ForkerError::Socketpair)?;
match fork_with_pidfd(false)? {
Forked::Parent { pid, .. } => {
drop(c);
@ -150,8 +150,8 @@ fn recv_pidfd(socket: &OwnedFd) -> Result<OwnedFd, ForkerError> {
flags: 0,
};
let (_, _, mut ctrl) = uapi::recvmsg(socket.raw(), &mut msghdr, c::MSG_CMSG_CLOEXEC)
.map_err(|e| ForkerError::RecvPidfd(e.into()))?;
let (_, hdr, data) = uapi::cmsg_read(&mut ctrl).map_err(|e| ForkerError::CmsgRead(e.into()))?;
.map_os_err(ForkerError::RecvPidfd)?;
let (_, hdr, data) = uapi::cmsg_read(&mut ctrl).map_os_err(ForkerError::CmsgRead)?;
if hdr.cmsg_level != c::SOL_SOCKET || hdr.cmsg_type != c::SCM_RIGHTS {
return Err(ForkerError::InvalidCmsg);
}

View file

@ -1,13 +1,16 @@
use {crate::utils::oserror::OsError, uapi::c};
use {
crate::utils::oserror::{OsError, OsErrorExt},
uapi::c,
};
pub fn set_nonblock(fd: c::c_int) -> Result<(), OsError> {
let fl = uapi::fcntl_getfl(fd)?;
uapi::fcntl_setfl(fd, fl | c::O_NONBLOCK)?;
let fl = uapi::fcntl_getfl(fd).to_os_error()?;
uapi::fcntl_setfl(fd, fl | c::O_NONBLOCK).to_os_error()?;
Ok(())
}
pub fn set_block(fd: c::c_int) -> Result<(), OsError> {
let fl = uapi::fcntl_getfl(fd)?;
uapi::fcntl_setfl(fd, fl & !c::O_NONBLOCK)?;
let fl = uapi::fcntl_getfl(fd).to_os_error()?;
uapi::fcntl_setfl(fd, fl & !c::O_NONBLOCK).to_os_error()?;
Ok(())
}

View file

@ -1,17 +1,17 @@
use {
crate::utils::oserror::OsError,
crate::utils::oserror::{OsError, OsErrorExt},
smallvec::{SmallVec, smallvec_inline},
uapi::{Errno, c},
uapi::c,
};
#[cfg_attr(not(feature = "it"), expect(dead_code))]
pub fn num_cpus() -> Result<u32, OsError> {
let mut buf: SmallVec<[usize; 32]> = smallvec_inline![0; 32];
loop {
match uapi::sched_getaffinity(0, &mut buf) {
match uapi::sched_getaffinity(0, &mut buf).to_os_error() {
Ok(_) => return Ok(count(&buf)),
Err(Errno(c::EINVAL)) => buf.extend_from_slice(&[0; 32][..]),
Err(e) => return Err(e.into()),
Err(OsError(c::EINVAL)) => buf.extend_from_slice(&[0; 32][..]),
Err(e) => return Err(e),
}
}
}

View file

@ -169,12 +169,6 @@ static ERRORS: LazyLock<&'static [Option<&'static str>]> = LazyLock::new(|| {
#[derive(Debug, Eq, PartialEq)]
pub struct OsError(pub c::c_int);
impl From<Errno> for OsError {
fn from(e: Errno) -> Self {
Self(e.0)
}
}
impl From<c::c_int> for OsError {
fn from(v: c_int) -> Self {
Self(v)
@ -192,7 +186,7 @@ impl From<std::io::Error> for OsError {
impl Default for OsError {
fn default() -> Self {
Errno::default().into()
OsError(Errno::default().0)
}
}
@ -208,7 +202,6 @@ impl Display for OsError {
}
}
#[cfg_attr(not(feature = "it"), expect(dead_code))]
pub trait OsErrorExt {
type Container;
@ -219,6 +212,31 @@ impl<T> OsErrorExt for Result<T, Errno> {
type Container = Result<T, OsError>;
fn to_os_error(self) -> Self::Container {
self.map_err(|e| e.into())
match self {
Ok(v) => Ok(v),
Err(e) => Err(OsError(e.0)),
}
}
}
pub trait OsErrorExt2 {
type T;
fn map_os_err<F, O>(self, op: O) -> Result<Self::T, F>
where
O: FnOnce(OsError) -> F;
}
impl<T> OsErrorExt2 for Result<T, Errno> {
type T = T;
fn map_os_err<F, O>(self, op: O) -> Result<T, F>
where
O: FnOnce(OsError) -> F,
{
match self {
Ok(t) => Ok(t),
Err(e) => Err(op(OsError(e.0))),
}
}
}

View file

@ -1,5 +1,5 @@
use {
crate::utils::{errorfmt::ErrorFmt, oserror::OsError},
crate::utils::{errorfmt::ErrorFmt, oserror::OsErrorExt},
bstr::ByteSlice,
std::os::unix::ffi::OsStrExt,
uapi::{OwnedFd, c},
@ -46,12 +46,12 @@ pub fn get_socket_creds(socket: &OwnedFd) -> Option<(c::uid_t, c::pid_t)> {
uid: 0,
gid: 0,
};
match uapi::getsockopt(socket.raw(), c::SOL_SOCKET, c::SO_PEERCRED, &mut cred) {
match uapi::getsockopt(socket.raw(), c::SOL_SOCKET, c::SO_PEERCRED, &mut cred).to_os_error() {
Ok(_) => Some((cred.uid, cred.pid)),
Err(e) => {
log::error!(
"Cannot determine peer credentials of new connection: {:?}",
OsError::from(e)
"Cannot determine peer credentials of new connection: {}",
ErrorFmt(e),
);
None
}

View file

@ -1,5 +1,5 @@
use {
crate::utils::oserror::OsError,
crate::utils::oserror::{OsError, OsErrorExt},
c::{c_int, syscall},
std::{ptr, rc::Rc},
uapi::{
@ -19,5 +19,5 @@ pub fn pidfd_send_signal(pidfd: &Rc<OwnedFd>, signal: c_int) -> Result<(), OsErr
0,
)
};
map_err!(res).map(drop).map_err(|e| e.into())
map_err!(res).map(drop).to_os_error()
}

View file

@ -1,5 +1,5 @@
use {
crate::utils::oserror::OsError,
crate::utils::oserror::{OsError, OsErrorExt},
uapi::{OwnedFd, c, pipe2},
};
@ -9,7 +9,7 @@ pub struct Pipe<L, R> {
}
pub fn pipe() -> Result<Pipe<OwnedFd, OwnedFd>, OsError> {
let (read, write) = pipe2(c::O_CLOEXEC)?;
let (read, write) = pipe2(c::O_CLOEXEC).to_os_error()?;
Ok(Pipe { read, write })
}

View file

@ -1,7 +1,10 @@
use {
crate::{
io_uring::{IoUring, IoUringError},
utils::{buf::TypedBuf, oserror::OsError},
utils::{
buf::TypedBuf,
oserror::{OsError, OsErrorExt2},
},
},
std::{cell::RefCell, rc::Rc, time::Duration},
thiserror::Error,
@ -28,10 +31,9 @@ pub struct TimerFd {
impl TimerFd {
pub fn new(clock_id: c::c_int) -> Result<Self, TimerError> {
let fd = match uapi::timerfd_create(clock_id, c::TFD_CLOEXEC) {
Ok(fd) => Rc::new(fd),
Err(e) => return Err(TimerError::CreateTimer(e.into())),
};
let fd = uapi::timerfd_create(clock_id, c::TFD_CLOEXEC)
.map(Rc::new)
.map_os_err(TimerError::CreateTimer)?;
Ok(Self {
fd,
buf: Rc::new(RefCell::new(TypedBuf::new())),
@ -61,9 +63,7 @@ impl TimerFd {
timerspec.it_interval.tv_nsec = per.subsec_nanos() as _;
}
}
if let Err(e) = uapi::timerfd_settime(self.fd.raw(), 0, &timerspec) {
return Err(TimerError::SetTimer(e.into()));
}
uapi::timerfd_settime(self.fd.raw(), 0, &timerspec).map_os_err(TimerError::SetTimer)?;
Ok(())
}
}

View file

@ -8,7 +8,11 @@ use {
format::Format,
io_uring::{IoUring, IoUringError},
utils::{
buf::Buf, errorfmt::ErrorFmt, oserror::OsError, stack::Stack, syncqueue::SyncQueue,
buf::Buf,
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt2},
stack::Stack,
syncqueue::SyncQueue,
vec_ext::VecExt,
},
video::{
@ -179,10 +183,9 @@ fn reopen(fd: c::c_int, need_primary: bool) -> Result<Rc<OwnedFd>, DrmError> {
}
device_node_name(fd)?
};
match uapi::open(path, c::O_RDWR | c::O_CLOEXEC, 0) {
Ok(f) => Ok(Rc::new(f)),
Err(e) => Err(DrmError::ReopenNode(e.into())),
}
uapi::open(path, c::O_RDWR | c::O_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(DrmError::ReopenNode)
}
pub struct Drm {
@ -192,7 +195,7 @@ pub struct Drm {
impl Drm {
pub fn open_existing(fd: Rc<OwnedFd>) -> Result<Self, DrmError> {
let stat = uapi::fstat(fd.raw()).map_err(|e| DrmError::Stat(e.into()))?;
let stat = uapi::fstat(fd.raw()).map_os_err(DrmError::Stat)?;
Ok(Self {
fd,
dev: stat.st_rdev,

View file

@ -7,7 +7,7 @@ use {
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
linkedlist::{LinkedList, LinkedNode},
oserror::OsError,
oserror::OsErrorExt2,
},
video::drm::{
DrmError, NodeType, get_drm_nodes_from_dev,
@ -116,8 +116,7 @@ impl SyncobjCtx {
.ok_or(DrmError::NoDeviceNodes)?;
let device_fd = uapi::open(path.as_c_str(), c::O_RDWR | c::O_CLOEXEC, 0)
.map(Rc::new)
.map_err(Into::into)
.map_err(DrmError::ReopenNode)?;
.map_os_err(DrmError::ReopenNode)?;
Ok(Self::new(&device_fd))
}
@ -193,9 +192,7 @@ impl SyncobjCtx {
fn supports_async_wait_(&self) -> Result<(), DrmError> {
let syncobj = self.create_syncobj()?;
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC)
.map_err(OsError::from)
.map_err(DrmError::EventFd)?;
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC).map_os_err(DrmError::EventFd)?;
self.wait_for_point(&eventfd, &syncobj, SyncobjPoint(1), true)?;
Ok(())
}

View file

@ -3,7 +3,11 @@
use {
crate::{
utils::{bitflags::BitflagsExt, compat::IoctlNumber, oserror::OsError},
utils::{
bitflags::BitflagsExt,
compat::IoctlNumber,
oserror::{OsError, OsErrorExt},
},
video::drm::{
DrmBlob, DrmCardResources, DrmConnector, DrmConnectorInfo, DrmCrtc, DrmEncoder,
DrmEncoderInfo, DrmError, DrmFb, DrmModeInfo, DrmPlane, DrmPlaneInfo, DrmProperty,
@ -124,10 +128,10 @@ pub fn get_minor_name_from_fd(fd: c::c_int, ty: NodeType) -> Result<Ustring, OsE
let (_, maj, min) = drm_stat(fd)?;
let dir = device_dir(maj, min);
let mut dir = uapi::opendir(dir)?;
let mut dir = uapi::opendir(dir).to_os_error()?;
while let Some(entry) = uapi::readdir(&mut dir) {
let entry = entry?;
let entry = entry.to_os_error()?;
if entry.name().to_bytes().starts_with_str(ty.name()) {
return Ok(uapi::format_ustr!(
"{}/{}",
@ -140,7 +144,7 @@ pub fn get_minor_name_from_fd(fd: c::c_int, ty: NodeType) -> Result<Ustring, OsE
}
fn drm_stat(fd: c::c_int) -> Result<(c::stat, u64, u64), OsError> {
let stat = uapi::fstat(fd)?;
let stat = uapi::fstat(fd).to_os_error()?;
let maj = uapi::major(stat.st_rdev);
let min = uapi::minor(stat.st_rdev);
@ -160,7 +164,7 @@ pub fn get_device_name_from_fd2(fd: c::c_int) -> Result<Ustring, OsError> {
let (_, maj, min) = drm_stat(fd)?;
let path = uapi::format_ustr!("/sys/dev/char/{maj}:{min}/uevent");
let mut buf = vec![];
let mut br = BufReader::new(uapi::open(path, c::O_RDONLY, 0)?);
let mut br = BufReader::new(uapi::open(path, c::O_RDONLY, 0).to_os_error()?);
loop {
buf.clear();
if br.read_until(b'\n', &mut buf)? == 0 {
@ -180,12 +184,12 @@ pub fn get_nodes(fd: c::c_int) -> Result<AHashMap<NodeType, CString>, OsError> {
pub fn get_drm_nodes_from_dev(maj: u64, min: u64) -> Result<AHashMap<NodeType, CString>, OsError> {
let dir = device_dir(maj, min);
let mut dir = uapi::opendir(dir)?;
let mut dir = uapi::opendir(dir).to_os_error()?;
let mut res = AHashMap::new();
'outer: while let Some(entry) = uapi::readdir(&mut dir) {
let entry = entry?;
let entry = entry.to_os_error()?;
let name = entry.name().to_bytes();
let ty = 'ty: {
for ty in [NodeType::Render, NodeType::Control, NodeType::Primary] {

View file

@ -4,7 +4,7 @@ use {
io_uring::IoUring,
utils::{
asyncevent::AsyncEvent, buf::Buf, clonecell::CloneCell, copyhashmap::CopyHashMap,
hash_map_ext::HashMapExt, numcell::NumCell, oserror::OsError, stack::Stack,
hash_map_ext::HashMapExt, numcell::NumCell, oserror::OsErrorExt2, stack::Stack,
},
video::drm::{
DrmError,
@ -136,9 +136,7 @@ impl WaitForSyncobj {
let waiter = match self.inner.idle.pop() {
Some(w) => w,
None => {
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC)
.map_err(OsError::from)
.map_err(DrmError::EventFd)?;
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC).map_os_err(DrmError::EventFd)?;
let waiter = Rc::new(WaiterInner {
inner: self.inner.clone(),
eventfd: Rc::new(eventfd),

View file

@ -4,8 +4,13 @@ use {
io_uring::{IoUring, IoUringError},
time::Time,
utils::{
buf::TypedBuf, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, hash_map_ext::HashMapExt,
numcell::NumCell, oserror::OsError, stack::Stack,
buf::TypedBuf,
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
numcell::NumCell,
oserror::{OsError, OsErrorExt, OsErrorExt2},
stack::Stack,
},
},
std::{
@ -110,10 +115,9 @@ pub struct WheelData {
impl Wheel {
pub fn new(eng: &Rc<AsyncEngine>, ring: &Rc<IoUring>) -> Result<Rc<Self>, WheelError> {
let fd = match uapi::timerfd_create(c::CLOCK_MONOTONIC, c::TFD_CLOEXEC) {
Ok(fd) => Rc::new(fd),
Err(e) => return Err(WheelError::CreateFailed(e.into())),
};
let fd = uapi::timerfd_create(c::CLOCK_MONOTONIC, c::TFD_CLOEXEC)
.map(Rc::new)
.map_os_err(WheelError::CreateFailed)?;
let data = Rc::new(WheelData {
destroyed: Cell::new(false),
ring: ring.clone(),
@ -173,11 +177,8 @@ impl Wheel {
it_value: expiration.0,
},
);
if let Err(e) = res {
future
.data
.expired
.set(Some(Err(WheelError::SetFailed(e.into()))));
if let Err(e) = res.to_os_error() {
future.data.expired.set(Some(Err(WheelError::SetFailed(e))));
return future;
}
self.data.current_expiration.set(Some(expiration));
@ -234,17 +235,15 @@ impl WheelData {
self.current_expiration.set(None);
while let Some(Reverse(entry)) = expirations.peek() {
if self.dispatchers.get(&entry.id).is_some() {
let res = uapi::timerfd_settime(
uapi::timerfd_settime(
self.fd.raw(),
c::TFD_TIMER_ABSTIME,
&c::itimerspec {
it_interval: uapi::pod_zeroed(),
it_value: entry.expiration.0,
},
);
if let Err(e) = res {
return Err(WheelError::SetFailed(e.into()));
}
)
.map_os_err(WheelError::SetFailed)?;
self.current_expiration.set(Some(entry.expiration));
break;
}

View file

@ -18,7 +18,7 @@ use {
copyhashmap::CopyHashMap,
errorfmt::ErrorFmt,
hash_map_ext::HashMapExt,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
},
video::dmabuf::DmaBufIds,
wheel::Wheel,
@ -99,10 +99,9 @@ impl UsrCon {
path: &str,
server_id: u32,
) -> Result<Rc<Self>, UsrConError> {
let socket = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(s) => Rc::new(s),
Err(e) => return Err(UsrConError::CreateSocket(e.into())),
};
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(UsrConError::CreateSocket)?;
let mut addr: c::sockaddr_un = uapi::pod_zeroed();
addr.sun_family = c::AF_UNIX as _;
if path.len() >= addr.sun_path.len() {

View file

@ -15,7 +15,7 @@ use {
clonecell::CloneCell,
errorfmt::ErrorFmt,
numcell::NumCell,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
queue::AsyncQueue,
stack::Stack,
vec_ext::VecExt,
@ -408,18 +408,16 @@ impl Xcon {
let mut path = uapi::as_bytes_mut(&mut addr.sun_path[..]);
let _ = write!(path, "/tmp/.X11-unix/X{}", display);
}
let fd = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(fd) => Rc::new(fd),
Err(e) => return Err(XconError::CreateSocket(e.into())),
};
let fd = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(XconError::CreateSocket)?;
if let Err(e) = state.ring.connect(&fd, &addr).await {
return Err(XconError::ConnectSocket(e));
}
let mut hnbuf = [MaybeUninit::<u8>::uninit(); 256];
let hn = match uapi::gethostname(&mut hnbuf[..]) {
Ok(hn) => hn.to_bytes(),
Err(e) => return Err(XconError::Hostname(e.into())),
};
let hn = uapi::gethostname(&mut hnbuf[..])
.map(|hn| hn.to_bytes())
.map_os_err(XconError::Hostname)?;
let (auth_method, auth_value) = 'auth: {
for auth in &authority {
if auth.display == display

View file

@ -20,7 +20,7 @@ use {
buf::Buf,
errorfmt::ErrorFmt,
line_logger::log_lines,
oserror::OsError,
oserror::{OsError, OsErrorExt2},
pipe::{Pipe, pipe},
},
wire::WlSurfaceId,
@ -167,16 +167,10 @@ async fn run(
Ok(p) => p,
Err(e) => return Err(XWaylandError::Pipe(e)),
};
let wm = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0);
let (wm1, wm2) = match wm {
Ok(w) => w,
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
};
let client = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0);
let (client1, client2) = match client {
Ok(w) => w,
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
};
let (wm1, wm2) = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map_os_err(XWaylandError::Socketpair)?;
let (client1, client2) = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map_os_err(XWaylandError::Socketpair)?;
let stderr_read = state
.eng
.spawn("log Xwayland", log_xwayland(state.clone(), stderr_read));

View file

@ -1,5 +1,11 @@
use {
crate::{utils::errorfmt::ErrorFmt, xwayland::XWaylandError},
crate::{
utils::{
errorfmt::ErrorFmt,
oserror::{OsError, OsErrorExt, OsErrorExt2},
},
xwayland::XWaylandError,
},
std::{
io::{Read, Write},
rc::Rc,
@ -37,10 +43,8 @@ fn bind_socket(fd: &Rc<OwnedFd>, id: u32) -> Result<(XSocket, Rc<OwnedFd>), XWay
if i == 1 {
return Err(XWaylandError::AlreadyInUse);
}
let mut fd = match uapi::open(&*lock_path, c::O_CLOEXEC | c::O_RDONLY, 0) {
Ok(f) => f,
Err(e) => return Err(XWaylandError::ReadLockFile(e.into())),
};
let mut fd = uapi::open(&*lock_path, c::O_CLOEXEC | c::O_RDONLY, 0)
.map_os_err(XWaylandError::ReadLockFile)?;
let mut pid = String::new();
if let Err(e) = fd.read_to_string(&mut pid) {
return Err(XWaylandError::ReadLockFile(e.into()));
@ -64,9 +68,7 @@ fn bind_socket(fd: &Rc<OwnedFd>, id: u32) -> Result<(XSocket, Rc<OwnedFd>), XWay
let sun_path = uapi::as_bytes_mut(&mut addr.sun_path[..]);
sun_path[..path.len()].copy_from_slice(path.as_bytes());
sun_path[path.len()] = 0;
if let Err(e) = uapi::bind(fd.raw(), &addr) {
return Err(XWaylandError::BindFailed(e.into()));
}
uapi::bind(fd.raw(), &addr).map_os_err(XWaylandError::BindFailed)?;
let s = format!("{:10}\n", uapi::getpid());
if let Err(e) = lock_fd.write_all(s.as_bytes()) {
return Err(XWaylandError::WriteLockFile(e.into()));
@ -80,9 +82,9 @@ fn bind_socket(fd: &Rc<OwnedFd>, id: u32) -> Result<(XSocket, Rc<OwnedFd>), XWay
}
pub(super) fn allocate_socket() -> Result<(XSocket, Rc<OwnedFd>), XWaylandError> {
match uapi::stat(SOCK_DIR) {
Err(Errno(c::ENOENT)) => return Err(XWaylandError::MissingSocketDir),
Err(e) => return Err(XWaylandError::StatSocketDir(e.into())),
match uapi::stat(SOCK_DIR).to_os_error() {
Err(OsError(c::ENOENT)) => return Err(XWaylandError::MissingSocketDir),
Err(e) => return Err(XWaylandError::StatSocketDir(e)),
Ok(s) if s.st_mode & c::S_IFMT != c::S_IFDIR => return Err(XWaylandError::NotASocketDir),
_ => {
if uapi::access(SOCK_DIR, c::W_OK).is_err() {
@ -90,10 +92,9 @@ pub(super) fn allocate_socket() -> Result<(XSocket, Rc<OwnedFd>), XWaylandError>
}
}
}
let fd = match uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0) {
Ok(f) => Rc::new(f),
Err(e) => return Err(XWaylandError::SocketFailed(e.into())),
};
let fd = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
.map(Rc::new)
.map_os_err(XWaylandError::SocketFailed)?;
for i in 500..1500 {
match bind_socket(&fd, i) {
Ok(s) => return Ok(s),