18

Is there a C API to get the:

  1. Current used file descriptors system wide
  2. Current used file descriptors of the current process
Mat
  • 202,337
  • 40
  • 393
  • 406
Vivek Goel
  • 22,942
  • 29
  • 114
  • 186

5 Answers5

22

For the current process count, you can use getrlimit to get the file descriptor limit, then iterate over all integers from 0 to that limit and try calling fcntl with the F_GETFD command. It will succeed only on the file descriptors which are actually open, letting you count them.

Edit: I now have a better way to do it. After getting the rlimit, make a large array of struct pollfd (as large as the limit if possible; otherwise you can break it down into multiple runs/calls) with each fd in the range and the events member set to 0. Call poll on the array with 0 timeout, and look for the POLLNVAL flag in the revents for each member. This will tell you which among a potentially-huge set of fds are invalid with a single syscall, rather than one syscall per fd.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
15

Since you say you are on Linux, you can open the folder /proc/self/fd/ which should contain symbolic links to all open file descriptors.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
13

You can read /proc/sys/fs/file-nr to find the total number of allocated and free file system handles as well as the maximum allowed.

[root@box proc]# cat /proc/sys/fs/file-nr
3853    908     53182
|       |       |
|       |       |
|       |       max: maximum open file descriptors
|       free: total free allocated file descriptors
allocated: total allocated file descriptors since boot

To calculate the number that are currently in use, just do allocated - free. You could also calculate a percentage of used descriptors by doing ((allocated - free) / max) * 100

As for per-process, I'm not sure of any programmatic way you can do it.

Here's a tutorial on how to do it with lsof anyway: http://linuxshellaccount.blogspot.com/2008/06/finding-number-of-open-file-descriptors.html

Polynomial
  • 27,674
  • 12
  • 80
  • 107
  • I believe these are actually counts of open file descriptions, not file descriptors, i.e. the value is unaffected by `dup` or `fork`. – R.. GitHub STOP HELPING ICE Nov 02 '11 at 07:12
  • `allocated` tells you the number allocated since boot, `free` tells you the number of those that have been freed. `allocated - free` = the number that are currently open on the system. If you just want to know how many file descriptors have been allocated on the system, just look at `allocated`. Or am I thinking of something different? – Polynomial Nov 02 '11 at 07:15
  • File descriptors and open file descriptions are subtly different. Each open file description can have many file descriptors referring to it (created by `dup`, `dup2`, `fcntl/F_DUPFD`, or inheritance across `fork`) all of which share properties like the current offset in the file, flags like append mode, etc., and the open file description is not closed until *all* file descriptors referring to it are closed. – R.. GitHub STOP HELPING ICE Nov 02 '11 at 07:19
  • @Polynomial on my system I get following o/p cat /proc/sys/fs/file-nr 8064 0 297986 Does it mean I have 8064 used file descriptor – Vivek Goel Nov 02 '11 at 07:31
  • @R.. - Should a file descriptor that is being referred to "somewhere" not still count as open? I'm not familiar with the internals of it, but my definition of "open" (as a developer that mainly works with GC-based languages) is that something is actively referring to it. – Polynomial Nov 02 '11 at 08:48
  • @VivekGoel - As R.. pointed out, it means that 8064 open file **descriptions** are open. There may be multiple file **descriptors** open for those **descriptions**. Note the difference between descriptions and descriptors. It's a subtle difference, but it's important. – Polynomial Nov 02 '11 at 08:51
2

To complement on Some programmer dude's answer, the most efficient (both in terms of space and time) way of getting the number of open fds for the current process is to walk /proc/self/fds where available.

This should do it:

#include <dirent.h>
#include <stddef.h>
#include <sys/types.h>

int count_open_fds(void) {
    DIR *dp = opendir("/proc/self/fd");
    struct dirent *de;
    int count = -3; // '.', '..', dp

    if (dp == NULL)
        return -1;

    while ((de = readdir(dp)) != NULL)
        count++;

    (void)closedir(dp);

    return count;
}
FelipeFR
  • 61
  • 7
-1

I'm not positive about file descriptors, but you can easily check <stdio.h> files.

In stdio.h, __sF, is a file array that stores every FILE. (googling __sF shows many stdios with a matching keyword).

If a FILE's flags are empty, the file is not in use. Therefore, we can simply walk through __sF, checking the flag of each FILE in the array.

#include <stdio.h>

int getOpenFileCount(void)
{
    int fileCount;

    for (fileCount = 0; __sF[fileCount]._flags != 0; fileCount++)
        continue;

    return fileCount;
}
MD XF
  • 7,860
  • 7
  • 40
  • 71