Yougeshwar Khatri
Yougeshwar Khatri

Reputation: 325

popen function: Command not found or exited with error status in C program

I'm trying to execute external command from C program in ubuntu shell, below is my code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    int BUFSIZE = 128;
    char buf[BUFSIZE];
    FILE *fp;

    if ((fp = popen("ls", "r")) == NULL) {
        printf("Error opening pipe!\n");
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
        printf("%s", buf);
    }

    if(pclose(fp))  {
        printf("Command not found or exited with error status\n");
    }
    return 1;
}

but its throwing error: Command not found or exited with error status, I have installed new ubuntu 16.04 LTS

Upvotes: 0

Views: 2035

Answers (1)

jxh
jxh

Reputation: 70392

pclose() will return -1 on error. Otherwise, it returns the exit status. If the command was not found, popen() should have issued some kind of diagnostic (but, it may not have returned NULL).

If pclose() returns an exit status, you should check it as if it was returned by a call to wait().

In comments, you mentioned the error was because you had commented out the fgets() loop in your test code. When you do not read out the data from the fp, then the called process may be blocked trying to write data to it. When you call pclose(), the ls command may then terminate due to SIGPIPE, since it will be trying to write to a closed pipe. You can test this by checking the error status returned from pclose().

int status = pclose(fp);

if (status == 0) exit(0);

if (status == -1) {
    perror("pclose");
} else if (WIFSIGNALED(status)) {
    printf("terminating signal: %d", WTERMSIG(status));
} else if (WIFEXITED(status)) {
    printf("exit with status: %d", WEXITSTATUS(status));
} else {
    printf("unexpected: %d", status);
}

In the case the pclose() does return an error, you may be able to get more detailed error information from explain_pclose() (make sure the libexplain-dev is installed on your system).

The package may be named libexplain-devel on other Linux distros.

Upvotes: 2

Related Questions