HelterSkelter HelterSkelter - 1 year ago 49
C Question

Flushing a pipe's buffer

I was playing with pipes, and took the following code from here; Once I understood I'm witnessing a block-buffering issue, I added a calling to

that wasn't present in the original code:

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

int main ()
FILE *ps_pipe;
FILE *grep_pipe;

int bytes_read;
int nbytes = 100;
char *my_string;

char buffer[100];

/* Open our two pipes */
ps_pipe = popen ("ls", "r");
grep_pipe = popen ("sort", "w");

/* Check that pipes are non-null, therefore open */
if ((!ps_pipe) || (!grep_pipe))
fprintf (stderr,
"One or both pipes failed.\n");

bytes_read = 0;
while (fgets(buffer, sizeof(buffer), ps_pipe))
fprintf(grep_pipe, "%s", buffer);
bytes_read += strlen(buffer);

printf("Total bytes read = %d\n", bytes_read);

/* Close ps_pipe, checking for errors */
if (pclose(ps_pipe) != 0)
fprintf(stderr, "Could not run 'ps', or other error.\n");

/* Close grep_pipe, cehcking for errors */
if (pclose(grep_pipe) != 0)
fprintf(stderr, "Could not run 'grep', or other error.\n");
} /* Exit! */

return 0;

EDIT [It's wrong, see answer below]: This way, I made sure that the pipe's buffer got flushed once the programed returned from its main function.

However, I still don't understand the reason: why would a pipe's kernel buffer be flushed to stdout? What does the former has to do with the latter? [EDIT: this is wrong, too, but was left for context]

Answer Source

The sleep has no effect on any kernel buffers.

The output you see on stdout is coming from the sort process, and is triggered by closing the grep_pipe.

Your program is in effect emulating the following shell script:

ls | sort

You open a pipe to read from ls, consume all of its output (from its stdout) and send this output to the stdin of the sort process. The sort can't sort the lines until it has all the lines, and it only knows it has all of the lines when its stdin is closed, which happens when you close the grep_pipe.

Once grep_pipe is closed, the sort does its work, producing the sorted lines to its stdout. The pclose does not return until the associated process has terminated, at which point the sort will have finished producing all of its output.