我编写了一个接收
FILE*
并检查它是否准备就绪的函数。
功能:
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;
}
我正在尝试使用
check.h
测试此功能。
测试:
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
结果:
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
在我使用 0
和
rewind
后,Select 返回
fflush
。
当我使用
read
时,我可以检索数据。
// Debug
char bff[MAXLINE];
int n = read(inDescrp, bff, MAXLINE);
bff[n] = '\0';
printf("%d\n", inDescrp);
printf("%s\n", bff);
所以即使我可以读取数据,选择也会返回
0
。
如果我尝试设置非零超时,问题也会继续存在。
为什么会出现这种情况?
我需要检查文件是否已准备好读取。
可能的解决方案是什么?
我明白为什么你会被 select() 的“nfds”参数引入歧途。它读起来和听起来都像“文件描述符的数量”。
不是那样的。它应该是您关心的最高文件描述符的值,加上 1。请参阅(例如)有关它的 Linux 手册页
顺便说一句,nfds 参数是一个 int - 所以不要使用无符号短整型。一般来说,它会“正常工作”,但非常令人困惑。