Using C popen(): read() work, but fread() doesn't

Viewed 150

After popen(), fread() always returns 0. Using read() with fileno(fp) works. What's going on?

Here is the code.

#include <errno.h>
#include <stdio.h>
#include <unistd.h>


int main(int argc, char *argv[]) {
    FILE *fp = popen("echo hello", "r");
    if (!fp) {
        perror("echo hello");
    } else {
        char buffer[128];
        for (;;) {
            int n;
            if (argc < 2) {
                n = fread(buffer, sizeof buffer, 1, fp);
            } else {
                n = read(fileno(fp), buffer, sizeof buffer);
            }
            printf("read %d bytes\n", n);
            if (n <= 0) break;
            fwrite(buffer, n, 1, stdout);
        }
        pclose(fp);
    }
}

The code uses fread() if there is no command line argument, read() otherwise.

Output:

$ ./test
read 0 bytes
$ ./test x
read 6 bytes
hello
read 0 bytes
1 Answers

You told fread() to read 1 item 100 bytes long. fread() returns the number of complete items that were read. Since the stream only has 6 bytes in it, it can't read any items before reaching EOF, so it returns 0.

Swap the order of the size and nitem arguments, then it will treat each byte as a separate item, and return the number of bytes that it read.

n = fread(buffer, 1, sizeof buffer, fp);
Related