-2

how exactly does the constant "PIPE_BUF" defined in limits.h work in linux. And when I use it as "count" in the system call "read(int fd, void *buf, size_t count);", does the system call "read", return one byte at a time and waits till it reaches the end of file? The code below takes two commands "last" and "sort" and makes two popen calls. Like ~$foo last sort In the code below I did not understand why the while loop was necessary if the read returns all available bytes only once. And also, how does the write to the popen understands that all input have been received and now it's time for the popen to execute the program.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>

int main (int argc, char* argv[])
{
  FILE *fin, *fout;
  char buffer[PIPE_BUF];
  int n;

  if (argc < 3)
    {
      printf("Need two parameters.\n");
      exit(1);
    }

  fin=popen(argv[1], "r");
  fout=popen(argv[2],"w");

  fflush(fout);

  while ((n=read(fileno(fin), buffer, PIPE_BUF)) > 0)
    {
      write(fileno(fout), buffer, n);
    }

  pclose(fin);
  pclose(fout);

  return 0;
}

2 Answers2

1

popen executes the program immediately, and creates a pipe that is connected to that program's input/output. All the programs run simultaneously.

A read call waits until some data (at least one byte) is available, and then returns all data that is available and fits into the buffer. If the program at the other end of the pipe wrote more than one byte, you will be able to read more than one byte, too.

You need a loop because the other program might write more data later. Only when the write end of the pipe is closed does read return zero.

CL.
  • 173,858
  • 17
  • 217
  • 259
0

According to the linux-source, there is no indication that the read() syscall would read 1 byte at a time. This would be very foolish so I'd never think Torvalds would accept that.

Answer to your question:

The read() function fills your buffer with some data, To read more data than the buffer can hold you need to keep calling it til you have read everything you need. This is why you would use a loop. It wouldn't be very efficient to have a buffer as large as the file you are reading.

Jocke
  • 673
  • 3
  • 8