如何检查syncfs是否可用,同时访问O_DIRECT
?
每https://man7.org/linux/man-pages/man2/open.2.htmlO_DIRECT
、O_NOATIME
、O_PATH
和O_TMPFILE
标志是特定于Linux的。必须定义_GNU_SOURCE
才能获得它们的定义。
因此,为了访问O_DIRECT
,似乎我必须自己定义 _GNU_SOURCE。
glibc的特性测试宏要求(参见feature_test_macros(7)):syncfs():_GNU_SOURCE
为了检查syncfs是否可用,我必须检查是否定义了_GNU_SOURCE?
如果我这么做了
#define _GNU_SOURCE
int handle = open(argv[0], O_RDWR
#ifdef _GNU_SOURCE
| O_DIRECT
#endif
);
#ifdef _GNU_SOURCE
syncfs(handle);
#endif
它将在Cygwin上错误编译,因为syncfs不可用,但#ifdef
检查认为它可用,因为我自己定义了_GNU_SOURCE
。
int handle = open(argv[0], O_RDWR
#ifdef _GNU_SOURCE
| O_DIRECT
#endif
);
#ifdef _GNU_SOURCE
syncfs(handle);
#endif
我猜O_DIRECT
会被错误地忽略,即使支持,因为我没有自己定义_GNU_SOURCE
?现在我很困惑.我不知道我应该如何安全地检查如果O_DIRECT是可用的,并安全地检查,如果我可以使用syncfs()
,在同一时间.帮助?
1条答案
按热度按时间qacovj5a1#
为了检查syncfs是否可用,我必须检查是否定义了
_GNU_SOURCE
?不,这是对(g)libc上下文中“feature test macro”含义的误解。
功能测试宏是在翻译单元中包含任何标题之前由您定义或未定义的东西。然后libc标题只向您的翻译单元公开那些您已经定义了相应功能测试宏或基于定义的宏选择行为的功能。这可以确保非标准实体的名称不会与用户定义的同名实体冲突,并且非标准实体的名称不会与用户定义的同名实体冲突。标准行为不会破坏应该是可移植的基于标准的程序。
详情请参见
man feature_test_macro
。这些宏不会告诉你系统支持哪些功能,只会告诉你当前翻译单元支持哪些功能。
要检查某个函数是否受支持,您需要使用一个测试程序,该程序定义了功能测试宏并尝试使用有问题的函数。然后在构建系统的配置阶段,您应该测试该程序是否可以编译和链接。如果可以,则该函数受支持。
构建系统有这样的功能,例如autotools通常使用这种方法,CMake有
check_symbol_exists
用于此目的。或者,您可以在平台和glibc版本等上硬编码需求,您知道该功能是否受支持。