Michael F. Robbins on Mon, 24 Jun 2002 14:00:11 +0200 |
I'm writing a c++ app to read a command stream from a fifo. Commands are delimited by newlines. The app must be able to process other tasks (running in a while loop) if there is no data incoming from the fifo. Right now, I'm using ifstream's rdbuf()->fd() to get the file descriptor so I can use poll() on the fifo. When there is a read event, I do an ifstream::getline() on the input stream class. The problem occurs when the sending program sends two lines at once, i.e. before the listener task is run again. The getline() is only called once for each poll() that returns positive, however sometimes really two or more getline()s are needed. I would have thought that checking for the POLLIN event would have returned true since there were more data left to read. However, my guess is that the ifstream class has an internal buffer which has the next command inside, so the poll() returns false. Any ideas? Right now I'm looking at setting O_NDELAY on the file descriptor. This would certainly allow a simple read() function to work on it, but would the getline() work correctly? Here's the code in question: ------ // includes omitted for sanity int main(int argc, char *argv[]) { ifstream fifoIn("/path/to/fifo"); int fifoInID = fifoIn.rdbuf()->fd(); pollfd fifoInPollFD = {0, 0, 0}; fifoInPollFD.fd = fifoInID; fifoInPollFD.events = POLLIN; char lastCommandC[1024]; String lastCommand; while(1) { // Other stuff must be free to happen here // if there are no new commands // Check for tasks on message queue and process them. fifoInPollFD.events = POLLIN; fifoInPollFD.revents = 0; // 10 millisecond timeout if(poll(&fifoInPollFD, 1, 10) > 0) { // Grab a line, stick it in lastCommandC, and // convert it to a String class fifoIn.getline(lastCommandC, sizeof lastCommandC, '\n'); lastCommandC[sizeof lastCommandC - 1] = '\0'; lastCommand = lastCommandC; // No, this is not the error. The dispatch function // is defined and works well. cerr << "Dispatch: " << lastCommand << endl; dispatch(lastCommand); if(fifoIn.eof()) { cerr << "eof on input fifo" << endl; exit(0); } } } // close while loop return 0; } ------ Thanks, Michael F. Robbins mike@gamerack.com Attachment:
signature.asc
|
|