Как и в заголовке, я регистрирую файловый дескриптор, который является каталогом с epoll, что он делает?
Что делает epoll с файловым дескриптором, который ссылается на каталог?
Ответ 1
Nothing - вызов для регистрации fd (по крайней мере для обычных файловых систем Linux) завершится с EPERM
.
Я тестировал это, используя следующую демонстрационную программу:
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(void) {
int ep = epoll_create1(0);
int fd = open("/tmp", O_RDONLY|O_DIRECTORY);
struct epoll_event evt = {
.events = EPOLLIN
};
if (ep < 0 || fd < 0) {
printf("Error opening fds.\n");
return -1;
}
if (epoll_ctl(ep, EPOLL_CTL_ADD, fd, &evt) < 0) {
perror("epoll_ctl");
return -1;
}
return 0;
}
Со следующим результатом:
[[email protected]:/tmp]$ make epoll
cc epoll.c -o epoll
[[email protected]:/tmp]$ ./epoll
epoll_ctl: Operation not permitted
Чтобы понять, что здесь происходит, я пошел к источнику. я узнает, что большая часть поведения epoll
определяется функцией ->poll
на struct file_operations
, соответствующей целевому файлу, что зависит от рассматриваемой файловой системы. Я выбрал ext4
в качестве типичного примера и посмотрел на fs/ext4/dir.c
, который определяет ext4_dir_operations
следующим образом:
const struct file_operations ext4_dir_operations = {
.llseek = ext4_dir_llseek,
.read = generic_read_dir,
.readdir = ext4_readdir,
.unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext4_compat_ioctl,
#endif
.fsync = ext4_sync_file,
.release = ext4_release_dir,
};
Обратите внимание на отсутствие определения .poll
, то есть он будет инициализирован NULL
. Итак, отбросив назад к epoll, который определен в fs/eventpoll.c
, мы ищем проверки для poll
как NULL, и мы находим один early on в определении syscall epoll_ctl
:
/* The target file descriptor must support poll */
error = -EPERM;
if (!tfile->f_op || !tfile->f_op->poll)
goto error_tgt_fput;
Как показал наш тест, если целевой файл не поддерживает poll
, попытка вставки просто выйдет из строя с помощью EPERM
.
Возможно, что другие файловые системы определяют методы .poll
в своих файлах файлов каталога, но я сомневаюсь, что многие это делают.