This is the mail archive of the glibc-linux@ricardo.ecn.wfu.edu mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

pipe() in glibc2.0.7


Hello,

I've a problem using pipes in glibc 2.0.7pre6 (SuSE 6.1) and I wonder, if
someone can tell me, what is going wrong here. As I understood the
manual (edition 0.08DRAFT, chapter 15, Pipes and FIFOs), a 'read()'
call should not block, if the file-descriptor is a pipe, that has been
closed on the writing side, but should instead return with EOF
(i.e. 'read()' should return 0). Unfortunately I find, that the
'read()' call blocks, when there are no more data available in the pipe
and the writing side of the pipe has been closed, leaving the
(reading) parent process sleeping and the (writing) child process
zombified, because the parent cannot reach the 'waitpid()' call). I
have veryfied that the child closes the pipe successfully before
exiting.

It might be related, that unread data in the pipe do not seem to be
discarded, when the writing side closes the pipe, i.e. if I call
'waitpid()' in the parent process before 'read()', I get all data
wrote to the pipe (and after the last character is read, the 'read()' call
hangs again and the parent process remains sleeping until I kill it). 

Sorry, if this is a silly question, but I am completely stuck here.

This is the program I used (it's the modfied demo program of chapter
15):

-------------------------------------------------------------------
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

void
read_from_pipe(int file)
{
  char c;
  int count;

  do {
    count = read(file, &c, 1);
    if (count < 0) {
      perror("read()");
      exit(1);
    }
    else if (count == 1) putchar(c);
  } while ((count > 0));
}

void
write_to_pipe(int file)
{
  char line[100];

  strcpy(line, "hello world!\n");
  if (write(file, line, strlen(line)) < strlen(line)) {
    fprintf(stderr, "write error.\n");
    exit(1);
  }
  strcpy(line, "goodbye, world!\n");
  if (write(file, line, strlen(line)) < strlen(line)) {
    fprintf(stderr, "write error.\n");
    exit(1);
  }
  fprintf(stderr, "close: %d\n", close(file));
}

int 
main(void)
{
  pid_t pid, p;
  int status;
  int mypipe[2];

if (pipe(mypipe))
  {
    fprintf(stderr, "Pipe failed.\n");
    return EXIT_FAILURE;
  }

pid = fork();
if (pid == (pid_t)0)
  {
    write_to_pipe(mypipe[1]);
    return EXIT_SUCCESS;
  }
else if (pid < (pid_t)0)
  {
    fprintf(stderr, "Fork failed.\n");
    return EXIT_FAILURE;
  }
else 
  {
    fprintf(stderr, "child PID %d\n", pid);
    read_from_pipe(mypipe[0]);
    p = waitpid(pid, &status, 0);
    fprintf(stderr, "pid: %d, status ist: %d\n", p, status);
    return EXIT_SUCCESS;
  }
}
-------------------------------------------------------------------

Regards,

Bernd

-- 
Bernd Rinn
Fakultaet fuer Physik
Universitaet Konstanz

Tel. 07531/88-3812, 
e-mail: Bernd.Rinn@uni-konstanz.de
PGP-Fingerprint: 1F AC 31 64 FF EF A9 67  6E 0D 4C 26 0B E7 ED 5C

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]