Skip to content

Commit

Permalink
Introduce set_errno (#2283)
Browse files Browse the repository at this point in the history
* Introduce set_errno

* set_errno test

* Add a changelog

* Add some docs to errno module

* Errno API Cleanup

* Stop using deprecated function of errno

* Update docs to not use deprecated functions

* Add since to deprecated attributes

* Update changelog

* Fix after rebase

* Use Errno::set_raw in Errno::clear implementation

* Use self in Errno::set

* Use errno.set() syntax in docs

* errno_set_and_clear test

* Remove Errno::clear from errno_set_and_read
  • Loading branch information
PolyMeilex committed Jan 8, 2024
1 parent 24b70dc commit c505277
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 29 deletions.
4 changes: 4 additions & 0 deletions changelog/2283.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- Added `errno::Errno::set` function
- Added `errno::Errno::set_raw` function
- Added `errno::Errno::last_raw` function
- Added `errno::Errno::from_raw` function
3 changes: 3 additions & 0 deletions changelog/2283.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Deprecated `errno::errno()` function (use `Errno::last_raw()`)
- Deprecated `errno::from_i32()` function (use `Errno::from_raw()`)
- Deprecated `errno::Errno::from_i32()` function (use `Errno::from_raw()`)
132 changes: 114 additions & 18 deletions src/errno.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
//! Safe wrappers around errno functions
//!
//! # Example
//! ```
//! use nix::errno::Errno;
//!
//! Errno::EIO.set();
//! assert_eq!(Errno::last(), Errno::EIO);
//!
//! Errno::clear();
//! assert_eq!(Errno::last(), Errno::from_raw(0));
//! ```

use crate::Result;
use cfg_if::cfg_if;
use libc::{c_int, c_void};
Expand Down Expand Up @@ -39,34 +52,77 @@ cfg_if! {
}
}

/// Sets the platform-specific errno to no-error
fn clear() {
// Safe because errno is a thread-local variable
unsafe {
*errno_location() = 0;
}
}

/// Returns the platform-specific value of errno
#[deprecated(since = "0.28.0", note = "please use `Errno::last_raw()` instead")]
pub fn errno() -> i32 {
unsafe { *errno_location() }
Errno::last_raw()
}

impl Errno {
/// Returns the current value of errno
pub fn last() -> Self {
last()
Self::from_raw(Self::last_raw())
}

pub fn desc(self) -> &'static str {
desc(self)
/// Returns the current raw i32 value of errno
pub fn last_raw() -> i32 {
unsafe { *errno_location() }
}

/// Sets the value of errno.
///
/// # Example
/// ```
/// use nix::errno::Errno;
///
/// Errno::EIO.set();
///
/// assert_eq!(Errno::last(), Errno::EIO);
/// ```
pub fn set(self) {
Self::set_raw(self as i32)
}

/// Sets the raw i32 value of errno.
pub fn set_raw(errno: i32) {
// Safe because errno is a thread-local variable
unsafe {
*errno_location() = errno;
}
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(err: i32) -> Errno {
Self::from_raw(err)
}

pub const fn from_raw(err: i32) -> Errno {
#[allow(deprecated)]
from_i32(err)
}

pub fn desc(self) -> &'static str {
desc(self)
}

/// Sets the platform-specific errno to no-error
///
/// ```
/// use nix::errno::Errno;
///
/// Errno::EIO.set();
///
/// Errno::clear();
///
/// let err = Errno::last();
/// assert_ne!(err, Errno::EIO);
/// assert_eq!(err, Errno::from_raw(0));
/// ```
pub fn clear() {
clear()
Self::set_raw(0)
}

/// Returns `Ok(value)` if it does not contain the sentinel value. This
Expand Down Expand Up @@ -135,14 +191,10 @@ impl TryFrom<io::Error> for Errno {
type Error = io::Error;

fn try_from(ioerror: io::Error) -> std::result::Result<Self, io::Error> {
ioerror.raw_os_error().map(Errno::from_i32).ok_or(ioerror)
ioerror.raw_os_error().map(Errno::from_raw).ok_or(ioerror)
}
}

fn last() -> Errno {
Errno::from_i32(errno())
}

fn desc(errno: Errno) -> &'static str {
use self::Errno::*;
match errno {
Expand Down Expand Up @@ -929,6 +981,10 @@ mod consts {
pub const ENOTSUP: Errno = Errno::EOPNOTSUPP;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -1192,6 +1248,10 @@ mod consts {
pub const EDEADLOCK: Errno = Errno::EDEADLK;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -1419,6 +1479,10 @@ mod consts {
pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -1636,6 +1700,10 @@ mod consts {
pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -1848,6 +1916,10 @@ mod consts {
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -2062,6 +2134,10 @@ mod consts {
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -2265,6 +2341,10 @@ mod consts {
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -2494,6 +2574,10 @@ mod consts {
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -2714,6 +2798,10 @@ mod consts {
pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -2905,6 +2993,10 @@ mod consts {
EOPNOTSUPP = libc::EOPNOTSUPP,
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down Expand Up @@ -3128,6 +3220,10 @@ mod consts {
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
}

#[deprecated(
since = "0.28.0",
note = "please use `Errno::from_raw()` instead"
)]
pub const fn from_i32(e: i32) -> Errno {
use self::Errno::*;

Expand Down
4 changes: 2 additions & 2 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ mod posix_fadvise {
if res == 0 {
Ok(())
} else {
Err(Errno::from_i32(res))
Err(Errno::from_raw(res))
}
}
}
Expand All @@ -1131,7 +1131,7 @@ pub fn posix_fallocate(
match Errno::result(res) {
Err(err) => Err(err),
Ok(0) => Ok(()),
Ok(errno) => Err(Errno::from_i32(errno)),
Ok(errno) => Err(Errno::from_raw(errno)),
}
}
}
2 changes: 1 addition & 1 deletion src/sys/aio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl AioCb {
let r = unsafe { libc::aio_error(&self.aiocb().0) };
match r {
0 => Ok(()),
num if num > 0 => Err(Errno::from_i32(num)),
num if num > 0 => Err(Errno::from_raw(num)),
-1 => Err(Errno::last()),
num => panic!("unknown aio_error return value {num:?}"),
}
Expand Down
4 changes: 2 additions & 2 deletions src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
let res = unsafe { clk_id.assume_init() };
Ok(ClockId::from(res))
} else {
Err(Errno::from_i32(ret))
Err(Errno::from_raw(ret))
}
}

Expand Down Expand Up @@ -248,6 +248,6 @@ pub fn clock_nanosleep(
if ret == 0 {
Ok(remain)
} else {
Err(Errno::from_i32(ret))
Err(Errno::from_raw(ret))
}
}
10 changes: 5 additions & 5 deletions src/unistd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Safe wrappers around functions found in libc "unistd.h" header

use crate::errno::{self, Errno};
use crate::errno::Errno;

#[cfg(any(
all(feature = "fs", not(target_os = "redox")),
Expand Down Expand Up @@ -2148,7 +2148,7 @@ pub fn fpathconf<F: AsFd>(fd: F, var: PathconfVar) -> Result<Option<c_long>> {
libc::fpathconf(fd.as_fd().as_raw_fd(), var as c_int)
};
if raw == -1 {
if errno::errno() == 0 {
if Errno::last_raw() == 0 {
Ok(None)
} else {
Err(Errno::last())
Expand Down Expand Up @@ -2188,7 +2188,7 @@ pub fn pathconf<P: ?Sized + NixPath>(
libc::pathconf(cstr.as_ptr(), var as c_int)
})?;
if raw == -1 {
if errno::errno() == 0 {
if Errno::last_raw() == 0 {
Ok(None)
} else {
Err(Errno::last())
Expand Down Expand Up @@ -2787,7 +2787,7 @@ pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
libc::sysconf(var as c_int)
};
if raw == -1 {
if errno::errno() == 0 {
if Errno::last_raw() == 0 {
Ok(None)
} else {
Err(Errno::last())
Expand Down Expand Up @@ -3543,7 +3543,7 @@ pub fn ttyname<F: AsFd>(fd: F) -> Result<PathBuf> {

let ret = unsafe { libc::ttyname_r(fd.as_fd().as_raw_fd(), c_buf, buf.len()) };
if ret != 0 {
return Err(Errno::from_i32(ret));
return Err(Errno::from_raw(ret));
}

CStr::from_bytes_until_nul(&buf[..])
Expand Down
1 change: 1 addition & 0 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod common;
mod sys;
#[cfg(not(target_os = "redox"))]
mod test_dir;
mod test_errno;
mod test_fcntl;
#[cfg(linux_android)]
mod test_kmod;
Expand Down
16 changes: 16 additions & 0 deletions test/test_errno.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use nix::errno::Errno;

#[test]
fn errno_set_and_read() {
Errno::ENFILE.set();
assert_eq!(Errno::last(), Errno::ENFILE);
}

#[test]
fn errno_set_and_clear() {
Errno::ENFILE.set();
assert_eq!(Errno::last(), Errno::ENFILE);

Errno::clear();
assert_eq!(Errno::last(), Errno::from_raw(0));
}
2 changes: 1 addition & 1 deletion test/test_mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ exit 23";
.mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
.open(&test_path)
.or_else(|e| {
if Errno::from_i32(e.raw_os_error().unwrap())
if Errno::from_raw(e.raw_os_error().unwrap())
== Errno::EOVERFLOW
{
// Skip tests on certain Linux kernels which have a bug
Expand Down

0 comments on commit c505277

Please sign in to comment.