谈谈dlfcn.h、sys/mman.h和sys/stat.h

这篇来介绍三个比较好玩的头文件: dlfcn.h、sys/mman.h 和 sys/stat.h 。
1. dlfcn.h

定义:
dlfcn.h 是动态链接库函数库的头文件,它提供了一组用于在运行时动态加载和链接共享库(动态链接库或共享对象)的接口。

作用:
允许程序在运行时动态地加载库、获取库中的函数地址以及卸载库。

其中定义的函数:

    void *dlopen(const char *filename, int flag): 打开一个动态链接库。
    void *dlsym(void *restrict handle, const char *restrict name): 在动态链接库中查找符号(如函数或变量)。
    int dlclose(void *handle): 关闭一个动态链接库。
    char *dlerror(void): 返回上一个动态链接库错误的字符串描述。

具体用法:

#include <dlfcn.h>  
#include <stdio.h>  
  
int main() {  
    void *handle = dlopen("./libexample.so", RTLD_LAZY);  
    if (!handle) {  
        fprintf(stderr, "%s\n", dlerror());  
        return 1;  
    }  
      
    void (*foo)() = dlsym(handle, "foo");  
    if (!foo) {  
        fprintf(stderr, "%s\n", dlerror());  
        dlclose(handle);  
        return 1;  
    }  
      
    foo(); // 调用库中的函数  
      
    dlclose(handle);  
      
    return 0;  
}

2. sys/mman.h

定义:
sys/mman.h 是内存映射的头文件,它提供了一组用于内存映射文件或设备的接口。

作用:
允许程序将文件或其他对象映射到进程的地址空间中,从而可以直接通过指针访问这些对象的内容。

其中定义的函数:

    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset): 映射文件或设备到内存。
    int munmap(void *addr, size_t length): 取消内存映射。
    int mprotect(void *addr, size_t len, int prot): 改变已映射内存区域的保护属性。
    int msync(void *addr, size_t length, int flags): 同步映射区域与文件或设备的内容。

具体用法:

#include <sys/mman.h>  
#include <fcntl.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
  
int main() {  
    int fd = open("example.txt", O_RDONLY);  
    if (fd == -1) {  
        perror("open");  
        return 1;  
    }  
      
    struct stat sb;  
    if (fstat(fd, &sb) == -1) {  
        perror("fstat");  
        return 1;  
    }  
      
    char *map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);  
    if (map == MAP_FAILED) {  
        perror("mmap");  
        return 1;  
    }  
      
    printf("%s\n", map);  
      
    if (munmap(map, sb.st_size) == -1) {  
        perror("munmap");  
        return 1;  
    }  
      
    close(fd);  
      
    return 0;  
}

3. sys/stat.h

定义:
sys/stat.h 是文件状态的头文件,它提供了一组用于获取和修改文件或文件系统状态信息的接口。

作用:
允许程序查询文件或目录的状态信息,如大小、权限、时间戳等。

其中定义的函数:

    int stat(const char *path, struct stat *buf): 获取文件状态。
    int fstat(int fd, struct stat *buf): 获取已打开文件的状态。
    int lstat(const char *path, struct stat *buf): 获取符号链接本身的状态,而不是链接指向的文件的状态。

结构体 struct stat:

struct stat 是一个结构体,用于存储文件或文件系统的状态信息。其定义在 sys/stat.h 中,具体的字段可能会因操作系统和文件系统类型而异,但通常会包含以下一些字段:

    dev_t st_dev: 文件所在设备的标识符。
    ino_t st_ino: 文件的 i-node 号。
    mode_t st_mode: 文件类型和权限。
    nlink_t st_nlink: 文件的硬链接数。
    uid_t st_uid: 文件所有者的用户 ID。
    gid_t st_gid: 文件所有者的组 ID。
    dev_t st_rdev: 如果该文件是一个特殊设备文件,则此字段表示设备类型。
    off_t st_size: 文件的大小(以字节为单位)。
    blksize_t st_blksize: 文件系统的最佳 I/O 块大小。
    blkcnt_t st_blocks: 文件占用的磁盘块数。
    time_t st_atime: 文件的最后访问时间。
    time_t st_mtime: 文件的最后修改时间。
    time_t st_ctime: 文件的最后状态改变时间(例如,权限或所有权改变)。

具体用法:

#include <sys/stat.h>  
#include <stdio.h>  
  
int main() {  
    struct stat buf;  
    if (stat("example.txt", &buf) == -1) {  
        perror("stat");  
        return 1;  
    }  
      
    printf("Size: %lld bytes\n", (long long)buf.st_size);  
    printf("Last modified: %s", ctime(&buf.st_mtime));  
      
    // 检查文件类型  
    if (S_ISREG(buf.st_mode)) {  
        printf("example.txt is a regular file.\n");  
    } else if (S_ISDIR(buf.st_mode)) {  
        printf("example.txt is a directory.\n");  
    }  
    // ... 其他文件类型检查  
      
    return 0;  
}

在这个例子中,我们使用 stat 函数获取了 example.txt 文件的状态信息,并打印了文件的大小和最后修改时间。我们还检查了文件的类型,看它是否是一个常规文件或一个目录。

sys/stat.h 还定义了一些宏,如 S_ISREG, S_ISDIR 等,用于检查文件类型。这些宏与 st_mode 字段结合使用,可以方便地判断文件是常规文件、目录、符号链接等。

简单来说,sys/mman.h, sys/stat.h 和 dlfcn.h 分别提供了内存映射、文件状态查询和动态链接库加载的接口,使得程序可以在运行时进行更复杂的操作和管理。

  • 36
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值