Почему следующее печатает «Ресурс временно недоступен»?

Почему следующий код выводит «read(): Ресурс временно недоступен» в 80% случаев? Это код EAGAIN, который совпадает с кодом WOULD BLOCK, что означает отсутствие данных, ожидающих чтения, но select возвращает 1, говоря, что данные есть (проверено в 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;
}

person user10060    schedule 11.12.2008    source источник


Ответы (1)


Ваш вызов select вернет 0 по истечении 5-секундного тайм-аута, если данные недоступны. Ваш код проигнорирует это и все равно попытается прочитать с устройства. Проверьте ret == 0, и это решит вашу проблему.

person SoapBox    schedule 11.12.2008
comment
На самом деле я проверил это, и ret всегда был = 1. Кто-то еще сказал мне, что происходит то, что select возвращает, что есть данные, но это чтение блокируется, потому что произошли контрольные суммы или какая-то ошибка данных. - person user10060; 12.12.2008
comment
Итак, на данный момент я собираюсь посмотреть, можно ли переключить его в режим блокировки. На самом деле это подмножество кода, который я преобразовал в C из java, который использовал для этого библиотеки rxtx и javax.comm, но всегда открывается в неблокирующей форме. - person user10060; 12.12.2008