summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md9
-rw-r--r--src/errno.rs14
-rw-r--r--src/fcntl.rs4
-rw-r--r--src/features.rs4
-rw-r--r--src/mount/bsd.rs2
-rw-r--r--src/mqueue.rs2
-rw-r--r--src/poll.rs2
-rw-r--r--src/sched.rs2
-rw-r--r--src/sys/aio.rs2
-rw-r--r--src/sys/epoll.rs1
-rw-r--r--src/sys/event.rs1
-rw-r--r--src/sys/mman.rs1
-rw-r--r--src/sys/ptrace/bsd.rs1
-rw-r--r--src/sys/ptrace/linux.rs2
-rw-r--r--src/sys/quota.rs2
-rw-r--r--src/sys/reboot.rs1
-rw-r--r--src/sys/signal.rs4
-rw-r--r--src/sys/socket/addr.rs38
-rw-r--r--src/sys/socket/mod.rs6
-rw-r--r--src/sys/stat.rs31
-rw-r--r--src/sys/termios.rs5
-rw-r--r--src/sys/time.rs8
-rw-r--r--src/sys/timerfd.rs3
-rw-r--r--src/time.rs4
-rw-r--r--src/unistd.rs2
-rw-r--r--test/test_stat.rs42
26 files changed, 150 insertions, 43 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e665b2d7..4a7dcfaf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
(#[1471](https://github.com/nix-rust/nix/pull/1471))
- Added `pthread_kill`.
(#[1472](https://github.com/nix-rust/nix/pull/1472))
+- Added `mknodat`.
+ (#[1473](https://github.com/nix-rust/nix/pull/1473))
### Changed
@@ -30,6 +32,13 @@ This project adheres to [Semantic Versioning](https://semver.org/).
builds.
(#[1481](https://github.com/nix-rust/nix/pull/1481))
+- Most enums that come from C, for example `Errno`, are now marked as
+ `#[non_exhaustive]`.
+ (#[1474](https://github.com/nix-rust/nix/pull/1474))
+
+- Many more functions, mostly contructors, are now `const`.
+ (#[1476](https://github.com/nix-rust/nix/pull/1476))
+
### Fixed
- Added more errno definitions for better backwards compatibility with
diff --git a/src/errno.rs b/src/errno.rs
index 9c2dfe46..07c8944c 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -63,7 +63,7 @@ impl Errno {
since = "0.22.0",
note = "It's a no-op now; just delete it."
)]
- pub fn as_errno(self) -> Option<Self> {
+ pub const fn as_errno(self) -> Option<Self> {
Some(self)
}
@@ -81,7 +81,7 @@ impl Errno {
since = "0.22.0",
note = "Use Errno::EINVAL instead"
)]
- pub fn invalid_argument() -> Error {
+ pub const fn invalid_argument() -> Error {
Errno::EINVAL
}
@@ -122,7 +122,7 @@ impl Errno {
)]
#[allow(non_snake_case)]
#[inline]
- pub fn Sys(errno: Errno) -> Error {
+ pub const fn Sys(errno: Errno) -> Error {
errno
}
}
@@ -768,6 +768,7 @@ fn desc(errno: Errno) -> &'static str {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -1073,6 +1074,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -1324,6 +1326,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -1562,6 +1565,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -1796,6 +1800,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -2019,6 +2024,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -2244,6 +2250,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
@@ -2441,6 +2448,7 @@ mod consts {
mod consts {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(i32)]
+ #[non_exhaustive]
pub enum Errno {
UnknownErrno = 0,
EPERM = libc::EPERM,
diff --git a/src/fcntl.rs b/src/fcntl.rs
index f8f1372a..0a50e748 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -374,6 +374,7 @@ libc_bitflags!(
#[cfg(not(target_os = "redox"))]
#[derive(Debug, Eq, Hash, PartialEq)]
+#[non_exhaustive]
pub enum FcntlArg<'a> {
F_DUPFD(RawFd),
F_DUPFD_CLOEXEC(RawFd),
@@ -405,6 +406,7 @@ pub enum FcntlArg<'a> {
#[cfg(target_os = "redox")]
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
+#[non_exhaustive]
pub enum FcntlArg {
F_DUPFD(RawFd),
F_DUPFD_CLOEXEC(RawFd),
@@ -454,6 +456,7 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+#[non_exhaustive]
pub enum FlockArg {
LockShared,
LockExclusive,
@@ -649,6 +652,7 @@ mod posix_fadvise {
libc_enum! {
#[repr(i32)]
+ #[non_exhaustive]
pub enum PosixFadviseAdvice {
POSIX_FADV_NORMAL,
POSIX_FADV_SEQUENTIAL,
diff --git a/src/features.rs b/src/features.rs
index bcda45d4..38eb3ea0 100644
--- a/src/features.rs
+++ b/src/features.rs
@@ -97,7 +97,7 @@ mod os {
#[cfg(any(target_os = "illumos"))]
mod os {
/// Check if the OS supports atomic close-on-exec for sockets
- pub fn socket_atomic_cloexec() -> bool {
+ pub const fn socket_atomic_cloexec() -> bool {
true
}
}
@@ -109,7 +109,7 @@ mod os {
target_os = "solaris"))]
mod os {
/// Check if the OS supports atomic close-on-exec for sockets
- pub fn socket_atomic_cloexec() -> bool {
+ pub const fn socket_atomic_cloexec() -> bool {
false
}
}
diff --git a/src/mount/bsd.rs b/src/mount/bsd.rs
index 01449081..f0a9443a 100644
--- a/src/mount/bsd.rs
+++ b/src/mount/bsd.rs
@@ -111,7 +111,7 @@ impl NmountError {
}
/// Returns the inner [`Error`]
- pub fn error(&self) -> Error {
+ pub const fn error(&self) -> Error {
self.errno
}
diff --git a/src/mqueue.rs b/src/mqueue.rs
index 3e494801..8598eaf2 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -59,7 +59,7 @@ impl MqAttr {
}
}
- pub fn flags(&self) -> mq_attr_member_t {
+ pub const fn flags(&self) -> mq_attr_member_t {
self.mq_attr.mq_flags
}
}
diff --git a/src/poll.rs b/src/poll.rs
index 0c3f208a..e814337a 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -25,7 +25,7 @@ pub struct PollFd {
impl PollFd {
/// Creates a new `PollFd` specifying the events of interest
/// for a given file descriptor.
- pub fn new(fd: RawFd, events: PollFlags) -> PollFd {
+ pub const fn new(fd: RawFd, events: PollFlags) -> PollFd {
PollFd {
pollfd: libc::pollfd {
fd,
diff --git a/src/sched.rs b/src/sched.rs
index bf51bc12..575bf24b 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -97,7 +97,7 @@ mod sched_linux_like {
}
/// Return the maximum number of CPU in CpuSet
- pub fn count() -> usize {
+ pub const fn count() -> usize {
8 * mem::size_of::<libc::cpu_set_t>()
}
}
diff --git a/src/sys/aio.rs b/src/sys/aio.rs
index b63affb8..71a2184d 100644
--- a/src/sys/aio.rs
+++ b/src/sys/aio.rs
@@ -39,6 +39,7 @@ libc_enum! {
/// Mode for `AioCb::fsync`. Controls whether only data or both data and
/// metadata are synced.
#[repr(i32)]
+ #[non_exhaustive]
pub enum AioFsyncMode {
/// do it like `fsync`
O_SYNC,
@@ -57,6 +58,7 @@ libc_enum! {
/// given `aiocb` should be used for a read operation, a write operation, or
/// ignored. Has no effect for any other aio functions.
#[repr(i32)]
+ #[non_exhaustive]
pub enum LioOpcode {
LIO_NOP,
LIO_WRITE,
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index b73af13e..9f68d5ce 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -29,6 +29,7 @@ libc_bitflags!(
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
+#[non_exhaustive]
pub enum EpollOp {
EpollCtlAdd = libc::EPOLL_CTL_ADD,
EpollCtlDel = libc::EPOLL_CTL_DEL,
diff --git a/src/sys/event.rs b/src/sys/event.rs
index 8050af31..1f4c1b41 100644
--- a/src/sys/event.rs
+++ b/src/sys/event.rs
@@ -36,6 +36,7 @@ type type_of_event_filter = i16;
libc_enum! {
#[cfg_attr(target_os = "netbsd", repr(u32))]
#[cfg_attr(not(target_os = "netbsd"), repr(i16))]
+ #[non_exhaustive]
pub enum EventFilter {
EVFILT_AIO,
/// Returns whenever there is no remaining data in the write buffer
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index 58edf086..a8d6d7c9 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -155,6 +155,7 @@ libc_enum!{
///
/// Used by [`madvise`](./fn.madvise.html).
#[repr(i32)]
+ #[non_exhaustive]
pub enum MmapAdvise {
/// No further special treatment. This is the default.
MADV_NORMAL,
diff --git a/src/sys/ptrace/bsd.rs b/src/sys/ptrace/bsd.rs
index 141dfbc4..a62881ef 100644
--- a/src/sys/ptrace/bsd.rs
+++ b/src/sys/ptrace/bsd.rs
@@ -24,6 +24,7 @@ cfg_if! {
libc_enum! {
#[repr(i32)]
/// Ptrace Request enum defining the action to be taken.
+ #[non_exhaustive]
pub enum Request {
PT_TRACE_ME,
PT_READ_I,
diff --git a/src/sys/ptrace/linux.rs b/src/sys/ptrace/linux.rs
index 4ac43936..74a23e03 100644
--- a/src/sys/ptrace/linux.rs
+++ b/src/sys/ptrace/linux.rs
@@ -33,6 +33,7 @@ libc_enum!{
#[cfg_attr(not(any(target_env = "musl", target_os = "android")), repr(u32))]
#[cfg_attr(any(target_env = "musl", target_os = "android"), repr(i32))]
/// Ptrace Request enum defining the action to be taken.
+ #[non_exhaustive]
pub enum Request {
PTRACE_TRACEME,
PTRACE_PEEKTEXT,
@@ -123,6 +124,7 @@ libc_enum!{
/// Using the ptrace options the tracer can configure the tracee to stop
/// at certain events. This enum is used to define those events as defined
/// in `man ptrace`.
+ #[non_exhaustive]
pub enum Event {
/// Event that stops before a return from fork or clone.
PTRACE_EVENT_FORK,
diff --git a/src/sys/quota.rs b/src/sys/quota.rs
index 19330132..6e34e38d 100644
--- a/src/sys/quota.rs
+++ b/src/sys/quota.rs
@@ -42,6 +42,7 @@ libc_enum!{
libc_enum!{
/// The scope of the quota.
#[repr(i32)]
+ #[non_exhaustive]
pub enum QuotaType {
/// Specify a user quota
USRQUOTA,
@@ -53,6 +54,7 @@ libc_enum!{
libc_enum!{
/// The type of quota format to use.
#[repr(i32)]
+ #[non_exhaustive]
pub enum QuotaFmt {
/// Use the original quota format.
QFMT_VFS_OLD,
diff --git a/src/sys/reboot.rs b/src/sys/reboot.rs
index 5b376824..be5067a9 100644
--- a/src/sys/reboot.rs
+++ b/src/sys/reboot.rs
@@ -12,6 +12,7 @@ libc_enum! {
/// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
/// enabling/disabling Ctrl-Alt-Delete.
#[repr(i32)]
+ #[non_exhaustive]
pub enum RebootMode {
RB_HALT_SYSTEM,
RB_KEXEC,
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index 273b3521..0911cfaa 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -23,6 +23,7 @@ libc_enum!{
// We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
// this is not (yet) possible.
#[repr(i32)]
+ #[non_exhaustive]
pub enum Signal {
SIGHUP,
SIGINT,
@@ -356,7 +357,7 @@ impl Iterator for SignalIterator {
}
impl Signal {
- pub fn iterator() -> SignalIterator {
+ pub const fn iterator() -> SignalIterator {
SignalIterator{next: 0}
}
}
@@ -396,6 +397,7 @@ libc_bitflags!{
libc_enum! {
#[repr(i32)]
+ #[non_exhaustive]
pub enum SigmaskHow {
SIG_BLOCK,
SIG_UNBLOCK,
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index d4860562..366c9afd 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -32,6 +32,7 @@ pub use self::vsock::VsockAddr;
/// These constants specify the protocol family to be used
/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
#[repr(i32)]
+#[non_exhaustive]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum AddressFamily {
/// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html))
@@ -372,7 +373,7 @@ impl IpAddr {
/// Create a new IpAddr that contains an IPv4 address.
///
/// The result will represent the IP address a.b.c.d
- pub fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
+ pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
IpAddr::V4(Ipv4Addr::new(a, b, c, d))
}
@@ -381,7 +382,7 @@ impl IpAddr {
/// The result will represent the IP address a:b:c:d:e:f
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
- pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
+ pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
}
@@ -420,11 +421,11 @@ pub struct Ipv4Addr(pub libc::in_addr);
impl Ipv4Addr {
#[allow(clippy::identity_op)] // More readable this way
- pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
- let ip = ((u32::from(a) << 24) |
- (u32::from(b) << 16) |
- (u32::from(c) << 8) |
- (u32::from(d) << 0)).to_be();
+ pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
+ let ip = (((a as u32) << 24) |
+ ((b as u32) << 16) |
+ ((c as u32) << 8) |
+ ((d as u32) << 0)).to_be();
Ipv4Addr(libc::in_addr { s_addr: ip })
}
@@ -436,16 +437,16 @@ impl Ipv4Addr {
Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
}
- pub fn any() -> Ipv4Addr {
+ pub const fn any() -> Ipv4Addr {
Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
}
- pub fn octets(self) -> [u8; 4] {
+ pub const fn octets(self) -> [u8; 4] {
let bits = u32::from_be(self.0.s_addr);
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
}
- pub fn to_std(self) -> net::Ipv4Addr {
+ pub const fn to_std(self) -> net::Ipv4Addr {
let bits = self.octets();
net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
}
@@ -486,7 +487,7 @@ macro_rules! to_u16_array {
impl Ipv6Addr {
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
- pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
+ pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)})
}
@@ -496,11 +497,11 @@ impl Ipv6Addr {
}
/// Return the eight 16-bit segments that make up this address
- pub fn segments(&self) -> [u16; 8] {
+ pub const fn segments(&self) -> [u16; 8] {
to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
}
- pub fn to_std(&self) -> net::Ipv6Addr {
+ pub const fn to_std(&self) -> net::Ipv6Addr {
let s = self.segments();
net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
}
@@ -641,6 +642,7 @@ impl Hash for UnixAddr {
/// Represents a socket address
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+#[non_exhaustive]
pub enum SockAddr {
Inet(InetAddr),
Unix(UnixAddr),
@@ -913,11 +915,11 @@ pub mod netlink {
NetlinkAddr(addr)
}
- pub fn pid(&self) -> u32 {
+ pub const fn pid(&self) -> u32 {
self.0.nl_pid
}
- pub fn groups(&self) -> u32 {
+ pub const fn groups(&self) -> u32 {
self.0.nl_groups
}
}
@@ -1020,7 +1022,7 @@ pub mod sys_control {
pub struct SysControlAddr(pub libc::sockaddr_ctl);
impl SysControlAddr {
- pub fn new(id: u32, unit: u32) -> SysControlAddr {
+ pub const fn new(id: u32, unit: u32) -> SysControlAddr {
let addr = libc::sockaddr_ctl {
sc_len: mem::size_of::<libc::sockaddr_ctl>() as c_uchar,
sc_family: AddressFamily::System as c_uchar,
@@ -1047,11 +1049,11 @@ pub mod sys_control {
Ok(SysControlAddr::new(info.ctl_id, unit))
}
- pub fn id(&self) -> u32 {
+ pub const fn id(&self) -> u32 {
self.0.sc_id
}
- pub fn unit(&self) -> u32 {
+ pub const fn unit(&self) -> u32 {
self.0.sc_unit
}
}
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index da5573c4..0f54ef0c 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -70,6 +70,7 @@ pub use libc::{c_uint, CMSG_SPACE};
/// when creating a socket with [`socket()`](fn.socket.html)
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(i32)]
+#[non_exhaustive]
pub enum SockType {
/// Provides sequenced, reliable, two-way, connection-
/// based byte streams. An out-of-band data transmission
@@ -94,6 +95,7 @@ pub enum SockType {
/// to specify the protocol to use.
#[repr(i32)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+#[non_exhaustive]
pub enum SockProtocol {
/// TCP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html))
Tcp = libc::IPPROTO_TCP,
@@ -384,7 +386,7 @@ pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
impl Ipv6MembershipRequest {
/// Instantiate a new `Ipv6MembershipRequest`
- pub fn new(group: Ipv6Addr) -> Self {
+ pub const fn new(group: Ipv6Addr) -> Self {
Ipv6MembershipRequest(libc::ipv6_mreq {
ipv6mr_multiaddr: group.0,
ipv6mr_interface: 0,
@@ -490,6 +492,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
//
// See https://github.com/nix-rust/nix/issues/999
#[derive(Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
pub enum ControlMessageOwned {
/// Received version of
/// [`ControlMessage::ScmRights`][#enum.ControlMessage.html#variant.ScmRights]
@@ -739,6 +742,7 @@ impl ControlMessageOwned {
///
/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html)
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[non_exhaustive]
pub enum ControlMessage<'a> {
/// A message of type `SCM_RIGHTS`, containing an array of file
/// descriptors passed between processes.
diff --git a/src/sys/stat.rs b/src/sys/stat.rs
index 15451e78..ed62b12d 100644
--- a/src/sys/stat.rs
+++ b/src/sys/stat.rs
@@ -9,6 +9,7 @@ use std::os::unix::io::RawFd;
use crate::sys::time::{TimeSpec, TimeVal};
libc_bitflags!(
+ /// "File type" flags for `mknod` and related functions.
pub struct SFlag: mode_t {
S_IFIFO;
S_IFCHR;
@@ -22,6 +23,7 @@ libc_bitflags!(
);
libc_bitflags! {
+ /// "File mode / permissions" flags.
pub struct Mode: mode_t {
S_IRWXU;
S_IRUSR;
@@ -41,30 +43,45 @@ libc_bitflags! {
}
}
+/// Create a special or ordinary file, by pathname.
pub fn mknod<P: ?Sized + NixPath>(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
- }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
+ })?;
+
+ Errno::result(res).map(drop)
+}
+
+/// Create a special or ordinary file, relative to a given directory.
+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))]
+pub fn mknodat<P: ?Sized + NixPath>(
+ dirfd: RawFd,
+ path: &P,
+ kind: SFlag,
+ perm: Mode,
+ dev: dev_t,
+) -> Result<()> {
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mknodat(dirfd, cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
})?;
Errno::result(res).map(drop)
}
#[cfg(target_os = "linux")]
-pub fn major(dev: dev_t) -> u64 {
+pub const fn major(dev: dev_t) -> u64 {
((dev >> 32) & 0xffff_f000) |
((dev >> 8) & 0x0000_0fff)
}
#[cfg(target_os = "linux")]
-pub fn minor(dev: dev_t) -> u64 {
+pub const fn minor(dev: dev_t) -> u64 {
((dev >> 12) & 0xffff_ff00) |
((dev ) & 0x0000_00ff)
}
#[cfg(target_os = "linux")]
-pub fn makedev(major: u64, minor: u64) -> dev_t {
+pub const fn makedev(major: u64, minor: u64) -> dev_t {
((major & 0xffff_f000) << 32) |
((major & 0x0000_0fff) << 8) |
((minor & 0xffff_ff00) << 12) |
diff --git a/src/sys/termios.rs b/src/sys/termios.rs
index 9abae9d0..b29d3b98 100644
--- a/src/sys/termios.rs
+++ b/src/sys/termios.rs
@@ -256,6 +256,7 @@ libc_enum!{
/// B0 is special and will disable the port.
#[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))]
#[cfg_attr(not(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64")), repr(u32))]
+ #[non_exhaustive]
pub enum BaudRate {
B0,
B50,
@@ -472,6 +473,7 @@ libc_enum! {
///
/// Used as an argument to `tcsetattr()`
#[repr(i32)]
+ #[non_exhaustive]
pub enum SetArg {
/// The change will occur immediately
TCSANOW,
@@ -487,6 +489,7 @@ libc_enum! {
///
/// Used as an argument to `tcflush()`.
#[repr(i32)]
+ #[non_exhaustive]
pub enum FlushArg {
/// Flush data that was received but not read
TCIFLUSH,
@@ -502,6 +505,7 @@ libc_enum! {
///
/// Used as an argument to `tcflow()`.
#[repr(i32)]
+ #[non_exhaustive]
pub enum FlowArg {
/// Suspend transmission
TCOOFF,
@@ -518,6 +522,7 @@ libc_enum! {
libc_enum! {
/// Indices into the `termios.c_cc` array for special characters.
#[repr(usize)]
+ #[non_exhaustive]
pub enum SpecialCharacterIndices {
VDISCARD,
#[cfg(any(target_os = "dragonfly",
diff --git a/src/sys/time.rs b/src/sys/time.rs
index c786500a..ac424718 100644
--- a/src/sys/time.rs
+++ b/src/sys/time.rs
@@ -187,11 +187,11 @@ impl TimeSpec {
}
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub fn tv_sec(&self) -> time_t {
+ pub const fn tv_sec(&self) -> time_t {
self.0.tv_sec
}
- pub fn tv_nsec(&self) -> timespec_tv_nsec_t {
+ pub const fn tv_nsec(&self) -> timespec_tv_nsec_t {
self.0.tv_nsec
}
@@ -404,11 +404,11 @@ impl TimeVal {
}
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub fn tv_sec(&self) -> time_t {
+ pub const fn tv_sec(&self) -> time_t {
self.0.tv_sec
}
- pub fn tv_usec(&self) -> suseconds_t {
+ pub const fn tv_usec(&self) -> suseconds_t {
self.0.tv_usec
}
}
diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs
index 44915be1..5d87b7c2 100644
--- a/src/sys/timerfd.rs
+++ b/src/sys/timerfd.rs
@@ -58,6 +58,7 @@ libc_enum! {
/// The type of the clock used to mark the progress of the timer. For more
/// details on each kind of clock, please refer to [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html).
#[repr(i32)]
+ #[non_exhaustive]
pub enum ClockId {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
@@ -87,7 +88,7 @@ bitflags! {
struct TimerSpec(libc::itimerspec);
impl TimerSpec {
- pub fn none() -> Self {
+ pub const fn none() -> Self {
Self(libc::itimerspec {
it_interval: libc::timespec {
tv_sec: 0,
diff --git a/src/time.rs b/src/time.rs
index 45dd26e7..1731e60e 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -20,7 +20,7 @@ pub struct ClockId(clockid_t);
impl ClockId {
/// Creates `ClockId` from raw `clockid_t`
- pub fn from_raw(clk_id: clockid_t) -> Self {
+ pub const fn from_raw(clk_id: clockid_t) -> Self {
ClockId(clk_id)
}
@@ -61,7 +61,7 @@ impl ClockId {
}
/// Gets the raw `clockid_t` wrapped by `self`
- pub fn as_raw(self) -> clockid_t {
+ pub const fn as_raw(self) -> clockid_t {
self.0
}
diff --git a/src/unistd.rs b/src/unistd.rs
index 1cba0303..e42f83a5 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -1806,6 +1806,7 @@ pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
+#[non_exhaustive]
pub enum PathconfVar {
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
@@ -1985,6 +1986,7 @@ pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Optio
/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(i32)]
+#[non_exhaustive]
pub enum SysconfVar {
/// Maximum number of I/O operations in a single list I/O call supported by
/// the implementation.
diff --git a/test/test_stat.rs b/test/test_stat.rs
index 424371fa..42c536a8 100644
--- a/test/test_stat.rs
+++ b/test/test_stat.rs
@@ -306,3 +306,45 @@ fn test_mkdirat_fail() {
let result = mkdirat(dirfd, filename, Mode::S_IRWXU).unwrap_err();
assert_eq!(result, Errno::ENOTDIR);
}
+
+#[test]
+#[cfg(not(any(target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox")))]
+fn test_mknod_family() {
+ use fcntl::{AtFlags, OFlag};
+ use nix::dir::Dir;
+ use stat::{fstatat, lstat, mknod, mknodat, SFlag};
+
+ let file_name = "test_file";
+ {
+ let tempdir = tempfile::tempdir().unwrap();
+ let target = tempdir.path().join(file_name);
+ mknod(&target, SFlag::S_IFREG, Mode::S_IRWXU, 0).unwrap();
+ let mode = lstat(&target).unwrap().st_mode as mode_t;
+ assert!(mode & libc::S_IFREG == libc::S_IFREG);
+ assert!(mode & libc::S_IRWXU == libc::S_IRWXU);
+ }
+ {
+ let tempdir = tempfile::tempdir().unwrap();
+ let target_dir = Dir::open(tempdir.path(), OFlag::O_DIRECTORY, Mode::S_IRWXU).unwrap();
+ mknodat(
+ target_dir.as_raw_fd(),
+ file_name,
+ SFlag::S_IFREG,
+ Mode::S_IRWXU,
+ 0,
+ )
+ .unwrap();
+ let mode = fstatat(
+ target_dir.as_raw_fd(),
+ file_name,
+ AtFlags::AT_SYMLINK_NOFOLLOW,
+ )
+ .unwrap()
+ .st_mode as mode_t;
+ assert!(mode & libc::S_IFREG == libc::S_IFREG);
+ assert!(mode & libc::S_IRWXU == libc::S_IRWXU);
+ }
+}