469,610 Members | 2,211 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,610 developers. It's quick & easy.

fread() blocks when reading pipe with closed write end

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);
}
}
~

Nov 15 '05 #1
4 7193
>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
Nov 15 '05 #2
No, and no. Thank you! That was quite frustrating.

Nov 15 '05 #3
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.
Nov 15 '05 #4
On 27 Oct 2005 11:03:18 -0700, "bill" <bi**********@gmail.com> 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>>
Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Christian Hammers | last post: by
2 posts views Thread by Luc Holland | last post: by
2 posts views Thread by Josh Wilson | last post: by
6 posts views Thread by Patrice Kadionik | last post: by
5 posts views Thread by David Mathog | last post: by
20 posts views Thread by ericunfuk | last post: by
15 posts views Thread by =?ISO-8859-15?Q?L=E9na=EFc?= Huard | last post: by
reply views Thread by devrayhaan | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.