2023-12-08 17:01:42 +01:00
//! Contains the error types used by the [`listen`](super) module.
#![ allow(clippy::module_name_repetitions) ]
2023-12-07 18:02:35 +01:00
use core ::fmt ::Display ;
use core ::num ::ParseIntError ;
use std ::error ::Error ;
use std ::ffi ::OsString ;
2023-12-08 10:03:55 +01:00
use rustix ::io ::Errno ;
2023-12-08 12:54:41 +01:00
use super ::{ FD_NAMES_VAR , FD_NUMBER_VAR , PID_VAR } ;
2023-12-07 18:02:35 +01:00
2023-12-08 17:01:42 +01:00
/// Errors that might happens when receiving file descriptors using [`FileDescriptor::receive()`](super::FileDescriptor::receive())
2023-12-07 18:02:35 +01:00
#[ derive(Debug) ]
pub enum ReceiveError {
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_PID` didn't exists (probably meaning that no file descriptor was passed to us).
2023-12-07 18:02:35 +01:00
NoListenPID ,
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_PID` (which should be a decimal number) isn't unicode.
2023-12-07 18:02:35 +01:00
NotUnicodeListenPID ( OsString ) ,
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_PID` couldn't be parsed as a [`u32`] (real [`pid_t`](libc::pid_t) due to [`std::process::id`])
2023-12-07 18:02:35 +01:00
ListenPIDParse ( ParseIntError ) ,
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_FDS` didn't exists (probably meaning that no file descriptor was passed to us)
2023-12-07 18:02:35 +01:00
NoListenFD ,
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_FDS` (which should be a decimal number) isn't unicode.
2023-12-07 18:02:35 +01:00
NotUnicodeListenFD ( OsString ) ,
2023-12-07 21:39:33 +01:00
/// The environement variable `LISTEN_FDS` couldn't be parsed as a [`usize`].
2023-12-07 18:02:35 +01:00
ListenFDParse ( ParseIntError ) ,
2023-12-07 21:39:33 +01:00
/// Our PID isn't the one expected as per `LISTEN_PID`.
2023-12-07 21:13:06 +01:00
PidMismatch { expected : u32 , found : u32 } ,
2023-12-07 21:39:33 +01:00
/// We couldn't get the file descriptors (see [`GetFdsError`])
2023-12-07 18:02:35 +01:00
GetFds ( GetFdsError ) ,
}
impl Display for ReceiveError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
write! ( f , " Couldn't receive file descriptors : " ) ? ;
match self {
ReceiveError ::NoListenPID = > write! ( f , " The variable {PID_VAR} doesn't exists. " ) ,
ReceiveError ::NotUnicodeListenPID ( var ) = > write! ( f , " The variable {PID_VAR} isn't unicode (this should never happen): it is {var:?} " ) ,
ReceiveError ::ListenPIDParse ( error ) = > write! ( f , " Couldn't parse {PID_VAR} as a `u32`: {error} " ) ,
ReceiveError ::NoListenFD = > write! ( f , " The variable {FD_NUMBER_VAR} doesn't exists. " ) ,
ReceiveError ::NotUnicodeListenFD ( var ) = > write! ( f , " The variable {FD_NUMBER_VAR} isn't unicode (this should never happen): it is {var:?} " ) ,
ReceiveError ::ListenFDParse ( error ) = > write! ( f , " Couldn't parse {FD_NUMBER_VAR} as a `u32`: {error} " ) ,
ReceiveError ::PidMismatch { expected , found } = > write! ( f , " PID mismatch! Was {found} but should have been {expected}. " ) ,
ReceiveError ::GetFds ( error ) = > Display ::fmt ( error , f ) ,
}
}
}
impl Error for ReceiveError {
fn source ( & self ) -> Option < & ( dyn Error + 'static ) > {
match self {
2023-12-07 21:39:33 +01:00
ReceiveError ::NoListenPID
| ReceiveError ::NotUnicodeListenPID ( _ )
| ReceiveError ::NoListenFD
| ReceiveError ::NotUnicodeListenFD ( _ )
| ReceiveError ::PidMismatch {
2023-12-07 21:13:06 +01:00
expected : _ ,
found : _ ,
} = > None ,
2023-12-07 21:39:33 +01:00
ReceiveError ::ListenPIDParse ( error ) | ReceiveError ::ListenFDParse ( error ) = > Some ( error ) ,
2023-12-07 18:02:35 +01:00
ReceiveError ::GetFds ( error ) = > Some ( error ) ,
}
}
}
2023-12-08 17:01:42 +01:00
/// Errors that might happens when receiving file descriptors along with their names using [`FileDescriptor::receive_with_names()`](super::FileDescriptor::receive_with_names()).
2023-12-07 18:02:35 +01:00
#[ derive(Debug) ]
pub enum ReceiveNameError {
2023-12-07 21:39:33 +01:00
/// The variable `LISTEN_FDNAMES` didn't exists.
2023-12-07 18:02:35 +01:00
NoListenFDName ,
2023-12-07 21:39:33 +01:00
/// No file descriptors could be received.
2023-12-07 18:02:35 +01:00
Receive ( ReceiveError ) ,
}
impl From < ReceiveError > for ReceiveNameError {
fn from ( value : ReceiveError ) -> Self {
Self ::Receive ( value )
}
}
impl Display for ReceiveNameError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
match self {
2023-12-07 21:13:06 +01:00
ReceiveNameError ::NoListenFDName = > write! (
f ,
" Couldn't find FDs name : the variable {FD_NAMES_VAR} doesn't exists. "
) ,
2023-12-07 18:02:35 +01:00
ReceiveNameError ::Receive ( error ) = > Display ::fmt ( error , f ) ,
}
}
}
impl Error for ReceiveNameError {
fn source ( & self ) -> Option < & ( dyn Error + 'static ) > {
match self {
ReceiveNameError ::NoListenFDName = > None ,
ReceiveNameError ::Receive ( error ) = > Some ( error ) ,
}
}
}
2023-12-08 17:01:42 +01:00
/// Errors that might be obtained when producing the iterator in [`FileDescriptor::receive()`](super::FileDescriptor::receive())
2023-12-07 18:02:35 +01:00
#[ derive(Debug) ]
pub enum GetFdsError {
2023-12-08 17:01:42 +01:00
/// Too many file descriptors were passed so we overflowed when adding `SD_LISTEN_FDS_START` (3)
2023-12-07 18:02:35 +01:00
TooManyFDs ( usize ) ,
}
impl Display for GetFdsError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
match self {
GetFdsError ::TooManyFDs ( size ) = > write! ( f , " Too many file descriptors ({size}) " ) ,
}
}
}
2023-12-07 21:13:06 +01:00
impl Error for GetFdsError { }
2023-12-08 10:03:55 +01:00
2023-12-08 17:01:42 +01:00
/// Errors when trying to duplicate the received file descriptors using [`rustix::fs::fcntl_dupfd_cloexec`].
2023-12-08 10:03:55 +01:00
#[ derive(Debug) ]
pub enum DupError {
2023-12-08 17:01:42 +01:00
/// The file descriptor we are attempting to duplicate isn't open.
2023-12-08 10:03:55 +01:00
InvalidFd ( Errno ) ,
2023-12-08 17:01:42 +01:00
/// Some other problem in the arguments passed to [`fcntl`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html).
2023-12-08 10:03:55 +01:00
InvalidArgument ( Errno ) ,
2023-12-08 17:01:42 +01:00
/// No file descriptor was available to us.
2023-12-08 10:03:55 +01:00
NoAvailableFd ( Errno ) ,
2023-12-08 17:01:42 +01:00
/// Some other error (see [`Errno`] and [`fcntl`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html) for details).
///
/// Please fill a bug if you see this variant so that we might add a more precise variant.
2023-12-08 10:03:55 +01:00
Other ( Errno ) ,
}
impl From < Errno > for DupError {
fn from ( value : Errno ) -> Self {
if value = = Errno ::INVAL {
Self ::InvalidArgument ( value )
} else if value = = Errno ::MFILE {
Self ::NoAvailableFd ( value )
} else if value = = Errno ::BADF {
Self ::InvalidFd ( value )
} else {
Self ::Other ( value )
}
}
}
impl Display for DupError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
f . write_str ( " Couldn't duplicate FD : " ) ? ;
match self {
DupError ::InvalidFd ( _ ) = > {
f . write_str ( " The file descriptor isn't valid (probably closed in the meantime). " )
}
DupError ::InvalidArgument ( _ ) = > f . write_str ( " Invalid argument. " ) ,
DupError ::NoAvailableFd ( _ ) = > {
f . write_str ( " Too many file descriptors are already open. " )
}
DupError ::Other ( err ) = > Display ::fmt ( err , f ) ,
}
}
}
impl Error for DupError {
fn source ( & self ) -> Option < & ( dyn Error + 'static ) > {
match self {
DupError ::InvalidArgument ( error )
| DupError ::InvalidFd ( error )
| DupError ::NoAvailableFd ( error )
| DupError ::Other ( error ) = > Some ( error ) ,
}
}
}