Wednesday, March 16, 2022

[SOLVED] Calculate max open files in Linux

Issue

I wrote a simple program to test the max open files per process in Linux. Here it is.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() {

    FILE* fp = NULL;
    int count = 0;
    
    while (1) {
        fp = fopen("tmp", "w");
        if (fp == NULL) {
            perror("fopen()");
            break;
        }
        count++;
    }
    printf("count:%d\n", count);
    return 0;    
}

The output of the program on my computer is

$ ./maxfopen
fopen(): Too many open files
count:1020

I used ulimit -a to check the max open files on my computer, and the result is 1024. As expected, apart from stdio, stdout, stderr, there should have been 1021 files, which are available to open, but the result is 1020 on my computer. What is wrong? Is there a fourth default open file stream? How can I detect it?


Solution

you can check the opened files with strace:

$ strace ./maxfopen 2>&1 | grep AT_FDCWD | wc -l
1024
$ strace ./maxfopen 2>&1 | grep AT_FDCWD                                                                                                                                                                              
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3                                                                                                                                                      
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3                                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4                                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5    
...
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1018
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1019
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1020
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1021
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1022
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1023
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 EMFILE (Too many open files)

The sum of all files should be (1021 + stdin + stdout + stderr). If it is not is because other file is being opened before main function which can be checked with strace as well.

Other files opened (and closed) are /etc/ld.so.cache and /lib/x86_64-linux-gnu/libc.so.6 (the dynamic linker to run the program)

you can verify it looking the file descriptors in: /proc/<pid>/fd



Answered By - sinkmanu
Answer Checked By - Cary Denson (WPSolving Admin)