【问题标题】:fcntl(), F_GETFD meaning in UNIXfcntl(), F_GETFD 在 UNIX 中的含义
【发布时间】:2019-02-12 18:27:30
【问题描述】:

在 fcntl() 函数中 F_GETFD 在 unix 中的含义是什么?,据我了解,如果指定位置没有文件描述符,它应该返回 -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


    【解决方案1】:

    来自man page of fcntl()

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

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

    (如果您在意,请查看POSIX standard text for fctnl()。)

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

    fcntl() 的常见错误情况适用,因此例如如果您提供的 fd 未打开,则返回 -1 并将 errno 设置为 EBADF。在您的代码中,您在 fd 0 上调用了 fcntl(),它保存了 x 的复制副本,因此是打开的。 fcntl() 会为 fd x 返回 -1,不过,这是您明确关闭的。

    【讨论】:

      【解决方案2】:

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

      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 打开的文件描述符。请注意,对于其他内核,它可能会有所不同,并会随着时间而改变。

      【讨论】:

        猜你喜欢
        • 2019-04-03
        • 2021-08-14
        • 2019-08-12
        • 1970-01-01
        • 2017-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        相关资源
        最近更新 更多