fcntl(), F_GETFD 在 UNIX 中的含义
fcntl(), F_GETFD meaning in UNIX
Unix 中 fcntl() 函数中 F_GETFD 的含义是什么?据我了解,如果指定位置没有文件描述符,则应 return -1 .. 如果是的,什么时候会发生?当接近那个位置的文件描述符时,F_GETFD 也不会 return -1 ..
这是使用 F_GETFD 的程序的一部分,如果我关闭 x fd(thid fd 在 fd table 中输入 0,它不会 return -1 因为我们预先关闭 0 并执行 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);
}
什么时候 F_GETFD return -1 ?
检查 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)
可能 return 仅 FD_CLOEXEC
或 0.
来自 here 的系统调用定义可以 return -EBADF
如果文件描述符错误或文件描述符是用 O_PATH
打开的。
据此判断,fcntl(F_GETFD)
将 return 仅 -1,errno 设置为 -9 (-EBADF
),或 return 0 或 1 (FD_CLOEXEC
) Linux 4.20。因此,如果文件描述符错误或使用 O_PATH
打开的文件描述符,fcntl(F_GETFD)
将 return -1
。请注意,对于其他内核,它可能会有所不同,并且会随着时间而改变。
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.
(如果您愿意,请参阅 POSIX standard text for fctnl()。)
因此,fnctl(fd, F_GETFD)
告诉您文件描述符是否在 execve()
期间保持打开状态。
适用 fcntl()
的常见错误情况,例如return -1 并设置 errno
到 EBADF
如果你给的 fd 没有打开。在您的代码中,您在 fd 0 上调用了 fcntl()
,它包含 x
的复制副本,因此是打开的。 fcntl()
将 return -1 用于 fd x
,不过,那是你明确关闭的那个。
Unix 中 fcntl() 函数中 F_GETFD 的含义是什么?据我了解,如果指定位置没有文件描述符,则应 return -1 .. 如果是的,什么时候会发生?当接近那个位置的文件描述符时,F_GETFD 也不会 return -1 ..
这是使用 F_GETFD 的程序的一部分,如果我关闭 x fd(thid fd 在 fd table 中输入 0,它不会 return -1 因为我们预先关闭 0 并执行 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);
}
什么时候 F_GETFD return -1 ?
检查 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)
可能 return 仅 FD_CLOEXEC
或 0.
来自 here 的系统调用定义可以 return -EBADF
如果文件描述符错误或文件描述符是用 O_PATH
打开的。
据此判断,fcntl(F_GETFD)
将 return 仅 -1,errno 设置为 -9 (-EBADF
),或 return 0 或 1 (FD_CLOEXEC
) Linux 4.20。因此,如果文件描述符错误或使用 O_PATH
打开的文件描述符,fcntl(F_GETFD)
将 return -1
。请注意,对于其他内核,它可能会有所不同,并且会随着时间而改变。
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.
(如果您愿意,请参阅 POSIX standard text for fctnl()。)
因此,fnctl(fd, F_GETFD)
告诉您文件描述符是否在 execve()
期间保持打开状态。
适用 fcntl()
的常见错误情况,例如return -1 并设置 errno
到 EBADF
如果你给的 fd 没有打开。在您的代码中,您在 fd 0 上调用了 fcntl()
,它包含 x
的复制副本,因此是打开的。 fcntl()
将 return -1 用于 fd x
,不过,那是你明确关闭的那个。