poll() not blocking, returns immediately
<p>I'm trying to catch an interrupt on GPIO through <code>sysfs</code> using <code>poll()</code>. I have -1 in the third position so it can block, but it seems to be always returning. I've checked out some similar posts on SO. Notably <a href="https://stackoverflow.com/questions/18616716/why-does-poll-keep-returning-although-there-is-no-input?lq=1">this (1)</a>, <a href="https://stackoverflow.com/questions/16442935/why-doesnt-this-call-to-poll-block-correctly-on-a-sysfs-device-attribute-file?lq=1">this (2)</a>, and <a href="https://stackoverflow.com/questions/34808276/poll-on-raspberry-gpio-sysfs-raspberry">this (3)</a>.</p>

<p>In (1), it was solved by placing a dummy <code>read()</code> before calling <code>poll()</code>. If I do this (see commented <code>read()</code> in code). My code runs through the loop once and blocks forever on <code>poll()</code> the second time around.</p>

<p>In (2), this might be an explanation, yet doesn't really provide a solution to my problem.</p>

<p>In (3), I already have an <code>lseek()</code> before my <code>read()</code></p>

<p>How can I get this <code>poll()</code> to block and only return as in interrupt when the the gpio's <code>value</code> has changed?</p>

<p>Here's the code snippet:</p>

<pre><code>int read_gpio(char *path, void (*callback)(int)){
    int fd;
    char buf[11];
    int res = 0;
    char c;
    int off;
    struct pollfd gpio_poll_fd = {
        .fd = fd,
        .events = POLLPRI,
        .revents = 0
    };
    for(;;){

        gpio_poll_fd.fd = open(path, O_RDONLY);
        if(fd == -1){
            perror("error opening file");
            return -1;
        }
//        char c;
//        read(fd,&amp;c,1);
        LOGD("for begins");
        res = poll(&amp;gpio_poll_fd,1,-1);
        LOGD("polling ended");
        if(res == -1){
            perror("error polling");
            break;
        }

        if((gpio_poll_fd.revents &amp; POLLPRI)  == POLLPRI){
            LOGD("POLLPRI");
            off = lseek(fd, 0, SEEK_SET);
            if(off == -1) break;
            memset(&amp;buf[0], 0, 11);
            size_t num = read(fd, &amp;buf[0], 10*sizeof(char));
            LOGD("Before callback");
            callback(atoi(buf));
            LOGD("After Callback");
        }
        if((gpio_poll_fd.revents &amp; POLLERR) == POLLERR) {
            //seems always to be true ..
            //LOGD("POLLERR");
        }
        close(fd);
        LOGD("for ends");

    }
    LOGD("for exits");

    return 0;
}
</code></pre>

<p><b>Note:</b> As I'm doing this on Android JNI, I've been getting info for debugging from <code>LOGD()</code></p>

<p><b>Update:</b>
Following the advice in jxh's comment I've arranged the structure like so, although now it blocks on <code>poll()</code> indefinitely. When the content of value is changed from the externally applied voltage, POLLPRI doesn't go high, and poll() doesn't return:</p>

<pre><code>int read_gpio(char *path, void (*callback)(int)){
    int fd = open(path, O_RDONLY);
    if(fd == -1){
        perror("error opening file");
        return -1;
    }
    char buf[11];
    int res, off;
    char c;
    struct pollfd pfd = {
            .fd = fd,
            .events = POLLPRI,
            .revents = 0
    };
    for(;;){
        LOGD("for begins");
//        dummy read causes poll never to run
//        lseek() alone here cause poll never to run
//        read(fd, &amp;buf[],1);
//        lseek(fd, 0, SEEK_SET);
        res = poll(&amp;pfd,1,-1);
        LOGD("polling ended");
        if(res == -1){
            perror("error polling");
            break;
        }

        if((pfd.revents &amp; POLLPRI)  == POLLPRI){
            LOGD("POLLPRI");
            off = lseek(fd, 0, SEEK_SET);
            if(off == -1) break;
            memset(&amp;buf[0], 0, 11);
            read(fd, &amp;buf[0], 10*sizeof(char));
//            These two lines will cause it to poll constantly
//            close(fd);
//            fd = open(path, O_RDONLY);
            LOGD("Before callback");
            callback(atoi(buf));
            LOGD("After Callback");
        }
        LOGD("for ends");
    }
    close(fd);
    LOGD("for exits");

    return 0;
}
</code></pre>