首页 > 代码库 > 一次 Rust 和C语言的混搭
一次 Rust 和C语言的混搭
存在内存泄露
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; }
一次 Rust 和C语言的混搭
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。