在使用setmntent、getmntent、endmntent这三个函数之前,先对这三个函数的功能做一个详细的介绍,在使用这三个函数得包含头文件**#include<stdio.h>和#include <mntent.h>。**
setmntent函数
(1)setmntent:打开文件系统描述文件的文件名,并且返回可以被使用的文件指针getmntent()。
mntent 结构是在 <mntent.h> 中定义,如下:
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 */
};
其函数原型为:
FILE * setmntent(const char * filename ,const char * type );
参数:filename 要打开的文件名字
type 表示打开文件的方式(r:只读 w:只写 r+:读写)等。
返回值:函数成功返回指向打开文件的文件指针FILE;失败返回NULL。
getmntent函数
(2)getmntent:函数读取文件系统的下一行来自文件流的描述文件并返回指向结构的指针(即循环读取文件)
其函数原型:
struct mntent * getmntent(FILE * fp );
参数:fp setmntent函数中返回的文件指针,即将要进行读写的文件指针。
返回值:struct mntent 结构体,后面将会详细介绍该结构体的中变量和对应的作用。
endmntent函数
(3)endmntent:关闭流和与其相关联的文件系统描述文件。
使用例子:
#include <mntent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
struct mntent *m;
FILE *f = NULL;
f = setmntent("/etc/fstab","r"); //打开文件系统描述文件的文件名
if(!f)
printf("error:%s\n",strerror(errno));
while ((m = getmntent(f))) //读取下一行
printf("Drive %s, name %s,type %s,opt %s\n", m->mnt_dir, m->mnt_fsname,m->mnt_type,m->mnt_opts );
endmntent(f); //关闭文件系统描述文件
return 0;
}
值得注意的是getmntent是不可重入函数,如果一个程序中多个地方同时调用getmntent,可能会得不到想要的结果,那么可以用getmntent_r函数来替代, 原型如下:
struct mntent *getmntent_r(FILE *fp, struct mntent *mntbuf, char *buf, int buflen);
getmntent_r会把数据存放在用户提供的内存中(mntbuf),而不是由系统管理。
addmntent(FILE *fp, const struct mntent *mnt) 可以在fp指向的文件追加最后一行数据。
statfs函数说明
函数:
statfs
功能描述:
查询文件系统相关的信息。
用法:
#include <sys/vfs.h> /* 或者 <sys/statfs.h> */
int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
参数:
path: 需要查询信息的文件系统的文件路径名。
fd: 需要查询信息的文件系统的文件描述词。
buf:以下结构体的指针变量,用于储存文件系统相关的信息
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; /* 文件名的最大长度 */
};
返回说明:
成功执行时,返回0。失败返回-1,errno被设为以下的某个值
EACCES: (statfs())文件或路径名中包含的目录不可访问
EBADF : (fstatfs()) 文件描述词无效
EFAULT: 内存地址无效
EINTR : 操作由信号中断
EIO : 读写出错
ELOOP : (statfs())解释路径名过程中存在太多的符号连接
ENAMETOOLONG:(statfs()) 路径名太长
ENOENT:(statfs()) 文件不存在
ENOMEM: 核心内存不足
ENOSYS: 文件系统不支持调用
ENOTDIR:(statfs())路径名中当作目录的组件并非目录
EOVERFLOW:信息溢出
例子:
//说明:pDisk 路径名 如“/home”
int DH_GetDiskfreeSpacePercent(char *pDisk){
long long freespace = 0;
struct statfs disk_statfs;
long long totalspace = 0;
float freeSpacePercent = 0 ;
if( statfs(pDisk, &disk_statfs) >= 0 ){
freespace = (((long long)disk_statfs.f_bsize * (long long)disk_statfs.f_bfree)/(long long)1024);
totalspace = (((long long)disk_statfs.f_bsize * (long long)disk_statfs.f_blocks) /(long long)1024);
}
freeSpacePercent = ((float)freespace/(float)totalspace)*100 ;
return freeSpacePercent ;
}
linux df命令实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/statfs.h>
static int ok = EXIT_SUCCESS;
static void printsize(long long n)
{
char unit = 'K';
n /= 1024;
if (n > 1024) {
n /= 1024;
unit = 'M';
}
if (n > 1024) {
n /= 1024;
unit = 'G';
}
printf("%4lld%c", n, unit);
}
static void df(char *s, int always) {
struct statfs st;
if (statfs(s, &st) < 0) {
fprintf(stderr, "%s: %s\n", s, strerror(errno));
ok = EXIT_FAILURE;
} else {
if (st.f_blocks == 0 && !always)
return;
printf("%-20s ", s);
printf("%-20s ", s);
printsize((long long)st.f_blocks * (long long)st.f_bsize);
printf(" ");
printsize((long long)(st.f_blocks - (long long)st.f_bfree) * st.f_bsize);
printf(" ");
printsize((long long)st.f_bfree * (long long)st.f_bsize);
printf(" %d\n", (int) st.f_bsize);
}
}
int main(int argc, char *argv[]) {
printf("Filesystem Size Used Free Blksize\n");
if (argc == 1) {
char s[2000];
FILE *f = fopen("/proc/mounts", "r");
while (fgets(s, 2000, f)) {
char *c, *e = s;
for (c = s; *c; c++) {
if (*c == ' ') {
e = c + 1;
break;
}
}
for (c = e; *c; c++) {
if (*c == ' ') {
*c = '\0';
break;
}
}
df(e, 0);
}
fclose(f);
} else {
printf(" NO argv\n");
int i;
for (i = 1; i < argc; i++) {
df(argv[i], 1);
}
}
exit(ok);
}