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;
}

Reply via email to