summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>2003-12-23 20:03:55 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>2003-12-23 20:03:55 +0000
commitf6d10452a089a45e9bd0f36e9a34e9447e5b37c9 (patch)
tree87a9fa2f8cf4f1cdad423fe4eb9feb4e23d13086
parenta182437e162d0b848fe8389fa28e3c62f2b1ae37 (diff)
Based upon a freebsd change:
If an application closes one of its stdio descriptors (0..2), an excessive close() on one of these descriptors would cause a memory for this descriptor to be allocated in the internal descriptor table. When this descriptor gets used again, e.g. through the call to open() or socket(), the descriptor would be erroneously left in the blocking mode, and the whole application would get stuck on a blocking operation, e.g., in accept(2). but changed to not eat fds when a file that the thread kernel doesn't know about is closed.
-rw-r--r--lib/libpthread/uthread/uthread_close.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/lib/libpthread/uthread/uthread_close.c b/lib/libpthread/uthread/uthread_close.c
index cba4afab6db..c850d50a464 100644
--- a/lib/libpthread/uthread/uthread_close.c
+++ b/lib/libpthread/uthread/uthread_close.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_close.c,v 1.10 2003/02/14 03:58:42 marc Exp $ */
+/* $OpenBSD: uthread_close.c,v 1.11 2003/12/23 20:03:54 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -51,17 +51,13 @@ close(int fd)
/* This is a cancelation point: */
_thread_enter_cancellation_point();
- if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
- /*
- * Don't allow silly programs to close the kernel pipe.
- */
+ if ((fd < 0) || (fd >= _thread_dtablesize) ||
+ (fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
errno = EBADF;
ret = -1;
- }
- /*
- * Lock the file descriptor while the file is closed and get
- * the file descriptor status:
- */
+ } else if (_thread_fd_table[fd] == NULL)
+ /* unknown to thread kernel, let system handle the close */
+ ret = _thread_sys_close(fd);
else if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
/*
* Check if the file should be left as blocking.