2012-08-06 75 views

回答

14

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 

要弄清楚什么是怎么回事,我去了源。 I happen to knowepoll的大多数行为由对应于目标文件的struct file_operations上的->poll函数确定,其取决于所讨论的文件系统。我拿起ext4作为一个典型的例子,看着fs/ext4/dir.c,这definesext4_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,我们发现在epoll_ctl系统调用定义一个early on

/* The target file descriptor must support poll */ 
error = -EPERM; 
if (!tfile->f_op || !tfile->f_op->poll) 
    goto error_tgt_fput; 

由于我们的试验表明,如果目标文件没有按不支持poll,插入尝试将仅以EPERM失败。

其他文件系统有可能在其目录文件对象上定义.poll方法,但我怀疑它们有很多。

+0

''dirfd(opendir(“/ tmp”))''优于'open(path,O_RDONLY | O_DIRECTORY);'?只是一个风格问题。使用'opendir'不会让fs支持民意调查。 – schmichael 2012-08-06 18:22:04

+0

'dirfd(opendir(“...”))'更便于携带,所以一般来说可能是首选。我是Linux内核黑客,所以我个人倾向于默认使用系统调用接口,即使它不是最合适的,因为我知道它更好。显然这里并不重要,因为'epoll'也是Linux特有的。 – nelhage 2012-08-06 18:25:07