【问题标题】:Where does kevent() validate its file descriptor?kevent() 在哪里验证它的文件描述符?
【发布时间】:2016-01-27 18:48:07
【问题描述】:

假设我们有一个像这样的简单程序:

int fd;
kq = kqueue();
EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD, 0, 0, NULL);
kevent(kq, &kev, 1, &ke, 1, &timeout)

kevent 在哪里检查fd 是否是有效的文件描述符?它可能会发现fd 表示的文件描述符已关闭。

【问题讨论】:

  • 不清楚(至少对我而言)你在问什么。如果你给 kevent 传递一个封闭的 fd 会发生什么?
  • @arrowd 感谢您的回复。是的,如果我通过 kevent 关闭 fd 会发生什么?我觉得kevent里面有这样的check,但是没找到....
  • 好吧,你可以编译你的代码试试看。我猜,kevent 不会返回 -1 来指示错误,而是简单地删除这个过滤器,因为这是关闭 fd 被监视时所做的事情。

标签: system-calls freebsd file-descriptor


【解决方案1】:

我不打算讨论在 freebsd 中系统调用是如何发生的(你可能欠 oracle 另一个问题),但是,sys_kevent() (/usr/src/sys/kern/kern_event.c) 被调用并且它调用kern_kevent() (同一个文件)。在下面的代码中,fget(fd) 在返回文件指针之前检查您的文件描述符(检查现有、权限等。可能也会锁定它)。

int
kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
    struct kevent_copyops *k_ops, const struct timespec *timeout)
{
    cap_rights_t rights;
    struct file *fp;
    int error;

    cap_rights_init(&rights);
    if (nchanges > 0)
        cap_rights_set(&rights, CAP_KQUEUE_CHANGE);
    if (nevents > 0)
        cap_rights_set(&rights, CAP_KQUEUE_EVENT);
    error = fget(td, fd, &rights, &fp);
    if (error != 0)
        return (error);

    error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout);
    fdrop(fp, td);

    return (error);
}

嘿...我什么时候变成了 UTSL 纳粹?叹息。

【讨论】:

    猜你喜欢
    • 2020-08-09
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2022-09-29
    • 2016-02-26
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多