views:

58

answers:

1

I'm using select() call to detect input presence in the main cycle of my program. This makes me use raw file descriptor (0) instead of stdin.

While working in this mode I've noticed that my software occasionally loses a chunk of input at the beginning. I suspect that stdin consumes some of it on the program start. Is there a way to prevent this behavior of stdin or otherwise get the whole input data?

The effect described can be reproduced only with some data on standard input at the very moment of program start. My executable should be used as xinetd service in a way that it always has some input on the start.

Standard input is read in the following way:

Error processInput() {
  struct timeval ktimeout;
  int fd=fileno(stdin);
  int maxFd=fd+1;
  FD_ZERO(&fdset);
  FD_SET(fd, &fdset);
  ktimeout.tv_sec = 0;
  ktimeout.tv_usec = 1;
  int selectRv=-1;
  while ((selectRv=select(maxFd, &fdset, NULL, NULL, &ktimeout)) > 0) {
    int left=MAX_BUFFER_SIZE-position-1;
    assert(left>0);
    int bytesCount=read(fd, buffer+position, left);
    //Input processing goes here
  }
}
+1  A: 

Don't mix cooked and raw meat together. Try replacing the read() call with the equivalent fread() call.

It is very likely that fileno(stdin) is initializing the stdin object, causing it to read and buffer some input. Or perhaps you are already calling something that causes it to initialize (scanf(), getchar(), etc...).

Juliano
Perhaps he should go the other direction, and avoid fileno(stdin). Instead, use the well known fd number of zero for stdin.
Darron
Juliano, you mean there is an asynchronous interface for streams in C? Can you please reference a manual about it?
Basilevs
@Basilevs: It is the same interface, actually. Just use fread() only when you know for sure that there is something to read (after a successful return from select()) and you will be doing asynchronous communication. You can also set O_NONBLOCK in the file descriptor using fctrl(), to guarantee that fread() will return EAGAIN if there is nothing to be read from that descriptor.
Juliano
Select does not work with fread (fread blocks after succesful select). I've used the second suggested approach.
Basilevs