diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2003-12-23 20:03:55 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2003-12-23 20:03:55 +0000 |
commit | f6d10452a089a45e9bd0f36e9a34e9447e5b37c9 (patch) | |
tree | 87a9fa2f8cf4f1cdad423fe4eb9feb4e23d13086 | |
parent | a182437e162d0b848fe8389fa28e3c62f2b1ae37 (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.c | 16 |
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. |