Search code examples
bashunixfile-descriptor

fcntl(), F_GETFD meaning in UNIX


What is the meaning of F_GETFD in fcntl() function in unix ?, From what I understand it should return -1 if there is no file descriptor in the position specified.. If that's true, when would it happen ? when doing close to a file descriptor in that posstion, F_GETFD doesn't return -1 either..

This is a part of a program using F_GETFD and it will not return -1 if I close the x fd (thid fd entered 0 in the fd table since we closed 0 beforehand and did dup(x)):

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>


void try(){
printf("got_sig\n");
}
int main(int argc, char *argv[]){
int x, stdout=1;
signal(SIGUSR1,&try);
x = open("t1.txt",O_RDWR|O_CREAT, 0666);
close(0);
dup(x);
close(x);
if (fcntl(0,F_GETFD)==-1)
printf("false\n");
kill(getpid(),SIGUSR1);
//close(x);
write(stdout,"BYE\n",4);
exit(0);
}

When will F_GETFD return -1 ?


Solution

  • From the man page of fcntl():

    File descriptor flags
    The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is set, the file descriptor will automatically be closed during a successful execve(2).

    F_GETFD (void)
    Return (as the function result) the file descriptor flags; arg is ignored.

    (Or see the POSIX standard text for fctnl(), if you care.)

    So, fnctl(fd, F_GETFD) tells you if the file descriptor stays open over an execve() or not.

    The usual error cases for fcntl() apply, so it would e.g. return -1 and set errno to EBADF if the fd you gave wasn't open. In your code, you called fcntl() on fd 0, which holds the dup'ed copy of x, and so is open. fcntl() would return -1 for the fd x, though, that's the one you explicitly closed.