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?
CodePudding user response:
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
CodePudding user response:
It could be used by your shell or the program for some other purpose.
To find out exactly what's the "missing" fd is being used for, you can simply
wait before exit and inspect /proc/<pid>/fd
.
For example, add a getchar()
and check /proc/<pid>/fd
in another terminal.
#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;
}
printf("%d\n", fileno(fp)); // shows each fd number
count ;
}
getchar(); // just to keep it running
printf("count:%d\n", count);
return 0;
}
Since the fd
's aren't closed, they should be pointing to the files/devices they refer to.
fileno(fp)
(see the code above) will also give the fd number of the file descriptor. So you can check what's the "missing" fd using that too.