<!-- lang: cpp -->
extern crate libc;
use libc::size_t;
use libc::{FILE,c_char};
use std::string;
#[repr(C)]
pub struct mntent {
mnt_fsname :*mut c_char, /* 挂载的文件系统的名字 */
mnt_dir :*mut c_char, /* 挂载点 */
mnt_type :*mut c_char, /* 文件系统类型:ufs、nfs 等 */
mnt_opts :*mut c_char, /* 选项,以逗号为分隔符 */
mnt_freq : size_t, /* Dump 的频率(以天为单位) */
mnt_passno :size_t, /* fsck检查的次序 */
}
#[link(name = "diskstat", kind="static")]
extern "C" {
fn getdisk() -> *const c_char;
pub fn setmntent(filename : *const c_char,
ttype : *const c_char ) -> FILE;
pub fn getmntent(filep :FILE) -> mntent;
pub fn endmntent(filep: FILE) -> size_t;
}
fn main(){
let mut mnt = unsafe { ( setmntent ("/etc/mtab".to_c_str().as_ptr(), "r".to_c_str().as_ptr())) };
let mut disk_info = unsafe { string::raw::from_buf (getdisk() as *const u8 ) };
println!("{}", disk_info);
}
<!-- lang: cpp -->
// gcc -c diskstat.c -o diskstat.o -fPIC
// ar -r libdiskstat.a diskstat.o
#include <stdio.h>
#include <mntent.h>
#include <string.h>
#include <sys/vfs.h>
static const unsigned long long G = 1024*1024*1024ULL;
static const unsigned long long M = 1024*1024;
static const unsigned long long K = 1024;
static char str[20];
char* kscale(unsigned long b, unsigned long bs)
{
unsigned long long size = b * (unsigned long long)bs;
if (size > G)
{
sprintf(str, "%0.2f GB", size/(G*1.0));
return str;
}
else if (size > M)
{
sprintf(str, "%0.2f MB", size/(1.0*M));
return str;
}
else if (size > K)
{
sprintf(str, "%0.2f K", size/(1.0*K));
return str;
}
else
{
sprintf(str, "%0.2f B", size*1.0);
return str;
}
}
char* getdisk()
{
FILE* mount_table;
struct mntent *mount_entry;
struct statfs s;
unsigned long blocks_used;
unsigned blocks_percent_used;
const char *disp_units_hdr = NULL;
mount_table = NULL;
mount_table = setmntent("/etc/mtab", "r");
if (!mount_table)
{
fprintf(stderr, "set mount entry error\n");
return -1;
}
disp_units_hdr = " Size";
//printf("Filesystem %-15sUsed Available %s Mounted on\n",
// disp_units_hdr, "Use%");
char *disk_info = (char *)malloc(10000*sizeof(char));
strcpy(disk_info, "["); //a
// *disk_info = "[" ;
char *z = (char *)malloc(1000*sizeof(char));
while (1) {
const char *device;
const char *mount_point;
const char *fs_type;
if (mount_table) {
mount_entry = getmntent(mount_table);
if ( !mount_entry ) {
endmntent(mount_table);
break;
}
}
else
continue;
device = mount_entry->mnt_fsname;
mount_point = mount_entry->mnt_dir;
fs_type = mount_entry->mnt_type;
// fprintf(stderr, "error mount info: device=%s mountpoint=%s\n", device, mount_point);
if (statfs(mount_point, &s) != 0)
{
fprintf(stderr, "statfs failed!\n");
continue;
}
if ((s.f_blocks > 0) || !mount_table )
{
blocks_used = s.f_blocks - s.f_bfree;
blocks_percent_used = 0;
if (blocks_used + s.f_bavail)
{
blocks_percent_used = (blocks_used * 100ULL
+ (blocks_used + s.f_bavail)/2
) / (blocks_used + s.f_bavail);
}
if (strcmp(device, "rootfs") == 0)
continue;
// if (printf("hello dksks \n%-20s" + 1, device) > 20)
// printf("\n%-20s", "");
char s1[20];
char s2[20];
char s3[20];
strcpy(s1, kscale(s.f_blocks, s.f_bsize));
strcpy(s2, kscale(s.f_blocks - s.f_bfree, s.f_bsize));
strcpy(s3, kscale(s.f_bavail, s.f_bsize));
sprintf (z, "{\"device\":\"%s\",\"fs_type\":\"%s\",\"mount_point\":\"%s\",\"size\":\"%s\",\"used\":%s,\"available\":\"%s\",\"use_percent\":\"%3u%%\"},",
device,
fs_type,
mount_point,
s1,
s2,
s3,
blocks_percent_used
);
strncat(disk_info,z , 1000);
}
}
strncat(disk_info, "]", 1);
return disk_info;
}