0

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.

Jason J.Y. Kim
  • 183
  • 2
  • 12

1 Answers1

2

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
}
Smeeheey
  • 9,906
  • 23
  • 39
  • just one thing, though. To include types.h header, I had to #include . – Jason J.Y. Kim Jun 09 '16 at 10:51
  • there should not be `cat` in the first `sprintf` of the `for` loop – ViKiG Jun 09 '16 at 11:26
  • Fixed typo. Thank you! – Smeeheey Jun 09 '16 at 11:27
  • @JasonJ.Y.Kim - I don't think this solution is sufficient by itself. I guess a process can stop at any time, i.e. after you check for the file but before you before you do the `cat`. Maybe you should swap the to code blocks so that you do the `cat` first. – Support Ukraine Jun 09 '16 at 12:14
  • @4386427 - Another method I tried was just go through all of the pid's until maximum pid that is set by procfs. But I did not want to do that because I set that maximum way too big just for experimental purpose, and that's why I used "ls" to check the files first. Also I didn't really expect the solutions to be perfect anyways. Smeeheey's answer was sufficient enough (even with the typo) to get me some ideas to solve the problem, which was perfectly good for me. – Jason J.Y. Kim Jun 09 '16 at 12:23