views:

1001

answers:

1

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;
}
+4  A: 

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.

SoapBox
Actually I checked for that and ret was always = 1. Someone else told me that what is happening is select is returning that there is data, but that read is blocking because checksums or some data error occurred
So at this point I am going to see if it is possible to switch it to blocking mode. This is actually a subset of code I converted to C from java that used rxtx libs and javax.comm to do this, but always opens in non-blocking form.