summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--Cargo.toml2
-rw-r--r--src/lib.rs1
-rw-r--r--src/mount/bsd.rs32
-rw-r--r--src/sys/socket/mod.rs10
-rw-r--r--src/sys/statfs.rs205
6 files changed, 142 insertions, 112 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de01c2f7..43d122ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased] - ReleaseDate
### Added
+- Add `MntFlags` and `unmount` on all of the BSDs.
+ ([#1849](https://github.com/nix-rust/nix/pull/1849))
+- Added a 'Statfs::flags' method.
+ ([#1849](https://github.com/nix-rust/nix/pull/1849))
- Added `NSFS_MAGIC` FsType on Linux and Android.
([#1829](https://github.com/nix-rust/nix/pull/1829))
- Added `sched_getcpu` on platforms that support it.
diff --git a/Cargo.toml b/Cargo.toml
index 2edb003b..e09f758a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ targets = [
]
[dependencies]
-libc = { version = "0.2.135", features = [ "extra_traits" ] }
+libc = { git = "https://github.com/rust-lang/libc", rev = "cc19b6f0801", features = [ "extra_traits" ] }
bitflags = "1.1"
cfg-if = "1.0"
pin-utils = { version = "0.1.0", optional = true }
diff --git a/src/lib.rs b/src/lib.rs
index 770258dd..6b821257 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -106,7 +106,6 @@ feature! {
#[allow(missing_docs)]
pub mod kmod;
}
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
feature! {
#![feature = "mount"]
pub mod mount;
diff --git a/src/mount/bsd.rs b/src/mount/bsd.rs
index 109522f9..1ba8b809 100644
--- a/src/mount/bsd.rs
+++ b/src/mount/bsd.rs
@@ -1,16 +1,22 @@
+#[cfg(target_os = "freebsd")]
use crate::{
Error,
+};
+use crate::{
Errno,
NixPath,
Result,
};
-use libc::{c_char, c_int, c_uint, c_void};
+#[cfg(target_os = "freebsd")]
+use libc::{c_char, c_uint, c_void};
+use libc::c_int;
+#[cfg(target_os = "freebsd")]
use std::{
borrow::Cow,
ffi::{CString, CStr},
+ marker::PhantomData,
fmt,
io,
- marker::PhantomData,
};
@@ -110,12 +116,14 @@ libc_bitflags!(
///
/// It wraps an [`Errno`], but also may contain an additional message returned
/// by `nmount(2)`.
+#[cfg(target_os = "freebsd")]
#[derive(Debug)]
pub struct NmountError {
errno: Error,
errmsg: Option<String>
}
+#[cfg(target_os = "freebsd")]
impl NmountError {
/// Returns the additional error string sometimes generated by `nmount(2)`.
pub fn errmsg(&self) -> Option<&str> {
@@ -135,8 +143,10 @@ impl NmountError {
}
}
+#[cfg(target_os = "freebsd")]
impl std::error::Error for NmountError {}
+#[cfg(target_os = "freebsd")]
impl fmt::Display for NmountError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(errmsg) = &self.errmsg {
@@ -147,6 +157,7 @@ impl fmt::Display for NmountError {
}
}
+#[cfg(target_os = "freebsd")]
impl From<NmountError> for io::Error {
fn from(err: NmountError) -> Self {
err.errno.into()
@@ -154,6 +165,7 @@ impl From<NmountError> for io::Error {
}
/// Result type of [`Nmount::nmount`].
+#[cfg(target_os = "freebsd")]
pub type NmountResult = std::result::Result<(), NmountError>;
/// Mount a FreeBSD file system.
@@ -425,13 +437,15 @@ impl<'a> Drop for Nmount<'a> {
///
/// Useful flags include
/// * `MNT_FORCE` - Unmount even if still in use.
-/// * `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID
-/// encoded as `FSID:val0:val1`, where `val0` and `val1`
-/// are the contents of the `fsid_t val[]` array in decimal.
-/// The file system that has the specified file system ID
-/// will be unmounted. See
-/// [`statfs`](crate::sys::statfs::statfs) to determine the
-/// `fsid`.
+#[cfg_attr(target_os = "freebsd", doc = "
+* `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID
+ encoded as `FSID:val0:val1`, where `val0` and `val1`
+ are the contents of the `fsid_t val[]` array in decimal.
+ The file system that has the specified file system ID
+ will be unmounted. See
+ [`statfs`](crate::sys::statfs::statfs) to determine the
+ `fsid`.
+")]
pub fn unmount<P>(mountpoint: &P, flags: MntFlags) -> Result<()>
where P: ?Sized + NixPath
{
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 04a6f937..af19c52d 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -272,14 +272,17 @@ libc_bitflags! {
/// Sends or requests out-of-band data on sockets that support this notion
/// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also
/// support out-of-band data.
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_OOB;
/// Peeks at an incoming message. The data is treated as unread and the next
/// [`recv()`](fn.recv.html)
/// or similar function shall still return this data.
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_PEEK;
/// Receive operation blocks until the full amount of data can be
/// returned. The function may return smaller amount of data if a signal
/// is caught, an error or disconnect occurs.
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_WAITALL;
/// Enables nonblocking operation; if the operation would block,
/// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar
@@ -291,8 +294,10 @@ libc_bitflags! {
/// which will affect all threads in
/// the calling process and as well as other processes that hold
/// file descriptors referring to the same open file description.
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_DONTWAIT;
/// Receive flags: Control Data was discarded (buffer too small)
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_CTRUNC;
/// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram
/// (since Linux 2.4.27/2.6.8),
@@ -302,15 +307,18 @@ libc_bitflags! {
/// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets.
///
/// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp).
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_TRUNC;
/// Terminates a record (when this notion is supported, as for
/// sockets of type [`SeqPacket`](enum.SockType.html)).
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_EOR;
/// This flag specifies that queued errors should be received from
/// the socket error queue. (For more details, see
/// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_ERRQUEUE;
/// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
/// file descriptor using the `SCM_RIGHTS` operation (described in
@@ -326,6 +334,7 @@ libc_bitflags! {
target_os = "netbsd",
target_os = "openbsd"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_CMSG_CLOEXEC;
/// Requests not to send `SIGPIPE` errors when the other end breaks the connection.
/// (For more details, see [send(2)](https://linux.die.net/man/2/send)).
@@ -340,6 +349,7 @@ libc_bitflags! {
target_os = "openbsd",
target_os = "solaris"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
+ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
MSG_NOSIGNAL;
}
}
diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs
index 83196dba..9c28bc21 100644
--- a/src/sys/statfs.rs
+++ b/src/sys/statfs.rs
@@ -7,7 +7,19 @@ use std::os::unix::io::AsRawFd;
#[cfg(not(any(target_os = "linux", target_os = "android")))]
use std::ffi::CStr;
+use cfg_if::cfg_if;
+
use crate::{NixPath, Result, errno::Errno};
+#[cfg(all(feature = "mount",
+ any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd")
+))]
+use crate::mount::MntFlags;
+#[cfg(target_os = "linux")]
+use crate::sys::statvfs::FsFlags;
/// Identifies a mounted file system
#[cfg(target_os = "android")]
@@ -18,10 +30,30 @@ pub type fsid_t = libc::__fsid_t;
#[cfg_attr(docsrs, doc(cfg(all())))]
pub type fsid_t = libc::fsid_t;
+cfg_if! {
+ if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] {
+ type type_of_statfs = libc::statfs64;
+ const LIBC_FSTATFS: unsafe extern fn
+ (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
+ = libc::fstatfs64;
+ const LIBC_STATFS: unsafe extern fn
+ (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
+ = libc::statfs64;
+ } else {
+ type type_of_statfs = libc::statfs;
+ const LIBC_FSTATFS: unsafe extern fn
+ (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
+ = libc::fstatfs;
+ const LIBC_STATFS: unsafe extern fn
+ (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
+ = libc::statfs;
+ }
+}
+
/// Describes a mounted file system
#[derive(Clone, Copy)]
#[repr(transparent)]
-pub struct Statfs(libc::statfs);
+pub struct Statfs(type_of_statfs);
#[cfg(target_os = "freebsd")]
type fs_type_t = u32;
@@ -352,6 +384,29 @@ impl Statfs {
self.0.f_bsize
}
+ /// Get the mount flags
+ #[cfg(all(feature = "mount",
+ any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd")
+ ))]
+ #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches
+ pub fn flags(&self) -> MntFlags {
+ MntFlags::from_bits_truncate(self.0.f_flags as i32)
+ }
+
+ /// Get the mount flags
+ // The f_flags field exists on Android and Fuchsia too, but without man
+ // pages I can't tell if it can be cast to FsFlags.
+ #[cfg(target_os = "linux")]
+ #[cfg_attr(docsrs, doc(cfg(all())))]
+ pub fn flags(&self) -> FsFlags {
+ FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong)
+ }
+
/// Maximum length of filenames
#[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
@@ -400,7 +455,9 @@ impl Statfs {
target_os = "macos",
target_os = "android",
target_os = "freebsd",
+ target_os = "fuchsia",
target_os = "openbsd",
+ target_os = "linux",
))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks(&self) -> u64 {
@@ -415,24 +472,9 @@ impl Statfs {
}
/// Total data blocks in filesystem
- #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ #[cfg(target_os = "emscripten")]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks(&self) -> u64 {
- self.0.f_blocks
- }
-
- /// Total data blocks in filesystem
- #[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks(&self) -> libc::c_ulong {
+ pub fn blocks(&self) -> u32 {
self.0.f_blocks
}
@@ -442,7 +484,9 @@ impl Statfs {
target_os = "macos",
target_os = "android",
target_os = "freebsd",
+ target_os = "fuchsia",
target_os = "openbsd",
+ target_os = "linux",
))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_free(&self) -> u64 {
@@ -457,29 +501,20 @@ impl Statfs {
}
/// Free blocks in filesystem
- #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ #[cfg(target_os = "emscripten")]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_free(&self) -> u64 {
+ pub fn blocks_free(&self) -> u32 {
self.0.f_bfree
}
- /// Free blocks in filesystem
- #[cfg(not(any(
+ /// Free blocks available to unprivileged user
+ #[cfg(any(
target_os = "ios",
target_os = "macos",
target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_free(&self) -> libc::c_ulong {
- self.0.f_bfree
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
+ target_os = "fuchsia",
+ target_os = "linux",
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn blocks_available(&self) -> u64 {
self.0.f_bavail
@@ -500,24 +535,9 @@ impl Statfs {
}
/// Free blocks available to unprivileged user
- #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ #[cfg(target_os = "emscripten")]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> u64 {
- self.0.f_bavail
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> libc::c_ulong {
+ pub fn blocks_available(&self) -> u32 {
self.0.f_bavail
}
@@ -527,7 +547,9 @@ impl Statfs {
target_os = "macos",
target_os = "android",
target_os = "freebsd",
+ target_os = "fuchsia",
target_os = "openbsd",
+ target_os = "linux",
))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files(&self) -> u64 {
@@ -542,33 +564,20 @@ impl Statfs {
}
/// Total file nodes in filesystem
- #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
+ #[cfg(target_os = "emscripten")]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files(&self) -> libc::fsfilcnt_t {
+ pub fn files(&self) -> u32 {
self.0.f_files
}
- /// Total file nodes in filesystem
- #[cfg(not(any(
+ /// Free file nodes in filesystem
+ #[cfg(any(
target_os = "ios",
target_os = "macos",
target_os = "android",
- target_os = "freebsd",
+ target_os = "fuchsia",
target_os = "openbsd",
- target_os = "dragonfly",
- all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files(&self) -> libc::c_ulong {
- self.0.f_files
- }
-
- /// Free file nodes in filesystem
- #[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "macos",
- target_os = "openbsd"
+ target_os = "linux",
))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn files_free(&self) -> u64 {
@@ -590,24 +599,9 @@ impl Statfs {
}
/// Free file nodes in filesystem
- #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- 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",
- target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
- )))]
+ #[cfg(target_os = "emscripten")]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files_free(&self) -> libc::c_ulong {
+ pub fn files_free(&self) -> u32 {
self.0.f_ffree
}
@@ -619,16 +613,25 @@ impl Statfs {
impl Debug for Statfs {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Statfs")
- .field("optimal_transfer_size", &self.optimal_transfer_size())
- .field("block_size", &self.block_size())
- .field("blocks", &self.blocks())
- .field("blocks_free", &self.blocks_free())
- .field("blocks_available", &self.blocks_available())
- .field("files", &self.files())
- .field("files_free", &self.files_free())
- .field("filesystem_id", &self.filesystem_id())
- .finish()
+ let mut ds = f.debug_struct("Statfs");
+ ds.field("optimal_transfer_size", &self.optimal_transfer_size());
+ ds.field("block_size", &self.block_size());
+ ds.field("blocks", &self.blocks());
+ ds.field("blocks_free", &self.blocks_free());
+ ds.field("blocks_available", &self.blocks_available());
+ ds.field("files", &self.files());
+ ds.field("files_free", &self.files_free());
+ ds.field("filesystem_id", &self.filesystem_id());
+ #[cfg(all(feature = "mount",
+ any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd")
+ ))]
+ ds.field("flags", &self.flags());
+ ds.finish()
+
}
}
@@ -642,8 +645,8 @@ impl Debug for Statfs {
/// `path` - Path to any file within the file system to describe
pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
unsafe {
- let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
- let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?;
+ let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
+ let res = path.with_nix_path(|path| LIBC_STATFS(path.as_ptr(), stat.as_mut_ptr()))?;
Errno::result(res).map(|_| Statfs(stat.assume_init()))
}
}
@@ -658,8 +661,8 @@ pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
/// `fd` - File descriptor of any open file within the file system to describe
pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
unsafe {
- let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
- Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr()))
+ let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
+ Errno::result(LIBC_FSTATFS(fd.as_raw_fd(), stat.as_mut_ptr()))
.map(|_| Statfs(stat.assume_init()))
}
}