ravibhuva9955
ravibhuva9955

Reputation: 199

Fail to read command output using popen function

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?

Upvotes: 0

Views: 1670

Answers (1)

sestus
sestus

Reputation: 1927

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);
}

Upvotes: 2

Related Questions