2012-08-06 82 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