0

I'm trying to read a binary file with read() on a well functioning open()returned file descriptor but it just doesn't work returning 22 with errno.

Here is the code :

int input = open(argv[1], O_RDONLY|O_DIRECT);
char buffer_header[4];
if(read(input,buffer_header,4) > 0)
    image_width = bytesToInt(buffer_header);
printf("%d\n",errno);

What's happening is that the condition on read() is not matched. Am I doing something wrong? The file descriptor returned is 3.

mas4
  • 889
  • 1
  • 7
  • 19
Marc
  • 61
  • 1
  • 7

2 Answers2

4

I think it may have to do with your if statement being > 0.

Here's what the read man page says (type man 2 read in the terminal):

RETURN VALUE On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.

So your code should read something like

    if(-1 == read(input,buffer_header,4)) {
        perror("error with read");
    } else {
        do something;
    }

Edit: Sorry, just saw the comment thanks Barmar!! Edit2: Also you should error check the open syscall similarly.

int input = open(argv[1], O_RDONLY|O_DIRECT);
if(-1 == input) {
    perror("error with open");
} else {
    do stuff;
}

Here's a short tutorial that may help

cdixit2
  • 182
  • 8
1

You should only check errno if read returns -1 to indicate that it got an error.

int n;
if ((n = read(input, buffer_header, 4)) > 0) {
    image_width = bytesToInt(buffer_header);
} else if (n == -1) {
    perror("read");
} else {
    printf("EOF\n");
}
Barmar
  • 596,455
  • 48
  • 393
  • 495
  • The only possible explanation is that `input` is not a valid descriptor. – Barmar May 22 '15 at 07:23
  • How can I check if it isn't ? Currently `input` is `3`. – Marc May 22 '15 at 07:27
  • 2
    Maybe the problem is that you're using the O_DIRECT option. – Barmar May 22 '15 at 07:31
  • 2
    According to http://stackoverflow.com/questions/5055859/how-are-the-o-sync-and-o-direct-flags-in-open2-different-alike `O_DIRECT` may have alignment restrictions on the buffer. So maybe `buffer_header` isn't properly aligned. Does it work if you don't use `O_DIRECT`? – Barmar May 22 '15 at 07:33