fcntl(),F_GETFD在UNIX中的含义

问题描述 投票:0回答:2

在unix中fcntl()函数中F_GETFD的含义是什么?据我所知,如果在指定的位置没有文件描述符,它应该返回-1。如果这是真的,什么时候会发生?当在该情况下接近文件描述符时,F_GETFD也不返回-1。

这是使用F_GETFD的程序的一部分,如果我关闭x fd它将不会返回-1(因为我们事先关闭了0并且执行了dup(x),所以fd表中的fd输入为0):

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

F_GETFD何时返回-1?

bash unix file-descriptor
2个回答
1
投票

来自man page of fcntl()

文件描述符标志 以下命令处理与文件描述符关联的标志。目前,只定义了一个这样的标志:FD_CLOEXEC,close-on-exec标志。如果设置了FD_CLOEXEC位,则在成功执行期间将自动关闭文件描述符(2)。

F_GETFD(无效) 返回(作为函数结果)文件描述符标志; arg被忽略了。

(或者如果你在意的话,请参阅POSIX standard text for fctnl()。)

因此,fnctl(fd, F_GETFD)会告诉您文件描述符是否在execve()上保持打开状态。

适用于fcntl()的常见错误情况,因此它会例如如果您给出的fd未打开,则返回-1并将errno设置为EBADF。在你的代码中,你在fd 0上调用了fcntl(),它保存了x的副本,因此是开放的。然而,fcntl()将为fd x返回-1,那是你明确关闭的那个。


-1
投票

在Linux内核中检查do_fcntl的实现,我们可以看到:

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)可能只返回FD_CLOEXEC或0。

here中的系统调用定义可以在文件描述符错误的情况下返回-EBADF,或者使用O_PATH打开文件描述符。

从这一点来看,fcntl(F_GETFD)将仅返回-1,其中errno设置为-9(-EBADF),或者在Linux 4.20上返回0或1(FD_CLOEXEC)。因此,如果使用fcntl(F_GETFD)打开了错误的文件描述符或文件描述符,-1将返回O_PATH。请注意,对于其他内核,它可能会有所不同,请注意它可能会随时间而变化。

© www.soinside.com 2019 - 2024. All rights reserved.