Given a filedescriptor, how can you tell that it is valid and has been opened?
In the attached simple program, a file and a directory are opened (with CLOEXEC set). I then call fcntl(fd, F_GETFD) on the range fd = [3..15]. fd = {3,4} correspond to the open file and directory. Why don't I get fcntl(4): [EBADF] fildes is not a valid open file descriptor. for fd = [5..15], but only for some of them? $ ./cloexec fd 3 testfile.txt flags = 0x1 (0x1) fd 4 testdir flags = 0x1 (0x1) fd 3's flags = 0x1 (0x1) fd 4's flags = 0x1 (0x1) fd 5's flags = 0x0 (0x0) fd 6's flags = 0x0 (0x0) fd 7's flags = 0x0 (0x0) fd 8's flags = 0x0 (0x0) fd 9's flags = 0x0 (0x0) fd 10's flags = 0x0 (0x0) cloexec: fcntl 11: Bad file descriptor cloexec: fcntl 12: Bad file descriptor fd 13's flags = 0x0 (0x0) fd 14's flags = 0x0 (0x0) cloexec: fcntl 15: Bad file descriptor The motivation for the question is https://bugs.freedesktop.org/show_bug.cgi?id=83899 Cheers, Patrick
#include <err.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> void flagtest(char *fname) { int fd, flags; fd = open(fname, O_RDONLY | O_CLOEXEC); if (fd == -1) err(1, "open %s", fname); flags = fcntl(fd, F_GETFD); if (flags == -1) err(1, "fcntl %s", fname); printf("fd %2d %s flags = 0x%x (0x%x)\n", fd, fname, flags, flags & FD_CLOEXEC); } void emptytest() { int i, flags; /* pick a number(s), any number... */ for (i = 3; i <= 15; ++i) { flags = fcntl(i, F_GETFD); if (flags == -1) warn("fcntl %d", i); else printf("fd %2d's flags = 0x%x (0x%x)\n", i, flags, flags & FD_CLOEXEC); } } int main() { flagtest("testfile.txt"); flagtest("testdir"); emptytest(); return 0; }