diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2006-12-01 16:34:42 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2006-12-01 16:34:42 +0000 |
commit | cc3275586fa747dea8554f15810e367f8f6a7056 (patch) | |
tree | 6a7e5eb36a55a37da6bb030c5e6c92ebc8a39f4a | |
parent | a66448ed11b2f3fb46ae2bf1385cf042f09ac4ce (diff) |
Normally pipes created by threaded apps are left non-blocking after being
closed so that a threaded child process can still read it without blocking.
However, leaving stdin/out/err non-blocking when closed is bad because it
can be shared with non-threaded apps that can't deal with a non-blocking
file descriptor (i.e. cat). Therefore special case stdin/out/err pipes so
that they are reset to blocking upon a close(). Tested by robert@, jolan@
and myself with multiple OOo builds on mp systems where the problem was
seen more frequently.
-rw-r--r-- | lib/libpthread/uthread/uthread_fd.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c index c226cc801c2..6d840cb2005 100644 --- a/lib/libpthread/uthread/uthread_fd.c +++ b/lib/libpthread/uthread/uthread_fd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_fd.c,v 1.26 2006/09/26 15:09:59 kurt Exp $ */ +/* $OpenBSD: uthread_fd.c,v 1.27 2006/12/01 16:34:41 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -131,7 +131,8 @@ _thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags) * the parent and child will normally close the file * descriptor of the end of the pipe that they are not * using, which would then cause any reads to block - * indefinitely. + * indefinitely. However, stdin/out/err will be reset + * to avoid leaving them as non-blocking indefinitely. * * Files that we cannot fstat are probably not regular * so we don't bother with them. @@ -140,9 +141,9 @@ _thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags) * the status flags with a shared version. */ if (new_status_flags == NULL && - (_thread_sys_fstat(fd, &sb) == 0) && - ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && - (old_status_flags->flags & O_NONBLOCK) == 0)) + (old_status_flags->flags & O_NONBLOCK) == 0 && + (fd < 3 || (_thread_sys_fstat(fd, &sb) == 0 && + (S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode))))) { /* Get the current flags: */ flags = _thread_sys_fcntl(fd, F_GETFL, NULL); |