liv2hak
liv2hak

Reputation: 14970

Prevent popen() from displaying error on stderr

I have the following code to find the release of the Linux distribution that I am using.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{

    return print_osinfo();
}

int print_osinfo()
{
    FILE *fp;
    extern FILE* popen();
    char buffer[128];
    int index = 0;

    memset(buffer,0,sizeof(buffer));
    fp = popen("/etc/centos-release", "r");
    if(!fp)
    {
        pclose(fp);
        fp = popen("/etc/redhat-release", "r");
        if(!fp)
        {
            pclose(fp);
            return 1;
        }
    }
    while(fgets(buffer, sizeof(buffer), fp)!= NULL)
    {
        printf("%s\n",buffer);
    }
    pclose(fp);
    return 0;
}

If I run the above code on Ubuntu 14.04 I get the following error.

sh: 1: /etc/centos-release: not found

I fail to understand why it is not trying to open redhat-release and then return -1. Also, is there a way to prevent the above error from being displayed on the screen?

Upvotes: 1

Views: 587

Answers (1)

F. Stephen Q
F. Stephen Q

Reputation: 4306

popen is a function more suited for accessing the output of a subprocess than for simply accessing the contents of a file. For that, you should use fopen. fopen takes a file path and a mode as arguments, so all you would need to do is replace your popens with fopens and it should work perfectly.

If you really want to use popen, it takes a shell command as it's first argument, not a filename. Try popen("cat /etc/centos-release","r"); instead.

Now, you might be a bit confused, because both of these functions return a FILE pointer. fopen returns a pointer to the file you passed as an argument. popen, however, returns a pipe pointing to the output of the command you passed to it, which C sees as a FILE pointer. This is because, in C, all i/o is file access; C's only connection to the outside world is through files. So, in order to pass the output of some shell command, popen creates what C sees as a FILE in memory, containing the output of said shell command. Since it is rather absurd to run a whole other program (the shell command) just to do what fopen does perfectly well, it makes far more sense to just use fopen to read from files that already exist on disk.

Upvotes: 5

Related Questions