This is the mail archive of the libc-alpha@sourceware.org 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]
Other format: [Raw text]

Is read intended to immediately terminate on close of its fd?


Hello,

I'm not sure if this is entirely a glibc question, but is read(2) intended to terminate on close(2) of its fd, using pipe(2) and pthreads? Closing the other end of the pipe is the common case, of course, but what about closing the same fd that is used by read?

With recent glibc, the read call does terminate after a close of its fd, but not unless the process happens to be interrupted with e.g. an unrelated SIGALRM in which case the read call returns "Bad file descriptor". Wouldn't it be desired to have read terminate immediately after close of its fd, independently of any signals?

Attached sample program below, to demonstrate the effect.

Test results with Linux Fedora Core 4, 6 and 7 (glibc-2.6-4):

Reading...
Sleeping...
<...1 second...>
Closing...
Closed.
<...4 seconds...>
Alarmed.     # <--- read only terminates after this SIGALRM
Read.
Done.

Test results with Solaris 7 and 10 (read terminates immediately):

Reading...
Sleeping...
<...1 second...>
Closing...
Read.
Closed.
Done.

(I've also tested Mac OS X but it had other more severe issues with the close call.)

All the best,
Fredrik

#include <sys/types.h>
#include <sys/uio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>

int inout[2] = { -1, -1 };

void *closer(void *arg)
{
	fprintf(stderr, "Sleeping...\n");
	sleep(1);
	fprintf(stderr, "Closing...\n");
	close(inout[0]);
     /* close(inout[1]); */
	fprintf(stderr, "Closed.\n");
	return NULL;
}

void wakeup(int sig)
{
	fprintf(stderr, "Alarmed.\n");
}

int main(int argc, char *argv[])
{
	pthread_t th;
	char buf[1];
	
	pipe(inout);
	pthread_create(&th, NULL, closer, NULL);
	signal(SIGALRM, wakeup);
	alarm(5);
	
	fprintf(stderr, "Reading...\n");
	read(inout[0], buf, 1);
	fprintf(stderr, "Read.\n");
	
	pthread_join(th, NULL);
	fprintf(stderr, "Done.\n");
	
	return 0;
}


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