1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use nix;
use std::error;
use std::fmt;
use std::io;
use std::num;
#[derive(Debug)]
pub enum Error {
InvalidQueueName(&'static str),
ValueReadingError(io::Error),
MessageSizeExceeded(),
MaximumMessageSizeExceeded(),
MaximumMessageCountExceeded(),
PermissionDenied(),
InvalidQueueDescriptor(),
QueueCallInterrupted(),
QueueAlreadyExists(),
QueueNotFound(),
InsufficientMemory(),
InsufficientSpace(),
ProcessFileDescriptorLimitReached(),
SystemFileDescriptorLimitReached(),
UnknownForeignError(nix::errno::Errno),
UnknownInternalError(Option<nix::Error>),
}
impl error::Error for Error {
fn description(&self) -> &str {
use Error::*;
match *self {
InvalidQueueName(e) => e,
ValueReadingError(_) => "error reading system configuration for message queues",
MessageSizeExceeded() => "message is larger than maximum size for specified queue",
MaximumMessageSizeExceeded() => "specified queue message size exceeds system maximum",
MaximumMessageCountExceeded() => "specified queue message count exceeds system maximum",
PermissionDenied() => "permission to the specified queue was denied",
InvalidQueueDescriptor() => "the internal queue descriptor was invalid",
QueueCallInterrupted() => "queue method interrupted by signal",
QueueAlreadyExists() => "the specified queue already exists",
QueueNotFound() => "the specified queue could not be found",
InsufficientMemory() => "insufficient memory to call queue method",
InsufficientSpace() => "insufficient space to call queue method",
ProcessFileDescriptorLimitReached() =>
"maximum number of process file descriptors reached",
SystemFileDescriptorLimitReached() =>
"maximum number of system file descriptors reached",
UnknownForeignError(_) => "unknown foreign error occured: please report a bug!",
UnknownInternalError(_) => "unknown internal error occured: please report a bug!",
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use std::error::Error;
f.write_str(self.description())
}
}
impl From<nix::Error> for Error {
fn from(e: nix::Error) -> Self {
match e {
nix::Error::Sys(e) => match_errno(e),
_ => Error::UnknownInternalError(Some(e)),
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::ValueReadingError(e)
}
}
impl From<num::ParseIntError> for Error {
fn from(_: num::ParseIntError) -> Self {
Error::UnknownInternalError(None)
}
}
fn match_errno(err: nix::errno::Errno) -> Error {
use nix::errno::Errno::*;
match err {
EACCES => Error::PermissionDenied(),
EBADF => Error::InvalidQueueDescriptor(),
EINTR => Error::QueueCallInterrupted(),
EEXIST => Error::QueueAlreadyExists(),
EMFILE => Error::ProcessFileDescriptorLimitReached(),
ENFILE => Error::SystemFileDescriptorLimitReached(),
ENOENT => Error::QueueNotFound(),
ENOMEM => Error::InsufficientMemory(),
ENOSPC => Error::InsufficientSpace(),
_ => Error::UnknownForeignError(err),
}
}