cposix-selectfflushrewind

Select always returns 0 in an input file


Select always returns 0 in an input file

I wrote a function function that receives FILE* and checks if it is ready.

The function:

int ioManager_nextReady(FILE *IFILE) {
  // Setting input ifle
  int inDescrp = fileno(IFILE ? IFILE : stdin);

  // Setting timer to 0
  struct timeval timeout;
  timeout.tv_sec = timeout.tv_usec = 0;

  // Variables for select
  unsigned short int nfds = 1;

  fd_set readfds;

  FD_ZERO(&readfds);
  FD_SET(inDescrp, &readfds);

  // Run select
  int nReady = select(nfds, &readfds, NULL, NULL, &timeout);
  if (nReady > 0) {
    return inDescrp;
  }

  return -1;
}

I am trying to test this function with check.h.

The tests:

static FILE *tmpIn;

void before(char *line) {
  tmpIn = tmpfile();

  if (line) {
    fprintf(tmpIn, "%s\n", line);
    rewind(tmpIn);
    fflush(tmpIn);
  }
}

void after() { fclose(tmpIn); }

START_TEST(test_ioManager_nextReady_NULL) {
  before(NULL);

  int data;
  data = ioManager_nextReady(tmpIn);

  ck_assert_int_eq(data, -1);

  after();
}
END_TEST

#define LINEIN "Sample input"
START_TEST(test_ioManager_nextReady_text) {
  before(LINEIN);

  int data;

  data = ioManager_nextReady(tmpIn);
  ck_assert_int_ne(data, -1);

  after();
}
END_TEST

The result:

Running suite(s): IOManager
50%: Checks: 2, Failures: 1, Errors: 0
ioManager.test.c:42:F:Smoke:test_ioManager_nextReady_text:0: Assertion 'data != -1' failed: data == -1, -1 == -1

Select is returning 0 after I use rewind and fflush.

When I use read I can retreive the data.

  // Debug
  char bff[MAXLINE];
  int n = read(inDescrp, bff, MAXLINE);
  bff[n] = '\0';

  printf("%d\n", inDescrp);
  printf("%s\n", bff);

So select is returning 0 even when I can read data.

The problem also continues if I try to set a not zero timeout.

Why is this happening?

I need to check if a file is ready to be read.

What is a possible solution?


Solution

  • I can see why you have been led astray, by the 'nfds' parameter to select(). It reads and sounds like "number of file descriptors".

    It is not that. It should be the value of the highest file descriptor that you care about, plus 1. See (for example) the Linux manpage about it

    As an aside, the nfds parameter is an int - so don't use an unsigned short. It will "just work" generally, but is very confusing.