summaryrefslogtreecommitdiffstats
path: root/safe_libc/src/errno.rs
blob: 2a2220b313d70f4fe4bca3bd4a3d0627cc6d6770 (plain)
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
use crate::string;

use core::fmt;

#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct Errno(pub libc::c_int);

extern "C" {
	//#[ffi_const]
	pub fn __errno_location() -> *mut libc::c_int;
}

#[inline]
pub fn errno() -> Errno {
	unsafe { Errno(*__errno_location()) }
}

impl fmt::Display for Errno {
	#[inline]
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		let mut buf = [0u8; 1024];
		let cstr = unsafe {
			if libc::strerror_r(self.0, buf.as_mut_ptr().cast(), buf.len()) != 0 {
				return Err(fmt::Error);
			}
			string::CStr::from_bytes_with_nul_unchecked(&buf)
		};
		match cstr.to_str() {
			Err(_) => Err(fmt::Error),
			Ok(s) => f.write_str(s),
		}
	}
}