0

In Linux, I am finding pid of process by opening pipe with "pidof process_name" command and then reading it's output using fgets function. But it fails to find pid once in a while. Below is my code for finding pid of my process.

int FindPidByProcessName(char *pName)
{
    int pid = -1;
    char line[30] = { 0 };
    char buf[64] = { 0 };

    sprintf(buf, "pidof %s", pName);

    //pipe stream to process
    FILE *cmd = popen(buf, "r");

    if (NULL != cmd)
    {
        //get line from pipe stream
        fgets(line, 30, cmd);
        //close pipe
        pclose(cmd); cmd = NULL;

        //convert string to unsigned LONG integer
        pid = strtoul(line, NULL, 10);
    }

    return pid;
}

In output sometimes pid=0 comes even though process is available in "ps" command output. So, I try to find root cause behind this issue and i found something like input/output buffer mechanism is may creating issue in my scenario.

So I try to use sync() function before opening popen() and strangely my function starts working with 100% accuracy.

Now sync() function is taking too much time(approximately 2min sometime) to complete its execution which is not desirable. So i try to use fflush(), fsync() and fdatasync() but these all are not working appropriately.

So please anyone tell me what was the exact root cause behind this issue And how to solve this issue appropriately?

ravibhuva9955
  • 199
  • 1
  • 11
  • I don't understand your `while` loop - you are only calling `popen` one time, why are you looping while reading the output? – Ariel Jul 02 '14 at 09:45
  • Sorry for misunderstanding, It is just coding format which i use to write functions. It is having no meaning here as it is while(0). It will not be looped. – ravibhuva9955 Jul 02 '14 at 09:58
  • When the `pid` is `0` what is the contents of `line`? – Ariel Jul 02 '14 at 10:05
  • line variable is empty. See it is working 100 times but somehow it fail to work you can say once in a 100 time it is failing. – ravibhuva9955 Jul 02 '14 at 10:06
  • Add some code that runs `perror` if `fgets` returns null and tell us what the error message is. – Ariel Jul 02 '14 at 10:18

1 Answers1

2

Ok, the root cause of the error is stored in the errno variable (which btw you do not need to initialize). You can get an informative message using the fucntion

perror("Error: ");

If u use perror the variable errno is interpreted and you get a descriptive message.

Another way (the right way!) of finding the root cause is compiling your program with the -g flag and running the binary with gdb.

Edit: I strongly suggest the use of the gdb debugger so that you can look exactly what path does your code follow, so that you can explain the strange behaviour you described.

Second Edit: Errno stores the last error (return value). Instead of calling the functions as you do, you should write, and check errno immediately:

if ((<function>) <0) {
  perror("<function>: ");
  exit(1);
}
sestus
  • 1,875
  • 2
  • 16
  • 16
  • I am appreciating your thoughts. But i already did debugging using gdb to find root cause. Here the thing is no output is coming in fgets() when try to read FILE*. So it is my problem of some i/o buffer mechanism. – ravibhuva9955 Jul 02 '14 at 10:02
  • @ravibhuva9955 what does fgets() return? You can use the strace command to monitor your programms' system calls (including I/O operation). – sestus Jul 02 '14 at 10:05
  • fgets returning NULL in this case. – ravibhuva9955 Jul 02 '14 at 10:09
  • Ok, one case (above all other errors) that fgets returns null is when it is EOF. Can you confirm that it is not? Cause if it is EOF (nothing to read on pipe) this is a normal behaviour – sestus Jul 02 '14 at 10:34