获取已打开文件的fd

获取进程中已打开文件的文件描述符:

1、运行测试代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char const* argv[])
{
    int fd = open(argv[1], O_RDONLY);
    printf("pid:%d fd:%d\n", getpid(), fd);
    while (1);
    return 0;
}

image-20210528164051360

2、shell命令查看对应进程xxx打开的文件

lsof -p xxx
image-20210528164200052

ls -lh /proc/xxx/fd
image-20210528164451788可以看出,测试代码中打开文件的文件描述符为3。


3、代码编程,获取已打开文件的fd
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <libgen.h>
#include <string.h>

// 功能:获取进程已打开文件的fd
// 方法:解析/proc/xxx/fd目录下的链接文件,与目标文件名比对

int openfile_to_fd(const char *target, int pid) {
    char fdpath[32];
    sprintf(fdpath, "/proc/%d/fd", pid);

    DIR *dir = opendir(fdpath);
    if (dir == NULL) {
        printf("failed to open %s\n", fdpath);
        return -1;
    }

    int res = -1;
    struct dirent *ptr = NULL;
    while ( (ptr = readdir(dir)) != NULL) {
        if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
            continue;
        }
        else if (ptr->d_type == 10) {   // link file
            char linkpath[128], filepath[256];
            sprintf(linkpath, "%s/%s", fdpath, ptr->d_name);
            if (readlink(linkpath, filepath, sizeof(filepath)) < 0) {// 获取fd对应的文件路径
                printf("failed to readlink %s\n", linkpath);
                continue;
            }
            char *filename = basename(filepath);  // 解析路径,获取文件名 
            if (strcmp(filename, target) == 0) {
                sscanf(ptr->d_name, "%d", &res);  // /proc/xxx/fd下的链接文件名其实就是fd大小 
                break;                    
            } 
        }
    }
    closedir(dir);
    return res;
}


int main(int argc, char const* argv[])
{
    int fd1 = open(argv[1], O_RDONLY);
    int fd2 = open(argv[2], O_RDONLY);
    printf("pid:%d fd1:%d fd2:%d\n", getpid(), fd1, fd2);
    printf("openfile_to_fd:\n");
    printf("%s --> %d\n", argv[1], openfile_to_fd(argv[1], getpid()));
    printf("%s --> %d\n", argv[2], openfile_to_fd(argv[2], getpid()));
    return 0;
}

测试运行:
image-20210528180025402

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值