diff options
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/mod.rs | 2 | ||||
-rw-r--r-- | src/sys/pthread.rs | 22 | ||||
-rw-r--r-- | src/sys/signal.rs | 2 | ||||
-rw-r--r-- | src/sys/socket/addr.rs | 36 | ||||
-rw-r--r-- | src/sys/socket/mod.rs | 2 | ||||
-rw-r--r-- | src/sys/stat.rs | 31 | ||||
-rw-r--r-- | src/sys/time.rs | 26 | ||||
-rw-r--r-- | src/sys/timerfd.rs | 2 |
8 files changed, 85 insertions, 38 deletions
diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 43877a12..b43587b8 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -17,7 +17,7 @@ pub mod epoll; target_os = "openbsd"))] pub mod event; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "android", target_os = "linux"))] pub mod eventfd; #[cfg(any(target_os = "android", diff --git a/src/sys/pthread.rs b/src/sys/pthread.rs index f7304087..9163c8d1 100644 --- a/src/sys/pthread.rs +++ b/src/sys/pthread.rs @@ -1,3 +1,9 @@ +#[cfg(not(target_os = "redox"))] +use crate::errno::Errno; +#[cfg(not(target_os = "redox"))] +use crate::Result; +#[cfg(not(target_os = "redox"))] +use crate::sys::signal::Signal; use libc::{self, pthread_t}; pub type Pthread = pthread_t; @@ -11,3 +17,19 @@ pub type Pthread = pthread_t; pub fn pthread_self() -> Pthread { unsafe { libc::pthread_self() } } + +/// Send a signal to a thread (see [`pthread_kill(3)`]). +/// +/// If `signal` is `None`, `pthread_kill` will only preform error checking and +/// won't send any signal. +/// +/// [`pthread_kill(3)`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html +#[cfg(not(target_os = "redox"))] +pub fn pthread_kill<T: Into<Option<Signal>>>(thread: Pthread, signal: T) -> Result<()> { + let sig = match signal.into() { + Some(s) => s as libc::c_int, + None => 0, + }; + let res = unsafe { libc::pthread_kill(thread, sig) }; + Errno::result(res).map(drop) +} diff --git a/src/sys/signal.rs b/src/sys/signal.rs index b1d938c3..0911cfaa 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -357,7 +357,7 @@ impl Iterator for SignalIterator { } impl Signal { - pub fn iterator() -> SignalIterator { + pub const fn iterator() -> SignalIterator { SignalIterator{next: 0} } } diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index bd031cf6..366c9afd 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -373,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)) } @@ -382,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)) } @@ -421,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 }) } @@ -437,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]) } @@ -487,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)}) } @@ -497,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]) } @@ -915,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 } } @@ -1022,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, @@ -1049,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 32904d01..0f54ef0c 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -386,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, 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/time.rs b/src/sys/time.rs index 7546d1b3..ac424718 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -77,11 +77,7 @@ impl From<timespec> for TimeSpec { impl From<Duration> for TimeSpec { fn from(duration: Duration) -> Self { - #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 - TimeSpec(timespec { - tv_sec: duration.as_secs() as time_t, - tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t - }) + Self::from_duration(duration) } } @@ -191,13 +187,25 @@ 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 } + + pub const fn from_duration(duration: Duration) -> Self { + #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 + TimeSpec(timespec { + tv_sec: duration.as_secs() as time_t, + tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t + }) + } + + pub const fn from_timespec(timespec: timespec) -> Self { + Self(timespec) + } } impl ops::Neg for TimeSpec { @@ -396,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 030e5976..5d87b7c2 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -88,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, |