Что делает epoll с файловым дескриптором, который ссылается на каталог?
Как и сказано в заголовке, я регистрирую файловый дескриптор, который является каталогом с epoll, что он делает?
1 ответ:
Ничего -- вызов для регистрации 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; }
Со следующим результатом:
Чтобы выяснить, что здесь происходит, я пошел к источнику. Я случайно знаю , что большая часть поведения[nelhage@hectique:/tmp]$ make epoll cc epoll.c -o epoll [nelhage@hectique:/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
, которые являются нулевыми, и мы находим один на ранней стадии в определенииepoll_ctl
syscall:/* The target file descriptor must support poll */ error = -EPERM; if (!tfile->f_op || !tfile->f_op->poll) goto error_tgt_fput;
Как показал наш тест, если целевой файл не поддерживает
poll
, попытка вставки будет просто провалиться сEPERM
.Возможно, что другие файловые системы определяют методы
.poll
для своих объектов файлов каталогов, но я сомневаюсь, что многие из них это делают.