linux中getmntent、setmntent 、endmntent 函数的详细用法

在使用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);
}
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
setmntent函数是一个C库函数,用于打开和操作mntent结构的文件。mntent结构是用于描述挂载点信息的结构体。setmntent函数的原型如下: ```c #include <mntent.h> FILE *setmntent(const char *filename, const char *type); ``` setmntent函数接受两个参数:filename和type。filename是一个字符串,表示要打开的文件的路径。type是一个字符串,表示要执行的操作类型。setmntent函数返回一个指向mntent结构的文件指针。 以下是一个使用setmntent函数的示例: ```python import ctypes # 定义mntent结构体 class mntent(ctypes.Structure): _fields_ = [ ("mnt_fsname", ctypes.c_char_p), ("mnt_dir", ctypes.c_char_p), ("mnt_type", ctypes.c_char_p), ("mnt_opts", ctypes.c_char_p), ("mnt_freq", ctypes.c_int), ("mnt_passno", ctypes.c_int) ] # 加载libc库 libc = ctypes.CDLL("libc.so.6") # 打开mntent结构的文件 mnt_file = libc.setmntent("/etc/mtab", "r") # 读取mntent结构的文件内容 mnt_entry = mntent() while libc.getmntent_r(mnt_file, ctypes.byref(mnt_entry), ctypes.byref(mnt_entry)) is not None: print("Filesystem: ", mnt_entry.mnt_fsname.decode()) print("Mount point: ", mnt_entry.mnt_dir.decode()) print("Type: ", mnt_entry.mnt_type.decode()) print("Options: ", mnt_entry.mnt_opts.decode()) print("Frequency: ", mnt_entry.mnt_freq) print("Pass number: ", mnt_entry.mnt_passno) # 关闭mntent结构的文件 libc.endmntent(mnt_file) ``` 这个示例演示了如何使用setmntent函数打开并读取mntent结构的文件。它打开了"/etc/mtab"文件,并逐行读取文件内容,然后打印出每个挂载点的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值