rustix/backend/linux_raw/io/
errno.rs1#![allow(unsafe_code)]
11#![cfg_attr(not(rustc_attrs), allow(unused_unsafe))]
12
13use crate::backend::c;
14use crate::backend::fd::RawFd;
15use crate::backend::reg::{RetNumber, RetReg};
16use crate::io;
17use linux_raw_sys::errno;
18
19#[repr(transparent)]
45#[doc(alias = "errno")]
46#[derive(Eq, PartialEq, Hash, Copy, Clone)]
47#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0xf001))]
50#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xffff))]
51pub struct Errno(u16);
52
53impl Errno {
54 #[cfg(feature = "std")]
59 #[inline]
60 pub fn from_io_error(io_err: &std::io::Error) -> Option<Self> {
61 io_err.raw_os_error().and_then(|raw| {
62 if (1..4096).contains(&raw) {
65 Some(Self::from_errno(raw as u32))
66 } else {
67 None
68 }
69 })
70 }
71
72 #[inline]
74 pub const fn raw_os_error(self) -> i32 {
75 (self.0 as i16 as i32).wrapping_neg()
76 }
77
78 #[inline]
80 pub const fn from_raw_os_error(raw: i32) -> Self {
81 Self::from_errno(raw as u32)
82 }
83
84 const fn from_errno(raw: u32) -> Self {
86 let encoded = raw.wrapping_neg() as u16;
89
90 assert!(encoded >= 0xf001);
92
93 unsafe { Self(encoded) }
96 }
97}
98
99#[inline]
102pub(in crate::backend) fn try_decode_c_int<Num: RetNumber>(
103 raw: RetReg<Num>,
104) -> io::Result<c::c_int> {
105 if raw.is_in_range(-4095..0) {
106 return Err(unsafe { Errno(raw.decode_error_code()) });
109 }
110
111 Ok(raw.decode_c_int())
112}
113
114#[inline]
117pub(in crate::backend) fn try_decode_c_uint<Num: RetNumber>(
118 raw: RetReg<Num>,
119) -> io::Result<c::c_uint> {
120 if raw.is_in_range(-4095..0) {
121 return Err(unsafe { Errno(raw.decode_error_code()) });
124 }
125
126 Ok(raw.decode_c_uint())
127}
128
129#[inline]
132pub(in crate::backend) fn try_decode_usize<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<usize> {
133 if raw.is_in_range(-4095..0) {
134 return Err(unsafe { Errno(raw.decode_error_code()) });
137 }
138
139 Ok(raw.decode_usize())
140}
141
142#[inline]
145pub(in crate::backend) fn try_decode_void_star<Num: RetNumber>(
146 raw: RetReg<Num>,
147) -> io::Result<*mut c::c_void> {
148 if raw.is_in_range(-4095..0) {
149 return Err(unsafe { Errno(raw.decode_error_code()) });
152 }
153
154 Ok(raw.decode_void_star())
155}
156
157#[cfg(target_pointer_width = "64")]
160#[inline]
161pub(in crate::backend) fn try_decode_u64<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<u64> {
162 if raw.is_in_range(-4095..0) {
163 return Err(unsafe { Errno(raw.decode_error_code()) });
166 }
167
168 Ok(raw.decode_u64())
169}
170
171#[inline]
179pub(in crate::backend) unsafe fn try_decode_raw_fd<Num: RetNumber>(
180 raw: RetReg<Num>,
181) -> io::Result<RawFd> {
182 if raw.is_negative() {
186 debug_assert!(raw.is_in_range(-4095..0));
187
188 #[cfg(core_intrinsics)]
191 {
192 core::intrinsics::assume(raw.is_in_range(-4095..0));
193 }
194
195 return Err(Errno(raw.decode_error_code()));
196 }
197
198 Ok(raw.decode_raw_fd())
199}
200
201#[inline]
208pub(in crate::backend) unsafe fn try_decode_void<Num: RetNumber>(
209 raw: RetReg<Num>,
210) -> io::Result<()> {
211 if raw.is_nonzero() {
215 debug_assert!(raw.is_in_range(-4095..0));
216
217 #[cfg(core_intrinsics)]
220 {
221 core::intrinsics::assume(raw.is_in_range(-4095..0));
222 }
223
224 return Err(Errno(raw.decode_error_code()));
225 }
226
227 raw.decode_void();
228
229 Ok(())
230}
231
232#[cfg(any(feature = "event", feature = "runtime", feature = "system"))]
239#[inline]
240pub(in crate::backend) unsafe fn try_decode_error<Num: RetNumber>(raw: RetReg<Num>) -> io::Errno {
241 debug_assert!(raw.is_in_range(-4095..0));
242
243 #[cfg(core_intrinsics)]
246 {
247 core::intrinsics::assume(raw.is_in_range(-4095..0));
248 }
249
250 Errno(raw.decode_error_code())
251}
252
253#[cfg(not(debug_assertions))]
255#[inline]
256pub(in crate::backend) fn decode_usize_infallible<Num: RetNumber>(raw: RetReg<Num>) -> usize {
257 raw.decode_usize()
258}
259
260#[cfg(not(debug_assertions))]
262#[inline]
263pub(in crate::backend) fn decode_c_int_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_int {
264 raw.decode_c_int()
265}
266
267#[cfg(not(debug_assertions))]
269#[inline]
270pub(in crate::backend) fn decode_c_uint_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_uint {
271 raw.decode_c_uint()
272}
273
274impl Errno {
275 #[doc(alias = "ACCES")]
277 pub const ACCESS: Self = Self::from_errno(errno::EACCES);
278 pub const ADDRINUSE: Self = Self::from_errno(errno::EADDRINUSE);
280 pub const ADDRNOTAVAIL: Self = Self::from_errno(errno::EADDRNOTAVAIL);
282 pub const ADV: Self = Self::from_errno(errno::EADV);
284 pub const AFNOSUPPORT: Self = Self::from_errno(errno::EAFNOSUPPORT);
286 pub const AGAIN: Self = Self::from_errno(errno::EAGAIN);
288 pub const ALREADY: Self = Self::from_errno(errno::EALREADY);
290 pub const BADE: Self = Self::from_errno(errno::EBADE);
292 pub const BADF: Self = Self::from_errno(errno::EBADF);
294 pub const BADFD: Self = Self::from_errno(errno::EBADFD);
296 pub const BADMSG: Self = Self::from_errno(errno::EBADMSG);
298 pub const BADR: Self = Self::from_errno(errno::EBADR);
300 pub const BADRQC: Self = Self::from_errno(errno::EBADRQC);
302 pub const BADSLT: Self = Self::from_errno(errno::EBADSLT);
304 pub const BFONT: Self = Self::from_errno(errno::EBFONT);
306 pub const BUSY: Self = Self::from_errno(errno::EBUSY);
308 pub const CANCELED: Self = Self::from_errno(errno::ECANCELED);
310 pub const CHILD: Self = Self::from_errno(errno::ECHILD);
312 pub const CHRNG: Self = Self::from_errno(errno::ECHRNG);
314 pub const COMM: Self = Self::from_errno(errno::ECOMM);
316 pub const CONNABORTED: Self = Self::from_errno(errno::ECONNABORTED);
318 pub const CONNREFUSED: Self = Self::from_errno(errno::ECONNREFUSED);
320 pub const CONNRESET: Self = Self::from_errno(errno::ECONNRESET);
322 pub const DEADLK: Self = Self::from_errno(errno::EDEADLK);
324 pub const DEADLOCK: Self = Self::from_errno(errno::EDEADLOCK);
326 pub const DESTADDRREQ: Self = Self::from_errno(errno::EDESTADDRREQ);
328 pub const DOM: Self = Self::from_errno(errno::EDOM);
330 pub const DOTDOT: Self = Self::from_errno(errno::EDOTDOT);
332 pub const DQUOT: Self = Self::from_errno(errno::EDQUOT);
334 pub const EXIST: Self = Self::from_errno(errno::EEXIST);
336 pub const FAULT: Self = Self::from_errno(errno::EFAULT);
338 pub const FBIG: Self = Self::from_errno(errno::EFBIG);
340 pub const HOSTDOWN: Self = Self::from_errno(errno::EHOSTDOWN);
342 pub const HOSTUNREACH: Self = Self::from_errno(errno::EHOSTUNREACH);
344 pub const HWPOISON: Self = Self::from_errno(errno::EHWPOISON);
346 pub const IDRM: Self = Self::from_errno(errno::EIDRM);
348 pub const ILSEQ: Self = Self::from_errno(errno::EILSEQ);
350 pub const INPROGRESS: Self = Self::from_errno(errno::EINPROGRESS);
352 pub const INTR: Self = Self::from_errno(errno::EINTR);
359 pub const INVAL: Self = Self::from_errno(errno::EINVAL);
361 pub const IO: Self = Self::from_errno(errno::EIO);
363 pub const ISCONN: Self = Self::from_errno(errno::EISCONN);
365 pub const ISDIR: Self = Self::from_errno(errno::EISDIR);
367 pub const ISNAM: Self = Self::from_errno(errno::EISNAM);
369 pub const KEYEXPIRED: Self = Self::from_errno(errno::EKEYEXPIRED);
371 pub const KEYREJECTED: Self = Self::from_errno(errno::EKEYREJECTED);
373 pub const KEYREVOKED: Self = Self::from_errno(errno::EKEYREVOKED);
375 pub const L2HLT: Self = Self::from_errno(errno::EL2HLT);
377 pub const L2NSYNC: Self = Self::from_errno(errno::EL2NSYNC);
379 pub const L3HLT: Self = Self::from_errno(errno::EL3HLT);
381 pub const L3RST: Self = Self::from_errno(errno::EL3RST);
383 pub const LIBACC: Self = Self::from_errno(errno::ELIBACC);
385 pub const LIBBAD: Self = Self::from_errno(errno::ELIBBAD);
387 pub const LIBEXEC: Self = Self::from_errno(errno::ELIBEXEC);
389 pub const LIBMAX: Self = Self::from_errno(errno::ELIBMAX);
391 pub const LIBSCN: Self = Self::from_errno(errno::ELIBSCN);
393 pub const LNRNG: Self = Self::from_errno(errno::ELNRNG);
395 pub const LOOP: Self = Self::from_errno(errno::ELOOP);
397 pub const MEDIUMTYPE: Self = Self::from_errno(errno::EMEDIUMTYPE);
399 pub const MFILE: Self = Self::from_errno(errno::EMFILE);
401 pub const MLINK: Self = Self::from_errno(errno::EMLINK);
403 pub const MSGSIZE: Self = Self::from_errno(errno::EMSGSIZE);
405 pub const MULTIHOP: Self = Self::from_errno(errno::EMULTIHOP);
407 pub const NAMETOOLONG: Self = Self::from_errno(errno::ENAMETOOLONG);
409 pub const NAVAIL: Self = Self::from_errno(errno::ENAVAIL);
411 pub const NETDOWN: Self = Self::from_errno(errno::ENETDOWN);
413 pub const NETRESET: Self = Self::from_errno(errno::ENETRESET);
415 pub const NETUNREACH: Self = Self::from_errno(errno::ENETUNREACH);
417 pub const NFILE: Self = Self::from_errno(errno::ENFILE);
419 pub const NOANO: Self = Self::from_errno(errno::ENOANO);
421 pub const NOBUFS: Self = Self::from_errno(errno::ENOBUFS);
423 pub const NOCSI: Self = Self::from_errno(errno::ENOCSI);
425 #[doc(alias = "NOATTR")]
427 pub const NODATA: Self = Self::from_errno(errno::ENODATA);
428 pub const NODEV: Self = Self::from_errno(errno::ENODEV);
430 pub const NOENT: Self = Self::from_errno(errno::ENOENT);
432 pub const NOEXEC: Self = Self::from_errno(errno::ENOEXEC);
434 pub const NOKEY: Self = Self::from_errno(errno::ENOKEY);
436 pub const NOLCK: Self = Self::from_errno(errno::ENOLCK);
438 pub const NOLINK: Self = Self::from_errno(errno::ENOLINK);
440 pub const NOMEDIUM: Self = Self::from_errno(errno::ENOMEDIUM);
442 pub const NOMEM: Self = Self::from_errno(errno::ENOMEM);
444 pub const NOMSG: Self = Self::from_errno(errno::ENOMSG);
446 pub const NONET: Self = Self::from_errno(errno::ENONET);
448 pub const NOPKG: Self = Self::from_errno(errno::ENOPKG);
450 pub const NOPROTOOPT: Self = Self::from_errno(errno::ENOPROTOOPT);
452 pub const NOSPC: Self = Self::from_errno(errno::ENOSPC);
454 pub const NOSR: Self = Self::from_errno(errno::ENOSR);
456 pub const NOSTR: Self = Self::from_errno(errno::ENOSTR);
458 pub const NOSYS: Self = Self::from_errno(errno::ENOSYS);
460 pub const NOTBLK: Self = Self::from_errno(errno::ENOTBLK);
462 pub const NOTCONN: Self = Self::from_errno(errno::ENOTCONN);
464 pub const NOTDIR: Self = Self::from_errno(errno::ENOTDIR);
466 pub const NOTEMPTY: Self = Self::from_errno(errno::ENOTEMPTY);
468 pub const NOTNAM: Self = Self::from_errno(errno::ENOTNAM);
470 pub const NOTRECOVERABLE: Self = Self::from_errno(errno::ENOTRECOVERABLE);
472 pub const NOTSOCK: Self = Self::from_errno(errno::ENOTSOCK);
474 pub const NOTSUP: Self = Self::from_errno(errno::EOPNOTSUPP);
477 pub const NOTTY: Self = Self::from_errno(errno::ENOTTY);
479 pub const NOTUNIQ: Self = Self::from_errno(errno::ENOTUNIQ);
481 pub const NXIO: Self = Self::from_errno(errno::ENXIO);
483 pub const OPNOTSUPP: Self = Self::from_errno(errno::EOPNOTSUPP);
485 pub const OVERFLOW: Self = Self::from_errno(errno::EOVERFLOW);
487 pub const OWNERDEAD: Self = Self::from_errno(errno::EOWNERDEAD);
489 pub const PERM: Self = Self::from_errno(errno::EPERM);
491 pub const PFNOSUPPORT: Self = Self::from_errno(errno::EPFNOSUPPORT);
493 pub const PIPE: Self = Self::from_errno(errno::EPIPE);
495 pub const PROTO: Self = Self::from_errno(errno::EPROTO);
497 pub const PROTONOSUPPORT: Self = Self::from_errno(errno::EPROTONOSUPPORT);
499 pub const PROTOTYPE: Self = Self::from_errno(errno::EPROTOTYPE);
501 pub const RANGE: Self = Self::from_errno(errno::ERANGE);
503 pub const REMCHG: Self = Self::from_errno(errno::EREMCHG);
505 pub const REMOTE: Self = Self::from_errno(errno::EREMOTE);
507 pub const REMOTEIO: Self = Self::from_errno(errno::EREMOTEIO);
509 pub const RESTART: Self = Self::from_errno(errno::ERESTART);
511 pub const RFKILL: Self = Self::from_errno(errno::ERFKILL);
513 pub const ROFS: Self = Self::from_errno(errno::EROFS);
515 pub const SHUTDOWN: Self = Self::from_errno(errno::ESHUTDOWN);
517 pub const SOCKTNOSUPPORT: Self = Self::from_errno(errno::ESOCKTNOSUPPORT);
519 pub const SPIPE: Self = Self::from_errno(errno::ESPIPE);
521 pub const SRCH: Self = Self::from_errno(errno::ESRCH);
523 pub const SRMNT: Self = Self::from_errno(errno::ESRMNT);
525 pub const STALE: Self = Self::from_errno(errno::ESTALE);
527 pub const STRPIPE: Self = Self::from_errno(errno::ESTRPIPE);
529 pub const TIME: Self = Self::from_errno(errno::ETIME);
531 pub const TIMEDOUT: Self = Self::from_errno(errno::ETIMEDOUT);
533 #[doc(alias = "2BIG")]
535 pub const TOOBIG: Self = Self::from_errno(errno::E2BIG);
536 pub const TOOMANYREFS: Self = Self::from_errno(errno::ETOOMANYREFS);
538 pub const TXTBSY: Self = Self::from_errno(errno::ETXTBSY);
540 pub const UCLEAN: Self = Self::from_errno(errno::EUCLEAN);
542 pub const UNATCH: Self = Self::from_errno(errno::EUNATCH);
544 pub const USERS: Self = Self::from_errno(errno::EUSERS);
546 pub const WOULDBLOCK: Self = Self::from_errno(errno::EWOULDBLOCK);
548 pub const XDEV: Self = Self::from_errno(errno::EXDEV);
550 pub const XFULL: Self = Self::from_errno(errno::EXFULL);
552}