如何在 C 中获取打开的 fd 的标志?
How to get flags of opened fd in C?
我想获取之前在 C 中打开的 fd 的标志。
但我使用 fcntl 手册页的 fcntl(fd,F_GETFD,0)
参考,它总是 return 1 给我。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define XSZ(x) (int)(sizeof(x)*2)
int main()
{
int ret;
static const char str [] = "hello c program!\n";
int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
if(fd < 0)
{
perror("open");
return -1;
}
printf("fd = %d\n", fd);
ret = fcntl(fd, F_GETFD, 0);
printf("flag:%d\n",ret);
write(fd, str, strlen(str)-1);
return 0;
}
它总是打印:
fd = 3
flag:1
我以为ret是O_RDWR | O_APPEND | O_CREAT
的总和
F_GETFD
不查询开放标志,而只是 FD_CLOEXEC
(参见 )。
行
write(fd, "hello c program\n", strlen("hello c program!\n"));
是错误的,因为你查询的字符串长度比你写的长,可能导致缓冲区溢出。一种更安全、更有效的方法是:
static const char str [] = "hello c program!\n";
write(fd, str, sizeof(str)-1);
需要 -1
以避免写入终止 0 字节。
我不知道
的目的
#define XSZ(x) (int)(sizeof(x)*2)
但是将 size_t
(sizeof()
的结果类型)转换为 int
可能不是一个好主意。
您应该使用 F_GETFL 而不是 F_GETFD。还记得打印八进制比较。
一件重要的事情是并非所有标志都由 fcntl 返回。仅记住访问模式标志,如 O_RDWR。但是 O_CREATE/O_TRUNC 等是系统不记住的操作模式或开放时间标志,因此不会返回。
这是您修改后的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define XSZ(x) (int)(sizeof(x)*2)
int main()
{
int ret;
int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
if(fd < 0)
{
perror("open");
return -1;
}
printf("fd = %d\n", fd);
ret = fcntl(fd, F_GETFL);
perror("fcntl");
printf("flag:%o\n",ret);
printf("flag:%o\n",O_RDWR|O_APPEND);
write(fd, "hello c program\n", strlen("hello c program!\n"));
return 0;
}
这是上面代码的输出
fd = 3
fcntl: Success
flag:102002
flag:2002
我想获取之前在 C 中打开的 fd 的标志。
但我使用 fcntl 手册页的 fcntl(fd,F_GETFD,0)
参考,它总是 return 1 给我。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define XSZ(x) (int)(sizeof(x)*2)
int main()
{
int ret;
static const char str [] = "hello c program!\n";
int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
if(fd < 0)
{
perror("open");
return -1;
}
printf("fd = %d\n", fd);
ret = fcntl(fd, F_GETFD, 0);
printf("flag:%d\n",ret);
write(fd, str, strlen(str)-1);
return 0;
}
它总是打印:
fd = 3
flag:1
我以为ret是O_RDWR | O_APPEND | O_CREAT
F_GETFD
不查询开放标志,而只是 FD_CLOEXEC
(参见
行
write(fd, "hello c program\n", strlen("hello c program!\n"));
是错误的,因为你查询的字符串长度比你写的长,可能导致缓冲区溢出。一种更安全、更有效的方法是:
static const char str [] = "hello c program!\n";
write(fd, str, sizeof(str)-1);
需要 -1
以避免写入终止 0 字节。
我不知道
的目的#define XSZ(x) (int)(sizeof(x)*2)
但是将 size_t
(sizeof()
的结果类型)转换为 int
可能不是一个好主意。
您应该使用 F_GETFL 而不是 F_GETFD。还记得打印八进制比较。
一件重要的事情是并非所有标志都由 fcntl 返回。仅记住访问模式标志,如 O_RDWR。但是 O_CREATE/O_TRUNC 等是系统不记住的操作模式或开放时间标志,因此不会返回。
这是您修改后的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define XSZ(x) (int)(sizeof(x)*2)
int main()
{
int ret;
int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
if(fd < 0)
{
perror("open");
return -1;
}
printf("fd = %d\n", fd);
ret = fcntl(fd, F_GETFL);
perror("fcntl");
printf("flag:%o\n",ret);
printf("flag:%o\n",O_RDWR|O_APPEND);
write(fd, "hello c program\n", strlen("hello c program!\n"));
return 0;
}
这是上面代码的输出
fd = 3
fcntl: Success
flag:102002
flag:2002