The issue when using popen and pclose

c, shell, unix

Solution

- "Broken pipe" is displayed by `ls` because the SIGPIPE signal is raised.

- SIGPIPE is raised because `ls` is trying to output to a closed pipe.

- The pipe is closed because your program immediately calls `pclose()` after your `popen()`.

This behaviour of `pclose` can be further understood by reading the documentation. Basically, `pclose` will:

- Close a stream opened by a `popen()` call.

- Wait for the command to terminate.

- Return the termination status of the command.

Since it closes the stream and then waits for the command to terminate, `ls` can sometimes try to write to the stream after it was closed hence causing the mentioned scenario.

Additionally, as kingsindian pointed out, SIGPIPE may not be raised always. This is because the command can actually finish doing its work before the main process calls `pclose()`. Since this behaviour is unpredictable, I suggest implementing some synchronization. You always want to know exactly what state your program is in at all times.

As a side note, pipes were meant for inter-process communication. If your main process just opens and closes a pipe, you might be better off using `fork()` and `exec()`.

Problem

I have a program which uses `popen` and `pclose`: ``` #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/wait.h> int main(void) { FILE *fp = NULL; int ret_val = 0; fp = popen("ls *", "r"); if (NULL == fp) { printf("popen error\n"); return 1; } ret_val = pclose(fp); if (-1 == ret_val) { printf("pclose error\n"); return 1; } else { printf("%d,%d,%d\n",ret_val, WIFEXITED(ret_val), WEXITSTATUS(ret_val)); } return 0; } ``` The output of the program is: ``` ./test Broken Pipe 36096,1,141 ``` My questions are: - Why is there a "Broken pipe"? - Why is the exit status code 141? I think "ls *" executed successfully and therefore, the exit status should be 0.

Original source