Jason J.Y. Kim Jason J.Y. Kim - 6 months ago 20
Linux Question

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.

Answer

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, "cat /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
}