fread() blocks when reading pipe with closed write end

Discussion in 'C Programming' started by bill, Oct 27, 2005.

  1. bill

    bill Guest

    I am confused by the behavior of the following code. The function
    copy() takes two FILE *'s and copies the data from one to the other.
    In the main routine, I create a pipe and copy stdin to the write end
    while copying the read end to stdout. If the child handles copying the
    read end of the pipe to stdout, the main program returns. If the child
    handles copying stdin to the write end of the pipe, the parent hangs in
    copy(), blocking on fget() (or fread()). I've executed in gdb and
    watched the child close the write end of the pipe before the parent
    ever gets to the read, read the data off the pipe, and then block
    indefinitely. The write end is closed, why doesn't fget() or fread()
    return EOF? And why does the behavior change when the role of
    parent/child is reversed? (replace "if(pid)" with "if(!pid)")

    I've removed most of the error checking from this for clarity, but
    point out that the fclose() succeeds. (I've tried replacing fclose
    with close(filedes[1]), to no affect.)

    #include<stdio.h>
    #include<inttypes.h>

    void
    copy(FILE *in, FILE *out)
    {
    int x;
    while( (x = fgetc(in)) != EOF)
    if (fwrite( &x, sizeof(x),1,out) != 1)
    break;
    /*
    while( fread(&x, sizeof(x),1,in) == 1)
    if (fwrite( &x, sizeof(x),1,out) != 1)
    break;
    */
    return;
    }

    int
    main()
    {
    int filedes[2];
    FILE *a, *b;
    int pid;

    pipe(filedes);
    a = fdopen(filedes[0],"r");
    b = fdopen(filedes[1],"w");
    pid = fork();
    if (!pid) {
    copy(a, stdout);
    }
    else {
    int err;
    copy (stdin, b);
    err = fclose(b);
    fprintf(stderr,"fclose returned: %d\n",err);
    }
    }
    ~
     
    bill, Oct 27, 2005
    #1
    1. Advertising

  2. >I am confused by the behavior of the following code. The function
    >copy() takes two FILE *'s and copies the data from one to the other.
    >In the main routine, I create a pipe and copy stdin to the write end
    >while copying the read end to stdout. If the child handles copying the
    >read end of the pipe to stdout, the main program returns. If the child
    >handles copying stdin to the write end of the pipe, the parent hangs in
    >copy(), blocking on fget() (or fread()). I've executed in gdb and
    >watched the child close the write end of the pipe before the parent


    Did the *parent* close the write end of the pipe?

    >ever gets to the read, read the data off the pipe, and then block
    >indefinitely. The write end is closed,


    Are *ALL* of the write ends closed?

    >why doesn't fget() or fread()
    >return EOF? And why does the behavior change when the role of
    >parent/child is reversed? (replace "if(pid)" with "if(!pid)")
    >


    Gordon L. Burditt
     
    Gordon Burditt, Oct 27, 2005
    #2
    1. Advertising

  3. bill

    bill Guest

    No, and no. Thank you! That was quite frustrating.
     
    bill, Oct 27, 2005
    #3
  4. bill

    Default User Guest

    bill wrote:

    > No, and no. Thank you! That was quite frustrating.


    What and what? Thank who? What was?



    Brian

    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, Oct 27, 2005
    #4
  5. On 27 Oct 2005 11:03:18 -0700, "bill" <> wrote:

    >I am confused by the behavior of the following code. The function
    >copy() takes two FILE *'s and copies the data from one to the other.
    >In the main routine, I create a pipe and copy stdin to the write end
    >while copying the read end to stdout. If the child handles copying the
    >read end of the pipe to stdout, the main program returns. If the child
    >handles copying stdin to the write end of the pipe, the parent hangs in
    >copy(), blocking on fget() (or fread()). I've executed in gdb and
    >watched the child close the write end of the pipe before the parent
    >ever gets to the read, read the data off the pipe, and then block
    >indefinitely. The write end is closed, why doesn't fget() or fread()
    >return EOF? And why does the behavior change when the role of
    >parent/child is reversed? (replace "if(pid)" with "if(!pid)")
    >
    >I've removed most of the error checking from this for clarity, but
    >point out that the fclose() succeeds. (I've tried replacing fclose
    >with close(filedes[1]), to no affect.)
    >
    >#include<stdio.h>
    >#include<inttypes.h>
    >
    >void
    >copy(FILE *in, FILE *out)
    >{
    > int x;
    > while( (x = fgetc(in)) != EOF)
    > if (fwrite( &x, sizeof(x),1,out) != 1)


    In addition to any other problems, you read one byte but write more
    than one (probably four).

    > break;
    > /*
    > while( fread(&x, sizeof(x),1,in) == 1)
    > if (fwrite( &x, sizeof(x),1,out) != 1)
    > break;
    > */
    > return;
    >}
    >
    >int
    >main()
    >{
    > int filedes[2];
    > FILE *a, *b;
    > int pid;
    >
    > pipe(filedes);
    > a = fdopen(filedes[0],"r");
    > b = fdopen(filedes[1],"w");
    > pid = fork();
    > if (!pid) {
    > copy(a, stdout);
    > }
    > else {
    > int err;
    > copy (stdin, b);
    > err = fclose(b);
    > fprintf(stderr,"fclose returned: %d\n",err);
    > }
    >}
    >~



    <<Remove the del for email>>
     
    Barry Schwarz, Nov 9, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. matt
    Replies:
    1
    Views:
    270
    George Ogata
    Aug 6, 2004
  2. Brent Heinz
    Replies:
    0
    Views:
    95
    Brent Heinz
    Dec 7, 2005
  3. Anders Lindgren
    Replies:
    3
    Views:
    139
    MenTaLguY
    Mar 6, 2007
  4. Matt Kruse
    Replies:
    5
    Views:
    309
    Richard Cornford
    Sep 9, 2003
  5. Replies:
    1
    Views:
    226
    Ben Morrow
    Jun 2, 2004
Loading...

Share This Page