Why does the following code print ‘read(): Resource temporarily unavailable’ 80% of the time? That is the EAGAIN code, which is the same as WOULD BLOCK which means there is no data waiting to be read, but select is returning 1 saying there is data (tested in Linux):
#include <time.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/errno.h> int main(int argc, char** argv) { int fd = open('/dev/lp0', O_RDWR | O_NONBLOCK); int ret = 0; int status = 0; char buffer[1024]; char teststr[] = 'This is a test\n'; char XMIT_STATUS_OFFLINE[] = {0x10,0x04,0x02}; char XMIT_STATUS_ERROR[] = {0x10,0x04,0x03}; char XMIT_STATUS_ROLL[] = {0x10,0x04,0x04}; char XMIT_STATUS_SLIP[] = {0x10,0x04,0x05}; fd_set rfds; FD_ZERO( &rfds ); FD_SET( fd, &rfds ); struct timeval sleep; sleep.tv_sec = 5; sleep.tv_usec = 0; /* Offline status */ ret = write(fd, XMIT_STATUS_OFFLINE, sizeof(XMIT_STATUS_OFFLINE)); //printf('write() returned %d\n', ret); do { ret = select( fd + 1, &rfds, NULL, NULL, &sleep ); } while (ret < 0 && (errno == EINTR)); ret = read(fd, buffer, 1024); if(ret == -1) { perror('read(): '); } else { status = buffer[0]; if((status & 0x04) != 0) { printf('The cover is open.\n'); } else { printf('OFFLINE is good.\n'); } } close(fd); return 0; }
Your select call will return 0 after the 5 second timeout elapses if no data is available. Your code will ignore this and try to read from the device anyways. Check for ret == 0 and that will fix your problem.