使用 poll() 和 POLLIN 来等待文件中的更改

问题描述 投票:0回答:1

当调用特定属性的 sysfs_notify(3) 时,我必须与内核驱动程序合作并在 C 应用程序中等待。我想通过文件描述符使用 poll() 方法。

我的实现如下:

...
    struct pollfd *fds = malloc(sizeof(struct pollfd) * 1);

    fds[0].fd = open("/path/to/file", O_RDONLY);
    fds[0].events = POLLIN;
    fds[0].revents = 0;
    if (fds[0].fd < 0) return -EXIT_FAILURE;

    //! Poll and Process Descriptors
    while (poll(fds, 1, -1) > 0) {
        if (fds[0].events & fds[0].revents) {
            fds[0].revents = 0;
            ret = read(fds[0].fd, buf, sizeof(buf));
        }
    }
...

结果,即使没有对目标文件执行任何操作,我也通过 POLLIN 在 fds.revents 中获得了无限不可阻挡的 poll() 激活。

我尝试了我的简单文本文件而不是内核 sysfs 属性,并且还对 POLLIN 进行了无限不可阻止的 poll() 激活,而对文件没有任何操作。

有人可以帮我解决吗? 预先感谢,安东!

c linux kernel sysfs
1个回答
0
投票

UPD:嗯,我已经解决了我的问题。我有自己的内核驱动程序,并且 sysfs_notify 的问题就在这里。 I2C 内核驱动程序有自己的结构

struct i2c_driver
和 sysfs 组注册
sysfs_create_group(2)
从内部驱动程序探针运行。因此,在探测期间不要使用
sysfs_create_group(2)
,只需由您的组初始化
struct i2c_driver
内部
struct device_driver driver
字段
dev_groups
,它会在内部探测期间自动在 sysfs 中注册,并且我还在
kobject_uevent_env(&chip->client->dev.kobj, KOBJ_CHANGE, envp);
之前粘贴
sysfs_notify()
,例如在我的司机身上:

ATTRIBUTE_GROUPS(sfh7771_attribute);
...
static struct i2c_driver sfh7771_driver = {
.driver  = {
    .name   = SFH7771_NAME,
    .of_match_table = sfh7771_of_match,
    .dev_groups = sfh7771_attribute_groups,
},
.probe    = sfh7771_probe,
.remove   = sfh7771_remove,
.id_table = sfh7771_id,
};
...
kobject_uevent_env(&chip->client->dev.kobj, KOBJ_CHANGE, envp);
sysfs_notify(&chip->client->dev.kobj, NULL, "your_attribute");

在我的用户空间代码中,我使用了

poll(3)
但作为事件,有 POLLPRI | POLLERR 标志,并且不要忘记使用 lseek() 来查找文件的开头。下面的简短示例:

struct pollfd *fds = malloc(sizeof(struct pollfd) * 1);

fds[0].fd = open("/path/to/file", O_RDONLY);
fds[0].events = POLLPRI | POLLERR;
fds[0].revents = 0;
if (fds[0].fd < 0) return -EXIT_FAILURE;

//! Poll and Process Descriptors
while (poll(fds, 1, -1) > 0) {
    if (fds[0].events & fds[0].revents) {
        fds[0].revents = 0;
        lseek(fds[0].fd, 0, SEEK_SET);
        ret = read(fds[0].fd, buf, sizeof(buf));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.