summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--src/fcntl.rs1
-rw-r--r--src/mqueue.rs15
-rw-r--r--src/poll.rs4
-rw-r--r--src/pty.rs4
-rw-r--r--src/sys/resource.rs36
-rw-r--r--src/sys/signal.rs2
-rw-r--r--src/sys/socket/mod.rs73
-rw-r--r--src/sys/socket/sockopt.rs16
-rw-r--r--src/sys/statfs.rs4
-rw-r--r--src/time.rs2
-rw-r--r--src/unistd.rs6
-rw-r--r--test/sys/test_ptrace.rs2
-rw-r--r--test/sys/test_socket.rs115
-rw-r--r--test/sys/test_sockopt.rs2
-rw-r--r--test/test_fcntl.rs1
-rw-r--r--test/test_mount.rs2
-rw-r--r--test/test_stat.rs6
18 files changed, 270 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4311668..4c4516ae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,14 @@ This project adheres to [Semantic Versioning](https://semver.org/).
(#[1581](https://github.com/nix-rust/nix/pull/1581))
- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly.
(#[1537](https://github.com/nix-rust/nix/pull/1537))
+- Added `posix_fallocate` on DragonFly.
+ (#[1621](https://github.com/nix-rust/nix/pull/1621))
+- Added the `SO_TIMESTAMPING` support
+ (#[1547](https://github.com/nix-rust/nix/pull/1547))
+- Added getter methods to `MqAttr` struct
+ (#[1619](https://github.com/nix-rust/nix/pull/1619))
+- Added the `TxTime` sockopt and control message.
+ (#[1564](https://github.com/nix-rust/nix/pull/1564))
### Changed
### Fixed
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 74d9eb9c..c02a81a9 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -749,6 +749,7 @@ mod posix_fadvise {
#[cfg(any(
target_os = "linux",
target_os = "android",
+ target_os = "dragonfly",
target_os = "emscripten",
target_os = "fuchsia",
any(target_os = "wasi", target_env = "wasi"),
diff --git a/src/mqueue.rs b/src/mqueue.rs
index 564df4e4..20740b54 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -64,6 +64,21 @@ impl MqAttr {
pub const fn flags(&self) -> mq_attr_member_t {
self.mq_attr.mq_flags
}
+
+ /// The max number of messages that can be held by the queue
+ pub const fn maxmsg(&self) -> mq_attr_member_t {
+ self.mq_attr.mq_maxmsg
+ }
+
+ /// The maximum size of each message (in bytes)
+ pub const fn msgsize(&self) -> mq_attr_member_t {
+ self.mq_attr.mq_msgsize
+ }
+
+ /// The number of messages currently held in the queue
+ pub const fn curmsgs(&self) -> mq_attr_member_t {
+ self.mq_attr.mq_curmsgs
+ }
}
diff --git a/src/poll.rs b/src/poll.rs
index 5b181526..6d332b03 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -10,7 +10,7 @@ use crate::errno::Errno;
/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
/// for a specific file descriptor.
///
-/// After a call to `poll` or `ppoll`, the events that occured can be
+/// After a call to `poll` or `ppoll`, the events that occurred can be
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
@@ -31,7 +31,7 @@ impl PollFd {
}
}
- /// Returns the events that occured in the last call to `poll` or `ppoll`. Will only return
+ /// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return
/// `None` if the kernel provides status flags that Nix does not know about.
pub fn revents(self) -> Option<PollFlags> {
PollFlags::from_bits(self.pollfd.revents)
diff --git a/src/pty.rs b/src/pty.rs
index a104a69c..ae304d83 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -112,7 +112,7 @@ pub fn grantpt(fd: &PtyMaster) -> Result<()> {
/// Open a pseudoterminal device (see
/// [`posix_openpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
///
-/// `posix_openpt()` returns a file descriptor to an existing unused pseuterminal master device.
+/// `posix_openpt()` returns a file descriptor to an existing unused pseudoterminal master device.
///
/// # Examples
///
@@ -214,7 +214,7 @@ pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
///
/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
/// referred to by `fd`. This must be called before trying to open the slave side of a
-/// pseuoterminal.
+/// pseudoterminal.
#[inline]
pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 {
diff --git a/src/sys/resource.rs b/src/sys/resource.rs
index 80473e58..7f2927b4 100644
--- a/src/sys/resource.rs
+++ b/src/sys/resource.rs
@@ -24,12 +24,15 @@ cfg_if! {
}
libc_enum! {
+ /// Types of process resources.
+ ///
/// The Resource enum is platform dependent. Check different platform
- /// manuals for more details. Some platform links has been provided for
- /// earier reference (non-exhaustive).
+ /// manuals for more details. Some platform links have been provided for
+ /// easier reference (non-exhaustive).
///
/// * [Linux](https://man7.org/linux/man-pages/man2/getrlimit.2.html)
/// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=setrlimit)
+ /// * [NetBSD](https://man.netbsd.org/setrlimit.2)
// linux-gnu uses u_int as resource enum, which is implemented in libc as
// well.
@@ -49,11 +52,7 @@ libc_enum! {
), repr(i32))]
#[non_exhaustive]
pub enum Resource {
- #[cfg(not(any(
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"
- )))]
+ #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum amount (in bytes) of virtual memory the process is
/// allowed to map.
@@ -83,7 +82,13 @@ libc_enum! {
/// this process may establish.
RLIMIT_LOCKS,
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "openbsd", target_os = "linux"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "linux",
+ target_os = "netbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum size (in bytes) which a process may lock into memory
/// using the mlock(2) system call.
@@ -101,7 +106,13 @@ libc_enum! {
/// setpriority or nice.
RLIMIT_NICE,
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "openbsd", target_os = "linux"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "linux",
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum number of simultaneous processes for this user id.
RLIMIT_NPROC,
@@ -112,7 +123,12 @@ libc_enum! {
/// create.
RLIMIT_NPTS,
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "openbsd", target_os = "linux"))]
+ #[cfg(any(target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "linux",
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// When there is memory pressure and swap is available, prioritize
/// eviction of a process' resident pages beyond this amount (in bytes).
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index f85bf266..b655604d 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -866,7 +866,7 @@ pub fn pthread_sigmask(how: SigmaskHow,
/// Examine and change blocked signals.
///
-/// For more informations see the [`sigprocmask` man
+/// For more information see the [`sigprocmask` man
/// pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html).
pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> {
if set.is_none() && oldset.is_none() {
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 2ed38272..42a032c9 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -198,6 +198,28 @@ pub enum SockProtocol {
NetlinkCrypto = libc::NETLINK_CRYPTO,
}
+#[cfg(any(target_os = "linux"))]
+libc_bitflags! {
+ /// Configuration flags for `SO_TIMESTAMPING` interface
+ ///
+ /// For use with [`Timestamping`][sockopt::Timestamping].
+ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
+ pub struct TimestampingFlag: c_uint {
+ /// Report any software timestamps when available.
+ SOF_TIMESTAMPING_SOFTWARE;
+ /// Report hardware timestamps as generated by SOF_TIMESTAMPING_TX_HARDWARE when available.
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ /// Collect transmiting timestamps as reported by hardware
+ SOF_TIMESTAMPING_TX_HARDWARE;
+ /// Collect transmiting timestamps as reported by software
+ SOF_TIMESTAMPING_TX_SOFTWARE;
+ /// Collect receiving timestamps as reported by hardware
+ SOF_TIMESTAMPING_RX_HARDWARE;
+ /// Collect receiving timestamps as reported by software
+ SOF_TIMESTAMPING_RX_SOFTWARE;
+ }
+}
+
libc_bitflags!{
/// Additional socket options
pub struct SockFlag: c_int {
@@ -641,6 +663,11 @@ pub enum ControlMessageOwned {
/// # }
/// ```
ScmTimestamp(TimeVal),
+ /// A set of nanosecond resolution timestamps
+ ///
+ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
+ #[cfg(all(target_os = "linux"))]
+ ScmTimestampsns(Timestamps),
/// Nanoseconds resolution timestamp
///
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
@@ -732,6 +759,18 @@ pub enum ControlMessageOwned {
Unknown(UnknownCmsg),
}
+/// For representing packet timestamps via `SO_TIMESTAMPING` interface
+#[cfg(all(target_os = "linux"))]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Timestamps {
+ /// software based timestamp, usually one containing data
+ pub system: TimeSpec,
+ /// legacy timestamp, usually empty
+ pub hw_trans: TimeSpec,
+ /// hardware based timestamp
+ pub hw_raw: TimeSpec,
+}
+
impl ControlMessageOwned {
/// Decodes a `ControlMessageOwned` from raw bytes.
///
@@ -776,6 +815,18 @@ impl ControlMessageOwned {
let ts: libc::timespec = ptr::read_unaligned(p as *const _);
ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts))
}
+ #[cfg(all(target_os = "linux"))]
+ (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => {
+ let tp = p as *const libc::timespec;
+ let ts: libc::timespec = ptr::read_unaligned(tp);
+ let system = TimeSpec::from(ts);
+ let ts: libc::timespec = ptr::read_unaligned(tp.add(1));
+ let hw_trans = TimeSpec::from(ts);
+ let ts: libc::timespec = ptr::read_unaligned(tp.add(2));
+ let hw_raw = TimeSpec::from(ts);
+ let timestamping = Timestamps { system, hw_trans, hw_raw };
+ ControlMessageOwned::ScmTimestampsns(timestamping)
+ }
#[cfg(any(
target_os = "android",
target_os = "freebsd",
@@ -1005,6 +1056,14 @@ pub enum ControlMessage<'a> {
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
RxqOvfl(&'a u32),
+
+ /// Configure the transmission time of packets.
+ ///
+ /// For further information, please refer to the
+ /// [`tc-etf(8)`](https://man7.org/linux/man-pages/man8/tc-etf.8.html) man
+ /// page.
+ #[cfg(target_os = "linux")]
+ TxTime(&'a u64),
}
// An opaque structure used to prevent cmsghdr from being a public type
@@ -1102,6 +1161,10 @@ impl<'a> ControlMessage<'a> {
ControlMessage::RxqOvfl(drop_count) => {
drop_count as *const _ as *const u8
},
+ #[cfg(target_os = "linux")]
+ ControlMessage::TxTime(tx_time) => {
+ tx_time as *const _ as *const u8
+ },
};
unsafe {
ptr::copy_nonoverlapping(
@@ -1157,6 +1220,10 @@ impl<'a> ControlMessage<'a> {
ControlMessage::RxqOvfl(drop_count) => {
mem::size_of_val(drop_count)
},
+ #[cfg(target_os = "linux")]
+ ControlMessage::TxTime(tx_time) => {
+ mem::size_of_val(tx_time)
+ },
}
}
@@ -1186,6 +1253,8 @@ impl<'a> ControlMessage<'a> {
ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
+ #[cfg(target_os = "linux")]
+ ControlMessage::TxTime(_) => libc::SOL_SOCKET,
}
}
@@ -1228,6 +1297,10 @@ impl<'a> ControlMessage<'a> {
ControlMessage::RxqOvfl(_) => {
libc::SO_RXQ_OVFL
},
+ #[cfg(target_os = "linux")]
+ ControlMessage::TxTime(_) => {
+ libc::SCM_TXTIME
+ },
}
}
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 3ad139ad..c600391c 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -16,7 +16,7 @@ use std::os::unix::ffi::OsStrExt;
// Constants
// TCP_CA_NAME_MAX isn't defined in user space include files
-#[cfg(any(target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
#[cfg(feature = "net")]
const TCP_CA_NAME_MAX: usize = 16;
@@ -465,7 +465,12 @@ sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
Ip6tOriginalDst, GetOnly, libc::SOL_IPV6, libc::IP6T_SO_ORIGINAL_DST, libc::sockaddr_in6);
-sockopt_impl!(
+#[cfg(any(target_os = "linux"))]
+sockopt_impl!(
+ /// Specifies exact type of timestamping information collected by the kernel
+ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
+ Timestamping, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPING, super::TimestampingFlag);
+sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
ReceiveTimestamp, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
#[cfg(all(target_os = "linux"))]
@@ -502,7 +507,7 @@ sockopt_impl!(
/// Enable or disable the receiving of the `SCM_CREDENTIALS` control
/// message.
PassCred, Both, libc::SOL_SOCKET, libc::SO_PASSCRED, bool);
-#[cfg(any(target_os = "freebsd", target_os = "linux"))]
+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -577,6 +582,11 @@ sockopt_impl!(
#[allow(missing_docs)]
// Not documented by Linux!
UdpGroSegment, Both, libc::IPPROTO_UDP, libc::UDP_GRO, bool);
+#[cfg(target_os = "linux")]
+sockopt_impl!(
+ /// Configures the behavior of time-based transmission of packets, for use
+ /// with the `TxTime` control message.
+ TxTime, Both, libc::SOL_SOCKET, libc::SO_TXTIME, libc::sock_txtime);
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
sockopt_impl!(
/// Indicates that an unsigned 32-bit value ancillary message (cmsg) should
diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs
index bfb94f48..62273475 100644
--- a/src/sys/statfs.rs
+++ b/src/sys/statfs.rs
@@ -536,7 +536,7 @@ impl Debug for Statfs {
/// Describes a mounted file system.
///
-/// The result is OS-dependent. For a portabable alternative, see
+/// The result is OS-dependent. For a portable alternative, see
/// [`statvfs`](crate::sys::statvfs::statvfs).
///
/// # Arguments
@@ -552,7 +552,7 @@ pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
/// Describes a mounted file system.
///
-/// The result is OS-dependent. For a portabable alternative, see
+/// The result is OS-dependent. For a portable alternative, see
/// [`fstatvfs`](crate::sys::statvfs::fstatvfs).
///
/// # Arguments
diff --git a/src/time.rs b/src/time.rs
index 959769f4..01a8fd00 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -14,7 +14,7 @@ use std::mem::MaybeUninit;
/// Clock identifier
///
-/// Newtype pattern around `clockid_t` (which is just alias). It pervents bugs caused by
+/// Newtype pattern around `clockid_t` (which is just alias). It prevents bugs caused by
/// accidentally passing wrong value.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ClockId(clockid_t);
diff --git a/src/unistd.rs b/src/unistd.rs
index 01f35215..7aa1cffe 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -204,8 +204,8 @@ impl ForkResult {
/// Create a new child process duplicating the parent process ([see
/// fork(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)).
///
-/// After calling the fork system call (successfully) two processes will
-/// be created that are identical with the exception of their pid and the
+/// After successfully calling the fork system call, a second process will
+/// be created which is identical to the original except for the pid and the
/// return value of this function. As an example:
///
/// ```
@@ -225,7 +225,7 @@ impl ForkResult {
/// }
/// ```
///
-/// This will print something like the following (order indeterministic). The
+/// This will print something like the following (order nondeterministic). The
/// thing to note is that you end up with two processes continuing execution
/// immediately after the fork call but with different match arms.
///
diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs
index 83fff9a5..89c4e2dd 100644
--- a/test/sys/test_ptrace.rs
+++ b/test/sys/test_ptrace.rs
@@ -72,7 +72,7 @@ fn test_ptrace_cont() {
let _m = crate::FORK_MTX.lock();
// FIXME: qemu-user doesn't implement ptrace on all architectures
- // and retunrs ENOSYS in this case.
+ // and returns ENOSYS in this case.
// We (ab)use this behavior to detect the affected platforms
// and skip the test then.
// On valid platforms the ptrace call should return Errno::EPERM, this
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index 0f6fac66..5262d3b8 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -57,6 +57,64 @@ pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() {
assert_eq!(from_storage, sockaddr);
}
+#[cfg(any(target_os = "linux"))]
+#[cfg_attr(qemu, ignore)]
+#[test]
+pub fn test_timestamping() {
+ use nix::sys::socket::{
+ recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping, ControlMessageOwned, MsgFlags,
+ SockFlag, SockType, TimestampingFlag,
+ };
+ use nix::sys::uio::IoVec;
+
+ let std_sa = SocketAddr::from_str("127.0.0.1:6790").unwrap();
+ let inet_addr = InetAddr::from_std(&std_sa);
+ let sock_addr = SockAddr::new_inet(inet_addr);
+
+ let ssock = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None,
+ )
+ .expect("send socket failed");
+
+ let rsock = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None,
+ )
+ .unwrap();
+ nix::sys::socket::bind(rsock, &sock_addr).unwrap();
+
+ setsockopt(rsock, Timestamping, &TimestampingFlag::all()).unwrap();
+
+ let sbuf = [0u8; 2048];
+ let mut rbuf = [0u8; 2048];
+ let flags = MsgFlags::empty();
+ let iov1 = [IoVec::from_slice(&sbuf)];
+ let iov2 = [IoVec::from_mut_slice(&mut rbuf)];
+ let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps);
+ sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap();
+ let recv = recvmsg(rsock, &iov2, Some(&mut cmsg), flags).unwrap();
+
+ let mut ts = None;
+ for c in recv.cmsgs() {
+ if let ControlMessageOwned::ScmTimestampsns(timestamps) = c {
+ ts = Some(timestamps.system);
+ }
+ }
+ let ts = ts.expect("ScmTimestampns is present");
+ let sys_time = ::nix::time::clock_gettime(::nix::time::ClockId::CLOCK_REALTIME).unwrap();
+ let diff = if ts > sys_time {
+ ts - sys_time
+ } else {
+ sys_time - ts
+ };
+ assert!(std::time::Duration::from(diff).as_secs() < 60);
+}
+
#[test]
pub fn test_inetv6_addr_to_sock_addr() {
let port: u16 = 3000;
@@ -1939,3 +1997,60 @@ mod linux_errqueue {
assert_eq!(ext_err.ee_info, 0);
}
}
+
+// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
+// of QEMU support is suspected.
+#[cfg_attr(qemu, ignore)]
+#[cfg(target_os = "linux")]
+#[test]
+pub fn test_txtime() {
+ use nix::sys::socket::{
+ bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage,
+ MsgFlags, SockFlag, SockType,
+ };
+ use nix::sys::time::TimeValLike;
+ use nix::time::{ClockId, clock_gettime};
+
+ require_kernel_version!(test_txtime, ">= 5.8");
+
+ let std_sa = SocketAddr::from_str("127.0.0.1:6790").unwrap();
+ let inet_addr = InetAddr::from_std(&std_sa);
+ let sock_addr = SockAddr::new_inet(inet_addr);
+
+ let ssock = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None,
+ )
+ .expect("send socket failed");
+
+ let txtime_cfg = libc::sock_txtime {
+ clockid: libc::CLOCK_MONOTONIC,
+ flags: 0,
+ };
+ setsockopt(ssock, sockopt::TxTime, &txtime_cfg).unwrap();
+
+ let rsock = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None,
+ )
+ .unwrap();
+ bind(rsock, &sock_addr).unwrap();
+
+ let sbuf = [0u8; 2048];
+ let iov1 = [nix::sys::uio::IoVec::from_slice(&sbuf)];
+
+ let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
+ let delay = std::time::Duration::from_secs(1).into();
+ let txtime = (now + delay).num_nanoseconds() as u64;
+
+ let cmsg = ControlMessage::TxTime(&txtime);
+ sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr)).unwrap();
+
+ let mut rbuf = [0u8; 2048];
+ let iov2 = [nix::sys::uio::IoVec::from_mut_slice(&mut rbuf)];
+ recvmsg(rsock, &iov2, None, MsgFlags::empty()).unwrap();
+}
diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs
index 01920fd4..59b97c8b 100644
--- a/test/sys/test_sockopt.rs
+++ b/test/sys/test_sockopt.rs
@@ -122,7 +122,7 @@ fn test_so_tcp_maxseg() {
}
// The CI doesn't supported getsockopt and setsockopt on emulated processors.
-// It's beleived that a QEMU issue, the tests run ok on a fully emulated system.
+// It's believed that a QEMU issue, the tests run ok on a fully emulated system.
// Current CI just run the binary with QEMU but the Kernel remains the same as the host.
// So the syscall doesn't work properly unless the kernel is also emulated.
#[test]
diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs
index db2acfbf..b24a49ee 100644
--- a/test/test_fcntl.rs
+++ b/test/test_fcntl.rs
@@ -488,6 +488,7 @@ mod test_posix_fadvise {
#[cfg(any(target_os = "linux",
target_os = "android",
+ target_os = "dragonfly",
target_os = "emscripten",
target_os = "fuchsia",
any(target_os = "wasi", target_env = "wasi"),
diff --git a/test/test_mount.rs b/test/test_mount.rs
index 44287f97..1ddfcfe9 100644
--- a/test/test_mount.rs
+++ b/test/test_mount.rs
@@ -1,6 +1,6 @@
mod common;
-// Impelmentation note: to allow unprivileged users to run it, this test makes
+// Implementation note: to allow unprivileged users to run it, this test makes
// use of user and mount namespaces. On systems that allow unprivileged user
// namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run
// without root.
diff --git a/test/test_stat.rs b/test/test_stat.rs
index 33cf748d..8baa6555 100644
--- a/test/test_stat.rs
+++ b/test/test_stat.rs
@@ -308,7 +308,8 @@ fn test_mkdirat_fail() {
}
#[test]
-#[cfg(not(any(target_os = "freebsd",
+#[cfg(not(any(target_os = "dragonfly",
+ target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "redox")))]
@@ -325,7 +326,8 @@ fn test_mknod() {
}
#[test]
-#[cfg(not(any(target_os = "freebsd",
+#[cfg(not(any(target_os = "dragonfly",
+ target_os = "freebsd",
target_os = "illumos",
target_os = "ios",
target_os = "macos",