加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

使用poll()检查文件修改

发布时间:2020-12-13 19:23:48 所属栏目:Linux 来源:网络整理
导读:有一个文件,我想用poll()检查内容是否已更改. 在Raspi上有一个名为gpio value的文件,如果值改变了poll()是用POLLPRI触发的,我想对普通文件做同样的事情. 这是我用来检查GPIO文件的代码: int gpio_fd = gpio_fd_open();int timeout = POLL_TIMEOUT;struct po

有一个文件,我想用poll()检查内容是否已更改.

在Raspi上有一个名为gpio value的文件,如果值改变了poll()是用POLLPRI触发的,我想对普通文件做同样的事情.

这是我用来检查GPIO文件的代码:

int gpio_fd = gpio_fd_open();
int timeout = POLL_TIMEOUT;
struct pollfd fdset;
int nfds = 1;
char *buf[MAX_BUF];
int len;
int rc;
fdset.fd = gpio_fd;
fdset.events =  POLLPRI | POLLERR | POLLHUP | POLLNVAL; // POLLIN | | POLLOUT 
unsigned int c1,c2,c3;
do{
    rc = poll(&fdset,1,timeout);

和gpio_fd_open函数:

int gpio_fd_open() {
    printf("opening File: " SYSFS_GPIO_DIR "n");

    int fd,len;
    char buf[MAX_BUF];

    len = snprintf(buf,sizeof (buf),SYSFS_GPIO_DIR);
    fd = open(buf,O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("gpio/fd_open");
    }
    return fd;
}
最佳答案
在Linux中,与您的特殊GPIO文件不同,您无法将fd轮询到这样的开放普通文件.

要查看文件以进行更改,您可以使用inotify系列函数.您可以方便地使用文件描述符,该文件描述符可以与您的GPIO文件描述符一起传递给poll(),因此您可以同时查看两者.

因此,对代码进行一些小的添加/更改:

int fw_fd = file_watch_fd("/some/file/to/watch");
struct pollfd fdset[2];
int nfds = 2;
int rc;
fdset[0].fd = gpio_fd;
fdset[0].events =  POLLPRI | POLLERR | POLLHUP | POLLNVAL;
fdset[1].fd = fw_fd;
fdset[1].events = POLLIN;
do {
    rc = poll(fdset,nfds,timeout);

您正在查看inotify fd,您阅读该fd以返回发生的另一个观察事件.由于此代码仅针对一个事件观看一个文件,因此我们非常确定事件是什么,但我们仍然需要从fd中读取它,然后我们才能真正读取该文件.

    if (fdset[1].revents & POLLIN) {
        if (ready(fw_fd)) {
            /* file has changed,read it */
        }
    }

这是file_watch_fd()函数:

int file_watch_fd ( const char * filename ) {
        static int      inot    = ERR;
        static int      iflags  = IN_CLOEXEC | IN_NONBLOCK;
        static uint32_t mask    = IN_MODIFY;
        int             watch;

        if (inot == ERR) {
                inot = inotify_init1(iflags);
                if (inot == ERR) return ERR;
        }
        watch = inotify_add_watch(inot,filename,mask);
        if (watch == ERR) return ERR;
        return inot;
}

这是ready()函数:

int ready ( int inot ) {
        uint64_t                buffer[8192];
        ssize_t                 nr;
        char *                  p;
        size_t                  n;
        struct inotify_event *  evP;
        int                     ready   = 0;

        while ((nr = read(inot,(char *)buffer,sizeof(buffer))) > 0) {
                for (p = buffer; p < buffer + nr; p += n) {
                        evP = (struct inotify_event *)p;
                        if (evP->mask & IN_MODIFY) ready = 1;
                        n = sizeof(struct inotify_event) + evP->len;
                }
        }
        return ready;
}

(人们使用inotify的经验会注意到我对它的功能进行粗暴操作以保持这个例子尽可能简单)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读