首页 > 解决方案 > 未定义对“inotify_init1”的引用

问题描述

我正在尝试在我的项目中集成最新版本的 dnsmasq 应用程序 2.80 。该平台是Linux 2.6.32。使用交叉编译器 arm-none-linux-gnueabi-gcc 进行编译会出现此错误:

inotify.o: In function `inotify_dnsmasq_init':
inotify.c:(.text+0x514): undefined reference to `inotify_init1'

这个平台似乎不支持函数 inotify_init1() 。

我想知道我是否可以自己编写这个函数。

int inotify_init1(int flags)
{
    int flags1 = 0;
    int inotify_fd = inotify_init();

    if ((inotify_fd != -1) && (flags != 0)) 
    {
        if((flags1 = fcntl(inotify_fd, F_GETFL)) != -1)
        {
            fcntl(inotify_fd, F_SETFL, flags1 | flags);
        }
    }
    return inotify_fd;
}

这段代码能完成这项工作吗?

更新: 根据inotify_init 手册页, inotify_init1() 在 2.9 版本中被添加到 glibc。我只使用 glibc 2.8 版

另一方面,我看到 inotify_init1 存在于内核的几个文件中:

1) /fs/notify/inotify/inotify_user.c
/* inotify syscalls */
SYSCALL_DEFINE1(inotify_init1, int, flags)
{ 
...
}
2) /kernel/sys_ni.c
cond_syscall(sys_inotify_init1);

我知道我遗漏了一些东西,但我不知道是否在 dnsmasq 构建文件上构建或正确链接了适当的库。

谢谢你的建议。

标签: clinux-kernelembedded-linuxdnsmasq

解决方案


你的功能看起来不错,应该可以工作。但是我不知道您的应用程序如何定义宏 IN_NONBLOCK 和 IN_CLOEXEC。查看内核 srcrs,它们的定义应与 O_NONBLOCK 和 O_CLOEXEC 相同。也可以添加if (flags & ~(IN_CLOEXEC | IN_NONBLOCK)) return -EINVAL;一些检查。

我会将一个文件添加inotify.h到您的项目/到 dnsmasq 源,我将添加到包含路径:

#ifndef MY_INOTIFY_H_
#define MY_INOTIFY_H_
#include_next <inotify.h>

// from https://github.molgen.mpg.de/git-mirror/glibc/blob/glibc-2.9/sysdeps/unix/sysv/linux/sys/inotify.h#L25
/* Flags for the parameter of inotify_init1.  */
enum
  {
    IN_CLOEXEC = 02000000,
#define IN_CLOEXEC IN_CLOEXEC
    IN_NONBLOCK = 04000
#define IN_NONBLOCK IN_NONBLOCK
  };

extern int inotify_init1 (int flags) __THROW;
// or just int inotify_init1(int flags); ...

#endif

与它一起将您在 ac 文件中的包装器添加到编译/链接中。include_next 用作对 glibc inotify.h 的简单覆盖。

如果你的内核支持 inotify_wait1 系统调用,我认为支持。您甚至可以检查__NR_inotify_wait1是否在 unistd.h 中定义。你可以:

   #define _GNU_SOURCE
   #include <unistd.h>
   #include <sys/syscall.h>

   int inotify_init1(int flags) {
       return syscall(332, flags);
   }

要进行系统调用,只需调用 syscall() 函数。


推荐阅读