summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dir.rs86
-rw-r--r--src/mqueue.rs21
-rw-r--r--src/pty.rs2
-rw-r--r--src/sys/signalfd.rs7
-rw-r--r--src/sys/statfs.rs175
-rw-r--r--src/sys/sysinfo.rs8
-rw-r--r--src/sys/time.rs19
-rw-r--r--src/sys/wait.rs38
-rw-r--r--src/unistd.rs3
9 files changed, 215 insertions, 144 deletions
diff --git a/src/dir.rs b/src/dir.rs
index 1d48f18c..7d4ab82f 100644
--- a/src/dir.rs
+++ b/src/dir.rs
@@ -25,7 +25,7 @@ use libc::{dirent, readdir_r};
/// * returns entries for `.` (current directory) and `..` (parent directory).
/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
/// does).
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+#[derive(Debug, Eq, Hash, PartialEq)]
pub struct Dir(
ptr::NonNull<libc::DIR>
);
@@ -85,7 +85,32 @@ impl AsRawFd for Dir {
impl Drop for Dir {
fn drop(&mut self) {
- unsafe { libc::closedir(self.0.as_ptr()) };
+ let e = Errno::result(unsafe { libc::closedir(self.0.as_ptr()) });
+ if !std::thread::panicking() && e == Err(Error::Sys(Errno::EBADF)) {
+ panic!("Closing an invalid file descriptor!");
+ };
+ }
+}
+
+fn next(dir: &mut Dir) -> Option<Result<Entry>> {
+ unsafe {
+ // Note: POSIX specifies that portable applications should dynamically allocate a
+ // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
+ // for the NUL byte. It doesn't look like the std library does this; it just uses
+ // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
+ // Probably fine here too then.
+ let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
+ let mut result = ptr::null_mut();
+ if let Err(e) = Errno::result(
+ readdir_r(dir.0.as_ptr(), ent.as_mut_ptr(), &mut result))
+ {
+ return Some(Err(e));
+ }
+ if result.is_null() {
+ return None;
+ }
+ assert_eq!(result, ent.as_mut_ptr());
+ Some(Ok(Entry(ent.assume_init())))
}
}
@@ -96,25 +121,7 @@ impl<'d> Iterator for Iter<'d> {
type Item = Result<Entry>;
fn next(&mut self) -> Option<Self::Item> {
- unsafe {
- // Note: POSIX specifies that portable applications should dynamically allocate a
- // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
- // for the NUL byte. It doesn't look like the std library does this; it just uses
- // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
- // Probably fine here too then.
- let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
- let mut result = ptr::null_mut();
- if let Err(e) = Errno::result(
- readdir_r((self.0).0.as_ptr(), ent.as_mut_ptr(), &mut result))
- {
- return Some(Err(e));
- }
- if result.is_null() {
- return None;
- }
- assert_eq!(result, ent.as_mut_ptr());
- Some(Ok(Entry(ent.assume_init())))
- }
+ next(self.0)
}
}
@@ -124,6 +131,43 @@ impl<'d> Drop for Iter<'d> {
}
}
+/// The return type of [Dir::into_iter]
+#[derive(Debug, Eq, Hash, PartialEq)]
+pub struct OwningIter(Dir);
+
+impl Iterator for OwningIter {
+ type Item = Result<Entry>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ next(&mut self.0)
+ }
+}
+
+impl IntoIterator for Dir {
+ type Item = Result<Entry>;
+ type IntoIter = OwningIter;
+
+ /// Creates a owning iterator, that is, one that takes ownership of the
+ /// `Dir`. The `Dir` cannot be used after calling this. This can be useful
+ /// when you have a function that both creates a `Dir` instance and returns
+ /// an `Iterator`.
+ ///
+ /// Example:
+ ///
+ /// ```
+ /// use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode};
+ /// use std::{iter::Iterator, string::String};
+ ///
+ /// fn ls_upper(dirname: &str) -> impl Iterator<Item=String> {
+ /// let d = Dir::open(dirname, OFlag::O_DIRECTORY, Mode::S_IXUSR).unwrap();
+ /// d.into_iter().map(|x| x.unwrap().file_name().as_ref().to_string_lossy().to_ascii_uppercase())
+ /// }
+ /// ```
+ fn into_iter(self) -> Self::IntoIter {
+ OwningIter(self)
+ }
+}
+
/// A directory entry, similar to `std::fs::DirEntry`.
///
/// Note that unlike the std version, this may represent the `.` or `..` entries.
diff --git a/src/mqueue.rs b/src/mqueue.rs
index 122705a5..0215de5a 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -5,7 +5,7 @@
use crate::Result;
use crate::errno::Errno;
-use libc::{self, c_char, c_long, mqd_t, size_t};
+use libc::{self, c_char, mqd_t, size_t};
use std::ffi::CString;
use crate::sys::stat::Mode;
use std::mem;
@@ -34,11 +34,18 @@ pub struct MqAttr {
mq_attr: libc::mq_attr,
}
+// x32 compatibility
+// See https://sourceware.org/bugzilla/show_bug.cgi?id=21279
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
+pub type mq_attr_member_t = i64;
+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
+pub type mq_attr_member_t = libc::c_long;
+
impl MqAttr {
- pub fn new(mq_flags: c_long,
- mq_maxmsg: c_long,
- mq_msgsize: c_long,
- mq_curmsgs: c_long)
+ pub fn new(mq_flags: mq_attr_member_t,
+ mq_maxmsg: mq_attr_member_t,
+ mq_msgsize: mq_attr_member_t,
+ mq_curmsgs: mq_attr_member_t)
-> MqAttr
{
let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
@@ -52,7 +59,7 @@ impl MqAttr {
}
}
- pub fn flags(&self) -> c_long {
+ pub fn flags(&self) -> mq_attr_member_t {
self.mq_attr.mq_flags
}
}
@@ -150,7 +157,7 @@ pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
/// Returns the old attributes
pub fn mq_set_nonblock(mqd: mqd_t) -> Result<MqAttr> {
let oldattr = mq_getattr(mqd)?;
- let newattr = MqAttr::new(c_long::from(MQ_OFlag::O_NONBLOCK.bits()),
+ let newattr = MqAttr::new(mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()),
oldattr.mq_attr.mq_maxmsg,
oldattr.mq_attr.mq_msgsize,
oldattr.mq_attr.mq_curmsgs);
diff --git a/src/pty.rs b/src/pty.rs
index 3a6a9232..d67518f4 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -43,7 +43,7 @@ pub struct ForkptyResult {
/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+#[derive(Debug, Eq, Hash, PartialEq)]
pub struct PtyMaster(RawFd);
impl AsRawFd for PtyMaster {
diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs
index e3ded1f7..c43b4504 100644
--- a/src/sys/signalfd.rs
+++ b/src/sys/signalfd.rs
@@ -79,7 +79,7 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// Err(err) => (), // some error happend
/// }
/// ```
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+#[derive(Debug, Eq, Hash, PartialEq)]
pub struct SignalFd(RawFd);
impl SignalFd {
@@ -116,7 +116,10 @@ impl SignalFd {
impl Drop for SignalFd {
fn drop(&mut self) {
- let _ = unistd::close(self.0);
+ let e = unistd::close(self.0);
+ if !std::thread::panicking() && e == Err(Error::Sys(Errno::EBADF)) {
+ panic!("Closing an invalid file descriptor!");
+ };
}
}
diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs
index 8e90a58d..27b72592 100644
--- a/src/sys/statfs.rs
+++ b/src/sys/statfs.rs
@@ -16,79 +16,85 @@ pub type fsid_t = libc::fsid_t;
pub struct Statfs(libc::statfs);
#[cfg(target_os = "freebsd")]
-#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub u32);
+type fs_type_t = u32;
#[cfg(target_os = "android")]
-#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub libc::c_ulong);
+type fs_type_t = libc::c_ulong;
#[cfg(all(target_os = "linux", target_arch = "s390x"))]
-#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub u32);
+type fs_type_t = libc::c_uint;
#[cfg(all(target_os = "linux", target_env = "musl"))]
-#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub libc::c_ulong);
+type fs_type_t = libc::c_ulong;
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
+type fs_type_t = libc::__fsword_t;
+
+#[cfg(any(
+ target_os = "freebsd",
+ target_os = "android",
+ all(target_os = "linux", target_arch = "s390x"),
+ all(target_os = "linux", target_env = "musl"),
+ all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))),
+))]
#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub libc::c_long);
-
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC);
-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
-pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC);
+pub struct FsType(pub fs_type_t);
+
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
+pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
+
impl Statfs {
/// Magic code defining system type
@@ -138,7 +144,7 @@ impl Statfs {
/// Optimal transfer block size
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
- pub fn optimal_transfer_size(&self) -> libc::c_long {
+ pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
self.0.f_bsize
}
@@ -177,7 +183,7 @@ impl Statfs {
/// Size of a block
// f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
- pub fn block_size(&self) -> libc::c_long {
+ pub fn block_size(&self) -> libc::__fsword_t {
self.0.f_bsize
}
@@ -219,7 +225,7 @@ impl Statfs {
/// Maximum length of filenames
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
- pub fn maximum_name_length(&self) -> libc::c_long {
+ pub fn maximum_name_length(&self) -> libc::__fsword_t {
self.0.f_namelen
}
@@ -248,7 +254,7 @@ impl Statfs {
}
/// Total data blocks in filesystem
- #[cfg(all(target_os = "linux", target_env = "musl"))]
+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
pub fn blocks(&self) -> u64 {
self.0.f_blocks
}
@@ -261,7 +267,7 @@ impl Statfs {
target_os = "freebsd",
target_os = "openbsd",
target_os = "dragonfly",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
)))]
pub fn blocks(&self) -> libc::c_ulong {
self.0.f_blocks
@@ -286,7 +292,7 @@ impl Statfs {
}
/// Free blocks in filesystem
- #[cfg(all(target_os = "linux", target_env = "musl"))]
+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
pub fn blocks_free(&self) -> u64 {
self.0.f_bfree
}
@@ -299,7 +305,7 @@ impl Statfs {
target_os = "freebsd",
target_os = "openbsd",
target_os = "dragonfly",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
)))]
pub fn blocks_free(&self) -> libc::c_ulong {
self.0.f_bfree
@@ -324,7 +330,7 @@ impl Statfs {
}
/// Free blocks available to unprivileged user
- #[cfg(all(target_os = "linux", target_env = "musl"))]
+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
pub fn blocks_available(&self) -> u64 {
self.0.f_bavail
}
@@ -337,7 +343,7 @@ impl Statfs {
target_os = "freebsd",
target_os = "openbsd",
target_os = "dragonfly",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
)))]
pub fn blocks_available(&self) -> libc::c_ulong {
self.0.f_bavail
@@ -362,8 +368,8 @@ impl Statfs {
}
/// Total file nodes in filesystem
- #[cfg(all(target_os = "linux", target_env = "musl"))]
- pub fn files(&self) -> u64 {
+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ pub fn files(&self) -> libc::fsfilcnt_t {
self.0.f_files
}
@@ -375,7 +381,7 @@ impl Statfs {
target_os = "freebsd",
target_os = "openbsd",
target_os = "dragonfly",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
)))]
pub fn files(&self) -> libc::c_ulong {
self.0.f_files
@@ -385,7 +391,6 @@ impl Statfs {
#[cfg(any(
target_os = "android",
target_os = "ios",
- all(target_os = "linux", target_env = "musl"),
target_os = "macos",
target_os = "openbsd"
))]
@@ -406,6 +411,12 @@ impl Statfs {
}
/// Free file nodes in filesystem
+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ pub fn files_free(&self) -> libc::fsfilcnt_t {
+ self.0.f_ffree
+ }
+
+ /// Free file nodes in filesystem
#[cfg(not(any(
target_os = "ios",
target_os = "macos",
@@ -413,7 +424,7 @@ impl Statfs {
target_os = "freebsd",
target_os = "openbsd",
target_os = "dragonfly",
- all(target_os = "linux", target_env = "musl")
+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
)))]
pub fn files_free(&self) -> libc::c_ulong {
self.0.f_ffree
diff --git a/src/sys/sysinfo.rs b/src/sys/sysinfo.rs
index f4b82798..222a2fc0 100644
--- a/src/sys/sysinfo.rs
+++ b/src/sys/sysinfo.rs
@@ -10,6 +10,12 @@ use crate::errno::Errno;
#[repr(transparent)]
pub struct SysInfo(libc::sysinfo);
+// The fields are c_ulong on 32-bit linux, u64 on 64-bit linux; x32's ulong is u32
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
+type mem_blocks_t = u64;
+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
+type mem_blocks_t = libc::c_ulong;
+
impl SysInfo {
/// Returns the load average tuple.
///
@@ -58,7 +64,7 @@ impl SysInfo {
self.scale_mem(self.0.freeram)
}
- fn scale_mem(&self, units: libc::c_ulong) -> u64 {
+ fn scale_mem(&self, units: mem_blocks_t) -> u64 {
units as u64 * self.0.mem_unit as u64
}
}
diff --git a/src/sys/time.rs b/src/sys/time.rs
index bdcfe3c9..7546d1b3 100644
--- a/src/sys/time.rs
+++ b/src/sys/time.rs
@@ -1,7 +1,7 @@
use std::{cmp, fmt, ops};
use std::time::Duration;
use std::convert::From;
-use libc::{c_long, timespec, timeval};
+use libc::{timespec, timeval};
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
pub use libc::{time_t, suseconds_t};
@@ -62,6 +62,13 @@ const TS_MAX_SECONDS: i64 = ::std::isize::MAX as i64;
const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS;
+// x32 compatibility
+// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
+type timespec_tv_nsec_t = i64;
+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
+type timespec_tv_nsec_t = libc::c_long;
+
impl From<timespec> for TimeSpec {
fn from(ts: timespec) -> Self {
Self(ts)
@@ -73,7 +80,7 @@ impl From<Duration> for TimeSpec {
#[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 c_long
+ tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t
})
}
}
@@ -148,7 +155,7 @@ impl TimeValLike for TimeSpec {
"TimeSpec out of bounds");
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
TimeSpec(timespec {tv_sec: secs as time_t,
- tv_nsec: nanos as c_long })
+ tv_nsec: nanos as timespec_tv_nsec_t })
}
fn num_seconds(&self) -> i64 {
@@ -175,9 +182,9 @@ impl TimeValLike for TimeSpec {
}
impl TimeSpec {
- fn nanos_mod_sec(&self) -> c_long {
+ fn nanos_mod_sec(&self) -> timespec_tv_nsec_t {
if self.tv_sec() < 0 && self.tv_nsec() > 0 {
- self.tv_nsec() - NANOS_PER_SEC as c_long
+ self.tv_nsec() - NANOS_PER_SEC as timespec_tv_nsec_t
} else {
self.tv_nsec()
}
@@ -188,7 +195,7 @@ impl TimeSpec {
self.0.tv_sec
}
- pub fn tv_nsec(&self) -> c_long {
+ pub fn tv_nsec(&self) -> timespec_tv_nsec_t {
self.0.tv_nsec
}
}
diff --git a/src/sys/wait.rs b/src/sys/wait.rs
index 0c040427..faf8543c 100644
--- a/src/sys/wait.rs
+++ b/src/sys/wait.rs
@@ -1,9 +1,9 @@
-use cfg_if::cfg_if;
-use libc::{self, c_int};
-use crate::Result;
use crate::errno::Errno;
-use crate::unistd::Pid;
use crate::sys::signal::Signal;
+use crate::unistd::Pid;
+use crate::Result;
+use cfg_if::cfg_if;
+use libc::{self, c_int};
use std::convert::TryFrom;
libc_bitflags!(
@@ -108,8 +108,7 @@ impl WaitStatus {
pub fn pid(&self) -> Option<Pid> {
use self::WaitStatus::*;
match *self {
- Exited(p, _) | Signaled(p, _, _) |
- Stopped(p, _) | Continued(p) => Some(p),
+ Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => Some(p),
StillAlive => None,
#[cfg(any(target_os = "android", target_os = "linux"))]
PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
@@ -117,49 +116,41 @@ impl WaitStatus {
}
}
-#[allow(unused_unsafe)]
fn exited(status: i32) -> bool {
- unsafe { libc::WIFEXITED(status) }
+ libc::WIFEXITED(status)
}
-#[allow(unused_unsafe)]
fn exit_status(status: i32) -> i32 {
- unsafe { libc::WEXITSTATUS(status) }
+ libc::WEXITSTATUS(status)
}
-#[allow(unused_unsafe)]
fn signaled(status: i32) -> bool {
- unsafe { libc::WIFSIGNALED(status) }
+ libc::WIFSIGNALED(status)
}
-#[allow(unused_unsafe)]
fn term_signal(status: i32) -> Result<Signal> {
- Signal::try_from(unsafe { libc::WTERMSIG(status) })
+ Signal::try_from(libc::WTERMSIG(status))
}
-#[allow(unused_unsafe)]
fn dumped_core(status: i32) -> bool {
- unsafe { libc::WCOREDUMP(status) }
+ libc::WCOREDUMP(status)
}
-#[allow(unused_unsafe)]
fn stopped(status: i32) -> bool {
- unsafe { libc::WIFSTOPPED(status) }
+ libc::WIFSTOPPED(status)
}
-#[allow(unused_unsafe)]
fn stop_signal(status: i32) -> Result<Signal> {
- Signal::try_from(unsafe { libc::WSTOPSIG(status) })
+ Signal::try_from(libc::WSTOPSIG(status))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
-#[allow(unused_unsafe)]
fn syscall_stop(status: i32) -> bool {
// From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
// of delivering SIGTRAP | 0x80 as the signal number for syscall
// stops. This allows easily distinguishing syscall stops from
// genuine SIGTRAP signals.
- unsafe { libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 }
+ libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80
}
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -167,9 +158,8 @@ fn stop_additional(status: i32) -> c_int {
(status >> 16) as c_int
}
-#[allow(unused_unsafe)]
fn continued(status: i32) -> bool {
- unsafe { libc::WIFCONTINUED(status) }
+ libc::WIFCONTINUED(status)
}
impl WaitStatus {
diff --git a/src/unistd.rs b/src/unistd.rs
index dd335596..7a4517e6 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -2671,6 +2671,8 @@ impl User {
pub struct Group {
/// Group name
pub name: String,
+ /// Group password
+ pub passwd: CString,
/// Group ID
pub gid: Gid,
/// List of Group members
@@ -2683,6 +2685,7 @@ impl From<&libc::group> for Group {
unsafe {
Group {
name: CStr::from_ptr((*gr).gr_name).to_string_lossy().into_owned(),
+ passwd: CString::new(CStr::from_ptr((*gr).gr_passwd).to_bytes()).unwrap(),
gid: Gid::from_raw((*gr).gr_gid),
mem: Group::members((*gr).gr_mem)
}