去年的作業系統課程設計,我做了一個基于linux到任務管理器。大部分需要到系統資訊都是從linux下
的一個僞檔案系統/proc中讀出的。大家都知道,此檔案系統隻存在記憶體當中,而不占用外存空間。它以檔案系統的方式為通路系統核心資料的操作提供接口。使用者和應用程式可以通過proc得到系統的資訊,并可以改變核心的某些參數。比如說我想看一下系統cpu的資訊,由于其資訊存于/proc/cpuinfo中,是以我們在終端用輸入如下指令:cat /proc/cpuinfo即可檢視要檢視到資訊,如果要使用其中到某項資訊則通過檔案操作讀出即可(當然要有一些處理)。其他像記憶體、程序等各項資訊都能按照這種操作得到。可唯獨在擷取檔案系統使用資訊時遇到了問題,先來看一下我們這個項目中要做出的一個類似頁面:

圖中所顯示的裝置、目錄等資訊既是我們希望從系統中得到到資訊,可/proc目錄中記錄檔案資訊的檔案partitions記錄的資訊于我們想要得到到資訊相差太遠,
[email protected]:~$ cat /proc/partitions
major minor #blocks name
8 0 244198584 sda
8 1 38427448 sda1
8 2 1 sda2
8 5 63898506 sda5
8 6 61440561 sda6
8 7 10241406 sda7
8 8 46138648 sda8
8 9 21430678 sda9
8 10 650601 sda10
8 11 1967931 sda11
看到了吧,裡面的資訊隻有這幾項,顯然不行。後來,我又以為所需到資訊可以從/dev下的檔案中查找,可那裡面到檔案都是不可讀的,我不停的在/proc下分析每個檔案内容,可都沒有我想要到内容,這個過程非常郁悶。可問題昨天晚上還是解決了,我通過系統調用實作的,在此,我将代碼公開,一是讓大家看一下,再一個就是如果哪位仁兄有能在檔案中直接讀出的方法,希望能告知一二,在此不勝感激。
下面這個程式是我和同學不斷讨論後設計出的一個非常巧妙的解決方案,具體代碼如下:
//讀出系統檔案系統的使用情況,并列印輸出
#include#include#include#include #include typedef struct {
char device[ 256 ]; //裝置名稱
char mntpnt[ 256 ]; //目錄
char type[256]; //類型
long blocks; //總容量(機關為:MB)
long bfree; //空閑容量(機關為:MB)
long bused; //已用容量(機關為:MB)
long available_disk; //可用容量
int bused_percent; //使用百分比(使用率乘以100)
} DiskInfo;
//所使用到到兩個系統調用結構體
//struct statfs {
// long f_type;
// long f_bsize;
// long f_blocks;
// long f_bfree;
// long f_bavail;
// long f_files;
// long f_ffree;
// fsid_t f_fsid;
// long f_namelen;
// };
// struct mntent {
// char *mnt_fsname;
// char *mnt_dir;
// char *mnt_type;
// char *mnt_opts;
// int mnt_freq;
// int mnt_passno;
// };
int main()
{
DiskInfo *disk_info;
struct statfs fs_info;
struct mntent *mnt_info;
FILE *fh;
float percent; //用于儲存設備使用百分比
long total_free=0; //用于存儲linux下尚餘磁盤空間
if ( ( fh = setmntent( "/etc/mtab", "r" ) ) == NULL )
{
printf( "Cannot open \'/etc/mtab\'!\n" );
return -1;
}
while ( ( mnt_info = getmntent( fh ) ) != NULL )
{
if ( statfs( mnt_info->mnt_dir, &fs_info ) < 0 )
{
continue;
}
if ( ( disk_info = (DiskInfo *)malloc( sizeof( DiskInfo ) ) ) == NULL )
{
continue;
}
//通過判斷找到要找的格式
if ( strcmp( mnt_info->mnt_type, "proc" ) &&
strcmp( mnt_info->mnt_type, "devfs" ) &&
strcmp( mnt_info->mnt_type, "usbfs" ) &&
strcmp( mnt_info->mnt_type, "sysfs" ) &&
strcmp( mnt_info->mnt_type, "tmpfs" ) &&
strcmp( mnt_info->mnt_type, "devpts" )&&
strcmp( mnt_info->mnt_type, "fusectl" ) &&
strcmp( mnt_info->mnt_type, "debugfs" )&&
strcmp( mnt_info->mnt_type, "binfmt_misc" )&&
strcmp( mnt_info->mnt_type, "fuse.gvfs-fuse-daemon" )&&
strcmp( mnt_info->mnt_type, "securityfs" )
)
{
if ( fs_info.f_blocks != 0 )
{
percent = ( ( (float)fs_info.f_blocks - (float)fs_info.f_bfree ) * 100.0/
(float)fs_info.f_blocks );
}
else
{
percent = 0;
}
}
else
{
continue;
}
//将系統中的各項資訊存于結構體相對應到變量中
strcpy(disk_info->type,mnt_info->mnt_type);
strcpy(disk_info->device,mnt_info->mnt_fsname);
strcpy(disk_info->mntpnt,mnt_info->mnt_dir);
long block_size=fs_info.f_bsize/1024;
disk_info->blocks = fs_info.f_blocks*block_size/1024;
disk_info->bfree = fs_info.f_bfree*block_size/1024;
disk_info->available_disk = fs_info.f_bavail*block_size/1024;
disk_info->bused = (fs_info.f_blocks - fs_info.f_bfree)*block_size/1024;
disk_info->bused_percent = (int)percent;
printf("塊大小:%dB\n",fs_info.f_bsize); //經測試每塊大小不一定一樣,根據分區格式确定的
//将各項資訊列印輸出
printf("裝置号:%s 目錄:%s 檔案類型:%s 總數:%ldMB 空閑:%ldMB 可用:%ldMB 已用:%ldMB 已用百分比:%d\n\n\n",
disk_info->device,disk_info->mntpnt,disk_info->type,disk_info->blocks,disk_info->bfree,
disk_info->available_disk,disk_info->bused,disk_info->bused_percent);
if((strcmp(disk_info->mntpnt,"/")==0)||(strcmp(disk_info->mntpnt,"/boot")==0))
{
total_free+=disk_info->available_disk;
}
};
printf("\nlinux下總的磁盤可用空間:%ldMB\n",total_free);
printf(" \nSuccess !\n");
return 0;
運作過程:
[email protected]:~/桌面/gcc$ gcc -c file2.c -o file2.o
[email protected]:~/桌面/gcc$ gcc file2.o -o file2
[email protected]:~/桌面/gcc$ ./file2
塊大小:4096B
裝置号:/dev/sda9 目錄:/ 檔案類型:ext4 總數:20599MB 空閑:17203MB 可用:16157MB 已用:3396MB 已用百分比:16
塊大小:4096B
裝置号:/dev/sda10 目錄:/boot 檔案類型:ext4 總數:625MB 空閑:579MB 可用:547MB 已用:45MB 已用百分比:7
塊大小:4096B
裝置号:/dev/sda1 目錄:/media/SYSTEM 檔案類型:fuseblk 總數:37526MB 空閑:21136MB 可用:21136MB 已用:16390MB 已用百分比:43
塊大小:32768B
裝置号:/dev/sda5 目錄:/media/SOURCE 檔案類型:vfat 總數:62385MB 空閑:35201MB 可用:35201MB 已用:27184MB 已用百分比:43
塊大小:4096B
裝置号:/dev/sda6 目錄:/media/Study 檔案類型:fuseblk 總數:60000MB 空閑:14746MB 可用:14746MB 已用:45254MB 已用百分比:75
塊大小:4096B
裝置号:/dev/sda7 目錄:/media/music 檔案類型:fuseblk 總數:10001MB 空閑:1891MB 可用:1891MB 已用:8109MB 已用百分比:81
linux下總的磁盤可用空間:16704MB
Success !