Search code examples
clinuxprocfs

How to skip iteration if linux command fails in C


procfs.c

for(i=0;i<10;i++)
{
    //linux command to check process status
    sprintf(cmd, "cat /proc/%d/status", pid[i]);
    pf = popen(cmd,"r");
    fread(data, 1024, 1, pf);
    pclose(pf);

    //......big chunk of code afterwards
}

This is part of the code I'm running on my ubuntu. Basically, pid array has some the process id's, and I want those data to be parsed in some sort of way - which did succeed, so this isn't the problem.

The problem is with some part of the structure. Initially when I saved the pid array, I used "ls /proc/" command - the same way I used "cat /proc/%d/status" command in the above code - to check the /proc/ folder for all the processes that are currently running. The above code runs some time later, so when I use the pid array list for execution, some programs are no longer running, and thus, is not in /proc/ folder (for example, the program itself). So while all the pid data are printed out the way I want them to, some data come out as below:

enter image description here

In order to cope with this I added a line of code like this:

if(!pf) continue;

I thought that this would see that the command has failed, and skip this iteration, but it didn't change anything.

Is there any way to deal with that error message?

edit: I also tried if(pf < 0), but this didn't work either.


Solution

  • Use the stat function to see if a file exists, which works perfectly well for /proc files.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    struct stat buf;
    int ret = stat("/proc/2023", &buf);
    if(ret == -1) {
        //file doesn't exist, so proc with pid 2023 isn't running
    }
    else {
        //file exists, so proc with pid 2023 is running
    }
    

    Incorporating this into your loop, we have:

    for(i=0;i<10;i++)
    {
        struct stat buf;
        sprintf(cmd, "/proc/%d", pid[i]);
        int ret = stat(cmd, &buf);
        if(ret == -1) continue;
    
        //linux command to check process status
        sprintf(cmd, "cat /proc/%d/status", pid[i]);
        pf = popen(cmd,"r");
        fread(data, 1024, 1, pf);
        pclose(pf);
    
        //......big chunk of code afterwards
    }