diff options
author | 2003-02-14 03:58:42 +0000 | |
---|---|---|
committer | 2003-02-14 03:58:42 +0000 | |
commit | 04397332fe2f3ba54d8fe0b9d437fe75b9e1b00b (patch) | |
tree | 42c24a47ced6db25c16d7aab8a2bc7ac8dadbf43 /lib/libpthread/uthread/uthread_fd.c | |
parent | white space (diff) | |
download | wireguard-openbsd-04397332fe2f3ba54d8fe0b9d437fe75b9e1b00b.tar.xz wireguard-openbsd-04397332fe2f3ba54d8fe0b9d437fe75b9e1b00b.zip |
fix bug that would leave an FD locked if dup'd, then closed.
Also, for safety lock the _thread_fd_table when removing entries.
Diffstat (limited to 'lib/libpthread/uthread/uthread_fd.c')
-rw-r--r-- | lib/libpthread/uthread/uthread_fd.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c index 4a48a8dd48c..ac81f56e1f1 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.20 2003/02/05 06:20:36 marc Exp $ */ +/* $OpenBSD: uthread_fd.c,v 1.21 2003/02/14 03:58:42 marc Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -233,10 +233,8 @@ _thread_fd_table_dup(int from_fd, int to_fd) entry = _thread_fd_table[to_fd]; if (entry != NULL) { ret = _FD_LOCK(to_fd, FD_RDWR, NULL); - if (ret != -1) { - if (--entry->refcnt == 0) - free(entry); - } + if (ret != -1) + _thread_fd_table_remove(to_fd); } else ret = 0; @@ -254,6 +252,26 @@ _thread_fd_table_dup(int from_fd, int to_fd) } /* + * Remove an fd entry from the table and free it if it's reference count + * goes to zero. The entry is assumed to be locked with a RDWR lock! It + * will be unlocked if it is not freed. + */ +void +_thread_fd_table_remove(int fd) +{ + struct fd_table_entry *entry; + + _SPINLOCK(&fd_table_lock); + entry = _thread_fd_table[fd]; + if (--entry->refcnt == 0) + free(entry); + else + _FD_UNLOCK(fd, FD_RDWR); + _thread_fd_table[fd] = NULL; + _SPINUNLOCK(&fd_table_lock); +} + +/* * Unlock the fd table entry for a given thread, fd, and lock type. */ void |