This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Is read intended to immediately terminate on close of its fd?
- From: Fredrik Noring <noring at nocrew dot org>
- To: libc-alpha at sourceware dot org
- Date: Thu, 9 Aug 2007 21:20:36 +0200
- Subject: 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;
}