user6243824
user6243824

Reputation: 15

Read reports Bad File Descriptor despite getc successfully using the same fd to read a char

I have this C code:

FILE * fd = fopen(filename,"rb");
printf("%c ",(char)getc(fd)); // returns expected char
unsigned char buffer[10];
printf("%d ",read(fd, &buffer, 10)); // -1
printf("%d\n",errno); // 9

getc returns a char from the input file, as expected. However read returns an error (-1) and errno is set to 9 (bad file descriptor). Clearly the file descriptor is OK, since getc manages to use it to read a char.

What is the problem here?

Upvotes: 0

Views: 469

Answers (3)

shrike
shrike

Reputation: 4501

Instead of read(fd, &buffer, 10)
You want to use: fread(buffer, 1, 10, fd)

a FILE* is not a file-descriptor, it is a stream; that's why you have to use fread() (which needs a stream) instead of read() (which needs a file-descriptor). Also, buffer should be used instead of &buffer (which would lead to UB).

Upvotes: 1

atturri
atturri

Reputation: 1153

fopen and read are functions of different families. The families are:

  • fopen with fread (and also getc), from the C standard library.

  • open with read, from the POSIX specification.

The first family uses file pointers as FILE* types, while the second one uses file descriptors as int types. You can't mix the two families as long as you don't convert from one file descriptor type to the other. The conversion from FILE* to int is done with the POSIX function fileno.

In your case, use fread to read from the file.

Upvotes: 2

Henno Brandsma
Henno Brandsma

Reputation: 2166

It's weird code. You want to print the return code of read, not the data that was read?

First fix your read, you need fread instead of read:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *" stream );

The crash is caused because you overwrite the address of buffer, you don't write into the buffer itself.

So printf("%d ",read(fd, &buffer, 10)); should be printf("%d ",fread(buffer, 1, 10, fd)); instead, to read 10 (nmemb=10) bytes (size=1) into the buffer.

Upvotes: 0

Related Questions