Chinaunix首页 | 论坛 | 博客
  • 博客访问: 148584
  • 博文数量: 33
  • 博客积分: 1494
  • 博客等级: 上尉
  • 技术积分: 325
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-24 21:50
文章分类

全部博文(33)

文章存档

2014年(1)

2013年(1)

2012年(2)

2011年(3)

2010年(26)

我的朋友

分类: LINUX

2010-06-26 12:45:07

    去年的操作系统课程设计,我做了一个基于linux到任务管理器。大部分需要到系统信息都是从linux下
的一个伪文件系统/proc中读出的。大家都知道,此文件系统只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。比如说我想看一下系统cpu的信息,由于其信息存于/proc/cpuinfo中,所以我们在终端用输入如下命令:cat /proc/cpuinfo即可查看要查看到信息,如果要使用其中到某项信息则通过文件操作读出即可(当然要有一些处理)。其他像内存、进程等各项信息都能按照这种操作得到。可唯独在获取文件系统使用信息时遇到了问题,先来看一下我们这个项目中要做出的一个类似页面:
图中所显示的设备、目录等信息既是我们希望从系统中得到到信息,可/proc目录中记录文件信息的文件partitions记录的信息于我们想要得到到信息相差太远,

changyan@changyan-fly:~$ 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;     /* type of file system (see below) */
//              long    f_bsize;    /* optimal transfer block size */
//              long    f_blocks;   /* total data blocks in file system */
//              long    f_bfree;    /* free blocks in fs */
//              long    f_bavail;   /* free blocks avail to non-superuser */
//              long    f_files;    /* total file nodes in file system */
//              long    f_ffree;    /* free file nodes in fs */
//              fsid_t  f_fsid;     /* file system id */
//              long    f_namelen;  /* maximum length of filenames */
//           };

//  struct mntent {
//               char *mnt_fsname;   /* name of mounted file system */
//               char *mnt_dir;      /* file system path prefix */
//               char *mnt_type;     /* mount type (see mntent.h) */
//               char *mnt_opts;     /* mount options (see mntent.h) */
//               int   mnt_freq;     /* dump frequency in days */
//               int   mnt_passno;   /* pass number on parallel fsck */
//           };

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;
运行过程:

changyan@changyan-fly:~/桌面/gcc$ gcc -c file2.c -o file2.o
changyan@changyan-fly:~/桌面/gcc$ gcc file2.o -o file2
changyan@changyan-fly:~/桌面/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 !

阅读(1973) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~