#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum OpenOrCreatePosixMessageQueue
{
OpenIfAlreadyExistsOrFail,
OpenOrCreateIfDoesNotExist(PosixMessageQueueCreateSettings),
CreateIfItDoesNotExistOrFail(PosixMessageQueueCreateSettings),
}
impl OpenOrCreatePosixMessageQueue
{
#[inline(always)]
pub(crate) fn invoke_mq_open(&self, send_or_receive: PosixMessageQueueCreateSendOrReceive, name: &CStr) -> Result<PosixMessageQueueFileDescriptor, CreationError>
{
PosixMessageQueueFileDescriptor::guard_name(name);
use self::OpenOrCreatePosixMessageQueue::*;
let oflag = send_or_receive as i32;
let name_pointer = name.as_ptr();
use self::CreationError::*;
match self
{
&OpenIfAlreadyExistsOrFail =>
{
let result = unsafe { mq_open(name_pointer, oflag) };
if likely!(result >= 0)
{
Ok(PosixMessageQueueFileDescriptor(result))
}
else if likely!(result == 0)
{
Err
(
match errno().0
{
EACCES => PermissionDenied,
EMFILE => PerProcessLimitOnNumberOfFileDescriptorsWouldBeExceeded,
ENFILE | ENOSPC => SystemWideLimitOnTotalNumberOfFileDescriptorsWouldBeExceeded,
ENOMEM => KernelWouldBeOutOfMemory,
ENOENT => panic!("No queue with this name exists"),
ENAMETOOLONG => panic!("`name` is too long"),
EINVAL => panic!("`name` is invalid in some way"),
_ => unreachable_code(format_args!("")),
}
)
}
else
{
unreachable_code(format_args!(""));
}
}
&OpenOrCreateIfDoesNotExist(ref create_settings) =>
{
let result = create_settings.invoke_mq_open(name_pointer, oflag | O_CREAT);
if likely!(result >= 0)
{
Ok(PosixMessageQueueFileDescriptor(result))
}
else if likely!(result == 0)
{
Err
(
match errno().0
{
EACCES => PermissionDenied,
EMFILE => PerProcessLimitOnNumberOfFileDescriptorsWouldBeExceeded,
ENFILE | ENOSPC => SystemWideLimitOnTotalNumberOfFileDescriptorsWouldBeExceeded,
ENOMEM => KernelWouldBeOutOfMemory,
EINVAL => PermissionDenied,
ENOENT => panic!("`name` was just \"/\" followed by no other characters"),
ENAMETOOLONG => panic!("`name` is too long"),
_ => unreachable_code(format_args!("")),
}
)
}
else
{
unreachable_code(format_args!(""));
}
}
&CreateIfItDoesNotExistOrFail(ref create_settings) =>
{
let result = create_settings.invoke_mq_open(name_pointer, oflag | O_CREAT | O_EXCL);
if likely!(result >= 0)
{
Ok(PosixMessageQueueFileDescriptor(result))
}
else if likely!(result == 0)
{
Err
(
match errno().0
{
EACCES => PermissionDenied,
EMFILE => PerProcessLimitOnNumberOfFileDescriptorsWouldBeExceeded,
ENFILE | ENOSPC => SystemWideLimitOnTotalNumberOfFileDescriptorsWouldBeExceeded,
ENOMEM => KernelWouldBeOutOfMemory,
EINVAL => PermissionDenied,
ENOENT => panic!("`name` was just \"/\" followed by no other characters"),
ENAMETOOLONG => panic!("`name` is too long"),
EEXIST => panic!("queue already exists"),
_ => unreachable_code(format_args!("")),
}
)
}
else
{
unreachable_code(format_args!(""));
}
}
}
}
}