2012-08-06 3 views

Antwort

14

Nichts - der Aufruf zur Registrierung der FD wird (zumindest für gängige Linux-Dateisysteme) mit EPERM fehlschlagen.

Getestet habe ich diese mit dem folgenden Demoprogramm:

#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; 
} 

mit folgendem Ergebnis:

[[email protected]:/tmp]$ make epoll 
cc  epoll.c -o epoll 
[[email protected]:/tmp]$ ./epoll 
epoll_ctl: Operation not permitted 

, um herauszufinden, was hier los war, ich an die Quelle ging. I happen to know, dass das meiste Verhalten von epoll durch die ->poll-Funktion auf der struct file_operations entsprechend der Zieldatei bestimmt wird, die von dem fraglichen Dateisystem abhängt. Ich nahm ext4 als ein typisches Beispiel und sah fs/ext4/dir.c, die definesext4_dir_operations wie folgt:

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, 
}; 

Hinweis das Fehlen einer .poll Definition, was bedeutet, es zu NULL initialisiert wird. Also, zurück zu epoll schwingen, die in fs/eventpoll.c definiert ist, suchen wir Kontrollen für poll NULL sein, und wir finden eine early on in der epoll_ctl syscall Definition:

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

Wie unser Test zeigte, wenn die Zieldatei Doesn 't unterstützt poll, der Einsatz Versuch wird nur fehlschlagen mit EPERM.

Es ist möglich, dass andere Dateisysteme .poll Methoden auf ihren Verzeichnis-Dateiobjekten definieren, aber ich bezweifle, dass viele dies tun.

+0

Ist 'dirfd (opendir ("/tmp "))' bevorzugt über 'open (Pfad, O_RDONLY | O_DIRECTORY);'? Nur eine Stilfrage. Die Verwendung von "opendir" macht die fs-Unterstützung nicht magisch. – schmichael

+0

'dirfd (opendir (" ... "))' ist tragbarer, wird also wahrscheinlich im Allgemeinen bevorzugt. Ich bin ein Linux-Kernel-Hacker, also tendiere ich persönlich dazu, standardmäßig die System-Call-Schnittstelle zu verwenden, selbst wenn es nicht die geeignetste ist, weil ich es besser kenne. Offensichtlich ist es hier nicht wirklich wichtig, da 'epoll' auch Linux-spezifisch ist. – nelhage

Verwandte Themen