查找进程linux的打开文件描述符(C代码)?

查找进程linux的打开文件描述符(C代码)?,c,linux,process,file-descriptor,C,Linux,Process,File Descriptor,我想找到linux中为进程打开的所有FD 我可以用glib库函数来完成吗?如果您可以通过pid识别流程,您只需 ls -l /proc/<pid>/fd | wc - l ls-l/proc//fd | wc-l 在C语言中,您可以通过管道传输所有内容并重用输出,或者您可以自己在上述目录中对文件进行计数(计数方法,例如,此处)如果您的意思是如何从流程中以编程方式进行计数,那么正常(如果有点可怕)的方法是循环所有可能的描述符(使用getrlimit()读取RLIMIT\u NOFI

我想找到linux中为进程打开的所有FD


我可以用glib库函数来完成吗?

如果您可以通过pid识别流程,您只需

ls -l /proc/<pid>/fd | wc - l
ls-l/proc//fd | wc-l

在C语言中,您可以通过管道传输所有内容并重用输出,或者您可以自己在上述目录中对文件进行计数(计数方法,例如,此处)

如果您的意思是如何从流程中以编程方式进行计数,那么正常(如果有点可怕)的方法是循环所有可能的描述符(使用
getrlimit()
读取
RLIMIT\u NOFILE
查找范围)对每个文件调用类似于
fcntl(fd,F\u GETFD,0)
的命令,并检查EBADF响应以查看哪些响应未打开


如果您的意思是想从shell中找出进程打开了哪些文件,那么
lsof-p
就是您想要的安装了
/proc
文件系统。这意味着最简单的方法是获取
/proc/self/fd
的内容列表;其中的每个文件都以fd命名。(当然,使用
g_dir_open
g_dir_read_name
g_dir_close
来进行列表。)


以其他方式获取信息有点笨拙(例如,没有有用的POSIX API;这是一个未标准化的领域)。

fstat命令列出了系统的所有运行进程及其打开的描述符,此外,它还列出了描述符的类型(文件、套接字、管道等)并试图给出描述符正在读取或写入的内容的提示,例如文件系统和文件系统上的inode编号这里是我以前使用的一些代码,我不知道/proc/self(thx Donal!),但这种方式可能更通用。我在顶部包含了所有函数所需的include

#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/resource.h>

#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif

/* implementation of Donal Fellows method */ 
int get_num_fds()
{
     int fd_count;
     char buf[64];
     struct dirent *dp;

     snprintf(buf, 64, "/proc/%i/fd/", getpid());

     fd_count = 0;
     DIR *dir = opendir(buf);
     while ((dp = readdir(dir)) != NULL) {
          fd_count++;
     }
     closedir(dir);
     return fd_count;
}

我希望回答你所提出的任何问题,如果你想知道,我实际上是在这里寻找答案,OP问的问题,读了答案后,记得我已经写了几年前的代码。享受。

< P>有时C++是一种选择,DoAN的解决方案使用Booo::文件系统:< /P>
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <unistd.h>

namespace fs = boost::filesystem;

int main()
{
    std::string path = "/proc/" + std::to_string(::getpid()) + "/fd/";
    unsigned count = std::distance(fs::directory_iterator(path),
                                   fs::directory_iterator());
    std::cout << "Number of opened FDs: " << count << std::endl;
}
#包括
#包括
#包括
#包括
名称空间fs=boost::filesystem;
int main()
{
std::string path=“/proc/”+std::to_string(::getpid())+“/fd/”;
无符号计数=std::distance(fs::directory\u迭代器(path),
fs::directory_iterator());

std::cout要为另一个进程列出它们,请改为列出目录
/proc/PID/fd
(其中PID是所讨论进程的进程id)。如果您不是root用户,您只能在某些进程中看到它们。使用/proc/*/pid当然是linux特有的,而且根本不可移植,但如果这不是问题,那么它应该可以正常工作。@Tom:这个问题被标记为
linux
…需要解决的问题有一个小陷阱:
/proc/self/fd
目录本身扫描时也算作打开的文件描述符。@C2H5OH是的。但是替代方法很可怕或者同样有问题(例如,运行子进程进行探测将打开更多的FD)。我看到有相当多的进程具有开放的FDs 0、1、2和255。获得252个失败的系统调用并不好……这一切都要看情况而定-显然,你不想在性能关键的代码段中这样做,但除此之外,这不是一个大问题。无论如何,在现代linux系统上,限制更可能类似2048。RLIMIT_NOFILE只告诉您新创建的文件描述符的最大值,而不是当前打开的文件描述符的限制,因此您无法使用getrlimit来发现文件描述符编号的上限。是的,我现在正试图作为沙箱代码的一部分来做这件事。我想运行一些任意设置代码,然后列出所有打开的文件句柄并关闭然后使用StRealEnter来防止任何新的文件句柄被打开。请注意,在FD表中,PthuUTILILFDYFALID不能使用空洞。请考虑下面的情况:<代码> INTFD=OPEN(…);//FD=3 < /COD> <代码> FD= OPEN(…);//FD=4 < /代码>代码>关闭(4)。
该功能将无法到达fd=4@kfir–pth_util_fd_valid仅报告给定文件句柄的有效性,它不包含循环。第二个代码示例需要包含sys/select.h来定义fd_SETSIZE。与组合路径名相比,扫描
/proc/self/fd
或稍微便携的
/dev/fd
更容易基于C中的当前进程ID.OP程序,而不是C++。这个答案是不相关的。
char *fcntl_flags(int flags)
{
    static char output[128];
    *output = 0;

    if (flags & O_RDONLY)
        strcat(output, "O_RDONLY ");
    if (flags & O_WRONLY)
        strcat(output, "O_WRONLY ");
    if (flags & O_RDWR)
        strcat(output, "O_RDWR ");
    if (flags & O_CREAT)
        strcat(output, "O_CREAT ");
    if (flags & O_EXCL)
        strcat(output, "O_EXCL ");
    if (flags & O_NOCTTY)
        strcat(output, "O_NOCTTY ");
    if (flags & O_TRUNC)
        strcat(output, "O_TRUNC ");
    if (flags & O_APPEND)
        strcat(output, "O_APPEND ");
    if (flags & O_NONBLOCK)
        strcat(output, "O_NONBLOCK ");
    if (flags & O_SYNC)
        strcat(output, "O_SYNC ");
    if (flags & O_ASYNC)
        strcat(output, "O_ASYNC ");

    return output;
}

char *fd_info(int fd)
{
    if (fd < 0 || fd >= FD_SETSIZE)
        return FALSE;
    // if (fcntl(fd, F_GETFL) == -1 && errno == EBADF)
    int rv = fcntl(fd, F_GETFL);
    return (rv == -1) ? strerror(errno) : fcntl_flags(rv);
}
#include <sys/time.h>
#include <sys/resource.h>

rlim_t get_rlimit_files()
{
    struct rlimit rlim;
    getrlimit(RLIMIT_NOFILE, &rlim);
    return rlim.rlim_cur;
}   
0:     0                  O_RDWR  dup() ok
1:     0                O_WRONLY  dup() ok
2:     0                  O_RDWR  dup() ok
3:     0              O_NONBLOCK  dup() ok
4:     0     O_WRONLY O_NONBLOCK  dup() ok
5:    -1      Bad file descriptor Bad file descriptor
6:    -1      Bad file descriptor Bad file descriptor
7:    -1      Bad file descriptor Bad file descriptor
8:    -1      Bad file descriptor Bad file descriptor
9:    -1      Bad file descriptor Bad file descriptor
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <unistd.h>

namespace fs = boost::filesystem;

int main()
{
    std::string path = "/proc/" + std::to_string(::getpid()) + "/fd/";
    unsigned count = std::distance(fs::directory_iterator(path),
                                   fs::directory_iterator());
    std::cout << "Number of opened FDs: " << count << std::endl;
}