mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
stat: use struct libc::statfs now
This commit is contained in:
parent
48968f3d8a
commit
580667295c
1 changed files with 104 additions and 45 deletions
|
@ -12,7 +12,7 @@ extern crate time;
|
||||||
use self::time::Timespec;
|
use self::time::Timespec;
|
||||||
pub use self::libc::{S_IFMT, S_IFDIR, S_IFCHR, S_IFBLK, S_IFREG, S_IFIFO, S_IFLNK, S_IFSOCK,
|
pub use self::libc::{S_IFMT, S_IFDIR, S_IFCHR, S_IFBLK, S_IFREG, S_IFIFO, S_IFLNK, S_IFSOCK,
|
||||||
S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP,
|
S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP,
|
||||||
S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH};
|
S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, mode_t, c_int, strerror};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! has {
|
macro_rules! has {
|
||||||
|
@ -26,7 +26,7 @@ pub fn pretty_time(sec: i64, nsec: i64) -> String {
|
||||||
time::strftime("%Y-%m-%d %H:%M:%S.%f %z", &tm).unwrap()
|
time::strftime("%Y-%m-%d %H:%M:%S.%f %z", &tm).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_filetype<'a>(mode: u32, size: u64) -> &'a str {
|
pub fn pretty_filetype<'a>(mode: mode_t, size: u64) -> &'a str {
|
||||||
match mode & S_IFMT {
|
match mode & S_IFMT {
|
||||||
S_IFREG => {
|
S_IFREG => {
|
||||||
if size != 0 {
|
if size != 0 {
|
||||||
|
@ -47,7 +47,7 @@ pub fn pretty_filetype<'a>(mode: u32, size: u64) -> &'a str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_access(mode: u32) -> String {
|
pub fn pretty_access(mode: mode_t) -> String {
|
||||||
let mut result = String::with_capacity(10);
|
let mut result = String::with_capacity(10);
|
||||||
result.push(match mode & S_IFMT {
|
result.push(match mode & S_IFMT {
|
||||||
S_IFDIR => 'd',
|
S_IFDIR => 'd',
|
||||||
|
@ -136,57 +136,116 @@ use std::path::Path;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::convert::{AsRef, From};
|
use std::convert::{AsRef, From};
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::Error as IOError;
|
||||||
|
|
||||||
pub struct Statfs {
|
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android"))]
|
||||||
pub f_type: i64,
|
use self::libc::statfs as Sstatfs;
|
||||||
pub f_bsize: i64,
|
// #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "bitrig", target_os = "dragonfly"))]
|
||||||
pub f_blocks: u64,
|
// use self::libc::statvfs as Sstatfs;
|
||||||
pub f_bfree: u64,
|
|
||||||
pub f_bavail: u64,
|
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android"))]
|
||||||
pub f_files: u64,
|
use self::libc::statfs as statfs_fn;
|
||||||
pub f_ffree: u64,
|
// #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "bitrig", target_os = "dragonfly"))]
|
||||||
pub f_namelen: i64,
|
// use self::libc::statvfs as statfs_fn;
|
||||||
pub f_frsize: i64,
|
|
||||||
pub f_fsid: u64,
|
pub trait FsMeta {
|
||||||
|
fn fs_type(&self) -> i64;
|
||||||
|
fn iosize(&self) -> i64;
|
||||||
|
fn blksize(&self) -> i64;
|
||||||
|
fn total_blocks(&self) -> u64;
|
||||||
|
fn free_blocks(&self) -> u64;
|
||||||
|
fn avail_blocks(&self) -> u64;
|
||||||
|
fn total_fnodes(&self) -> u64;
|
||||||
|
fn free_fnodes(&self) -> u64;
|
||||||
|
fn fsid(&self) -> u64;
|
||||||
|
fn namelen(&self) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn statfs<P: AsRef<Path>>(path: P) -> Result<Statfs, String>
|
impl FsMeta for Sstatfs {
|
||||||
where Vec<u8>: From<P>
|
fn blksize(&self) -> i64 {
|
||||||
{
|
self.f_bsize as i64
|
||||||
use std::error::Error;
|
}
|
||||||
match CString::new(path) {
|
fn total_blocks(&self) -> u64 {
|
||||||
Ok(p) => {
|
self.f_blocks as u64
|
||||||
let mut buffer = unsafe { mem::zeroed() };
|
}
|
||||||
unsafe {
|
fn free_blocks(&self) -> u64 {
|
||||||
match self::libc::statfs(p.as_ptr(), &mut buffer) {
|
self.f_bfree as u64
|
||||||
0 => {
|
}
|
||||||
let fsid: u64;
|
fn avail_blocks(&self) -> u64 {
|
||||||
if cfg!(unix) {
|
self.f_bavail as u64
|
||||||
|
}
|
||||||
|
fn total_fnodes(&self) -> u64 {
|
||||||
|
self.f_files as u64
|
||||||
|
}
|
||||||
|
fn free_fnodes(&self) -> u64 {
|
||||||
|
self.f_ffree as u64
|
||||||
|
}
|
||||||
|
fn fs_type(&self) -> i64 {
|
||||||
|
self.f_type as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn iosize(&self) -> i64 {
|
||||||
|
self.f_frsize as i64
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn iosize(&self) -> i64 {
|
||||||
|
self.f_iosize as i64
|
||||||
|
}
|
||||||
|
// FIXME:
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
|
fn iosize(&self) -> i64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
// Linux, SunOS, HP-UX, 4.4BSD, FreeBSD have a system call statfs() that returns
|
// Linux, SunOS, HP-UX, 4.4BSD, FreeBSD have a system call statfs() that returns
|
||||||
// a struct statfs, containing a fsid_t f_fsid, where fsid_t is defined
|
// a struct statfs, containing a fsid_t f_fsid, where fsid_t is defined
|
||||||
// as struct { int val[2]; }
|
// as struct { int val[2]; }
|
||||||
let f_fsid: &[u32; 2] = transmute(&buffer.f_fsid);
|
//
|
||||||
fsid = (f_fsid[0] as u64) << 32_u64 | f_fsid[1] as u64;
|
|
||||||
} else {
|
|
||||||
// Solaris, Irix and POSIX have a system call statvfs(2) that returns a
|
// Solaris, Irix and POSIX have a system call statvfs(2) that returns a
|
||||||
// struct statvfs, containing an unsigned long f_fsid
|
// struct statvfs, containing an unsigned long f_fsid
|
||||||
fsid = 0;
|
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
fn fsid(&self) -> u64 {
|
||||||
|
let f_fsid: &[u32; 2] = unsafe { transmute(&self.f_fsid) };
|
||||||
|
(f_fsid[0] as u64) << 32 | f_fsid[1] as u64
|
||||||
}
|
}
|
||||||
Ok(Statfs {
|
// FIXME:
|
||||||
f_type: buffer.f_type as i64,
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
f_bsize: buffer.f_bsize as i64,
|
fn fsid(&self) -> u64 {
|
||||||
f_blocks: buffer.f_blocks as u64,
|
0
|
||||||
f_bfree: buffer.f_bfree as u64,
|
}
|
||||||
f_bavail: buffer.f_bavail as u64,
|
|
||||||
f_files: buffer.f_files as u64,
|
#[cfg(target_os = "linux")]
|
||||||
f_ffree: buffer.f_ffree as u64,
|
fn namelen(&self) -> i64 {
|
||||||
f_fsid: fsid,
|
self.f_namelen as i64
|
||||||
f_namelen: buffer.f_namelen as i64,
|
}
|
||||||
f_frsize: buffer.f_frsize as i64,
|
#[cfg(target_os = "macos")]
|
||||||
})
|
fn namelen(&self) -> i64 {
|
||||||
|
1024
|
||||||
|
}
|
||||||
|
// FIXME:
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
|
fn namelen(&self) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn statfs<P: AsRef<Path>>(path: P) -> Result<Sstatfs, String>
|
||||||
|
where Vec<u8>: From<P>
|
||||||
|
{
|
||||||
|
match CString::new(path) {
|
||||||
|
Ok(p) => {
|
||||||
|
let mut buffer: Sstatfs = unsafe { mem::zeroed() };
|
||||||
|
unsafe {
|
||||||
|
match statfs_fn(p.as_ptr(), &mut buffer) {
|
||||||
|
0 => Ok(buffer),
|
||||||
|
_ => {
|
||||||
|
let errno = IOError::last_os_error().raw_os_error().unwrap_or(0);
|
||||||
|
Err(CString::from_raw(strerror(errno))
|
||||||
|
.into_string()
|
||||||
|
.unwrap_or("Unknown Error".to_owned()))
|
||||||
}
|
}
|
||||||
// TODO: Return explicit error message
|
|
||||||
_ => Err("Unknown error".to_owned()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue