How do you poll data from a device in C++ without blocking?

Viewed 78

I have a device connected via USB, which is outputting a stream of characters separated by a newline, every few seconds. I want to repeatedly poll this device for input without blocking on the event that no such input exists.

I am trying to use the poll() function as recommended on other questions, however, it is not working, and I am having trouble determining where I am going wrong.

My device is at /dev/TTYACM0 and when I run cat /dev/TTYACM) I can see the stream of data.

This is my current program, however it just causes a segmentation fault:

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>

int main (int argc, char* argv[]){
    char buf[1024];
    int fd = open("/dev/ttyACM0", O_RDONLY | O_NONBLOCK);
    int ret;
    if (fd < 0){
        std::cout << "ERROR" << fd << std::endl;
    }

    int i;

    struct pollfd *pfds;

    while(1){
        pfds->fd = 0;
        pfds->events = POLLIN;
        ret = poll(pfds, 1, 0);
        if (ret > 0) {
            if (pfds->revents & POLLWRBAND)
            {
                i = read(0, buf, 1024);
                if (!i){
                    printf("stdin closed\n");
                    return 0;
                }
                std::cout << i << std::endl;
            }
        }
    }

    return 0;
}

UPDATE:

I fixed the code, here is the working version

#include <poll.h>
#include <iostream>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>


int main(){

    char readBuf[5];
    char c;
    std::string buf;
    int counter = 0;
    int ret;
    int i;

    struct pollfd mypoll;
    int fd = open("/dev/ttyACM0", O_RDONLY | O_NONBLOCK);

    //init mypoll
    memset(&mypoll, 0, sizeof(mypoll));
    mypoll.fd = fd;
    mypoll.events = POLLIN;

    while(1){
        // poll (pointer to pollfd, number of polls, timeout)
        // noneg = successful poll
        // 0 = systemcall timeout (no data)
        // -1, errno set to indicate error
        ret = poll(&mypoll, 1, 0);
        if (ret == 1){
            int bytes_read = read(fd, readBuf, sizeof(readBuf));
            for (i = 0; readBuf[i] != '\n' && i < bytes_read; i++){
                buf.push_back(readBuf[i]);
            }
            std::cout << "#" << buf << "#" << std::endl;
            buf = "";   
        }
    }

    printf("done\n");

    close(fd);

    return 0; 
}
0 Answers
Related