13

タイトルが言うように、私はepollのディレクトリであるファイル記述子を登録します、それは何をしますか?

4

1 に答える 1

17

何もありません-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->pollstruct file_operationsext4fs/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に戻ると、NULLであるfs/eventpoll.cかどうかのチェックを探し、syscall定義の早い段階でチェックを見つけます。pollepoll_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他のファイルシステムがディレクトリファイルオブジェクトにメソッドを定義している可能性はありますが、多くの人が定義しているとは思えません。

于 2012-08-06T18:04:55.330 に答える