неопределенная ссылка на `inotify_init1 ' - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь интегрировать в свой проект последнюю версию 2.80 dnsmasq . Платформа 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 () был добавлен в glibc в версии 2.9. Я работаю только с 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.

Спасибо за совет.

1 Ответ

0 голосов
/ 13 ноября 2018

Ваша функция выглядит нормально и должна работать. Однако я не знаю, как ваше приложение определяет макросы 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

Наряду с этим в компиляцию / компоновку добавлена ​​ваша обертка в c-файл. 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 ().

...