[LCP]fork() pipe() problem

Steve Baker ice at mama.indstate.edu
Sat Nov 16 00:17:01 UTC 2002


"mehul radheshyam choube" <mehulchoube_cprog at rediffmail.com> wrote:
> here is the code. please go through it and reply with comments.

  It would really be a good idea in the future, if you want good quick help,
to actually describe what the problem is or at the very least distill the
problem down to a smaller amount of code.  At any rate I think I may know what
your problem is:

>      if (pID == 0) {
...
>          data_processed = read(my_write[0], buffer, 10);
>          printf("(child) data_processed = %d buffer = %s err = %s\n", data_processed, buffer, strerror(errno));
...
>      }/* if (pID == 0) */
...
>      data_processed = write(my_write[1], "*mrc-mrc_*", strlen("*mrc-mrc_*"));
>      printf("data_processed = %d err = %s\n", data_processed, strerror(errno));

  Strings end with a 0, you didn't transfer the 0 at the end of "*mrc-mrc_*",
You should have said (strlen("*mrc-mrc_*")+1) or 11 for the buffer size, and
likewise read at least 11 bytes in the child process.

  Alternatively, in the child you could have done:

  data_processed = read(my_write[0], buffer, 10);
  buffer[10] = 0;

  Also you should know that reading from pipes and sockets is not the same as
reading from a file.  I believe, usually under Linux you have only a 4096 byte
buffer for your pipe or socket data, and it does not work as a proper ring
buffer, probably because I/O on such small amounts of data can be completed
atomically.  Writes that would overflow the buffer will block until a reader
empties the buffer, and reads that empty the buffer immediately return, even
if there will be more data to read. So if you need to read XX bytes of data,
your reader ought to be more like:

  int n, c;
  for(n=0,c=XX; c && (n=read(pipefd, buffer, c)) != -1; c-=n);
  if (n < 0) perror("pipe read");

  Alternatively if all that is too much to deal with and all you're sending
are strings you could just as well fdopen() the pipe on both ends and use
the standard C library f*() routines to do your I/O.  Also, if you need
bi-directional I/O, I recommend you look at socketpair(), its much less
cumbersome than using multiple pipes.

								- Steve



More information about the linuxCprogramming mailing list