fcntl(), F_GETFD meaning in UNIX

感情迁移 提交于 2021-01-28 19:10:14

问题


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 ?


回答1:


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.




回答2:


Inspecting the implementation of do_fcntl in the Linux kernel, we can see that:

static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        struct file *filp)
{
    long err = -EINVAL;
    switch (cmd) {
    ...
    case F_GETFD:
        err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
        break;
    ...
    }
    return err;
}

do_fcntl(F_GETFD) may return only FD_CLOEXEC or 0.

The syscall definition from here can return -EBADF in case of a bad file descriptor or the file descriptor was opened with O_PATH.

Judging from that, the fcntl(F_GETFD) will return only -1 with errno set to -9 (-EBADF), or return 0 or 1 (FD_CLOEXEC) on Linux 4.20. So the fcntl(F_GETFD) will return -1 in case of a bad file descriptor or file descriptor opened with O_PATH. Note that for other kernels it may be different and note that it can change over time.



来源:https://stackoverflow.com/questions/54656482/fcntl-f-getfd-meaning-in-unix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!