NDK中如何使用fanotify监控/proc/pid/maps及CMakeLists配置
问题根源
linux/fanotify.h是内核层面的头文件,仅定义fanotify的结构体、常量宏,不包含用户态函数的封装,所以引入该头文件不会报错,但直接调用fanotify_init会找不到函数定义。sys/fanotify.h是C标准库提供的用户态头文件,包含函数声明。Android使用的bionic C库从API 30(Android 11)才正式加入该头文件和对应的fanotify_init、fanotify_mark函数封装,minSdkVersion低于30或者NDK版本过旧都会找不到该头文件和函数。
解决方案
分两种场景适配:
场景1:仅需要兼容Android 11(API 30)及以上设备
直接用bionic提供的官方封装即可,配置如下:
- 确认使用的NDK版本 >= r21,项目minSdkVersion设置为30或更高
- 在
CMakeLists.txt中添加对应配置:
cmake_minimum_required(VERSION 3.18.0) project("your_project_name") # 显式指定目标API级别为30 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__ANDROID_API__=30") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__ANDROID_API__=30") add_library( your_native_lib SHARED your_native_source.cpp ) target_link_libraries( your_native_lib log # fanotify函数已内置在libc中,无需额外链接依赖库 )
- 代码中直接引入
#include <sys/fanotify.h>即可正常调用相关函数。
场景2:需要兼容Android 11以下版本
由于低版本bionic没有封装fanotify函数,可直接通过系统调用调用内核功能,只要运行设备的内核版本 >= 2.6.36(绝大多数现役Android设备都满足)即可正常使用:
- 代码中引入内核头文件和系统调用头文件,自行封装fanotify函数:
#include <linux/fanotify.h> #include <sys/syscall.h> #include <unistd.h> // 自行封装fanotify_init static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) { return syscall(__NR_fanotify_init, flags, event_f_flags); } // 自行封装fanotify_mark static inline int fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, int dirfd, const char *pathname) { return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dirfd, pathname); }
- 该场景下
CMakeLists.txt无需额外特殊配置,按原有NDK项目配置正常编译即可。
额外注意事项
fanotify需要进程持有CAP_SYS_ADMIN权限才能正常调用,普通应用无该权限,运行时会返回权限错误,需要应用为系统应用、或者设备root后授予对应权限才可正常使用。
内容的提问来源于stack exchange,提问作者cs x
相关产品推荐
相关产品推荐

