diff options
author | Christopher Faylor <me@cgf.cx> | 2013-12-01 17:52:48 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2013-12-01 17:52:48 +0000 |
commit | f456b9f6f8efcb1e7472d31860b5815ccd614aa4 (patch) | |
tree | c263f4fab9d502e46cea61f8254fbbc088a274e7 | |
parent | 10a5939224465e3feb8e19208f187904000a0c38 (diff) | |
download | cygnal-f456b9f6f8efcb1e7472d31860b5815ccd614aa4.tar.gz cygnal-f456b9f6f8efcb1e7472d31860b5815ccd614aa4.tar.bz2 cygnal-f456b9f6f8efcb1e7472d31860b5815ccd614aa4.zip |
* dtable.cc (dtable::find_unused_handle): Fix off-by-one error. Always exit
through the bottom.
(cygwin_attach_handle_to_fd): Make sure that fd tab is locked for the duration
of this function.
* dtable.h (dtable::lock): Make public.
(dtable::unlock): Ditto.
(dtable): Remove friends.
-rw-r--r-- | winsup/cygwin/ChangeLog | 10 | ||||
-rw-r--r-- | winsup/cygwin/dtable.cc | 24 | ||||
-rw-r--r-- | winsup/cygwin/dtable.h | 13 |
3 files changed, 29 insertions, 18 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index fc599bf36..c68ced329 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2013-12-01 Christopher Faylor <me.cygwin2013@cgf.cx> + + * dtable.cc (dtable::find_unused_handle): Fix off-by-one error. Always + exit through the bottom. + (cygwin_attach_handle_to_fd): Make sure that fd tab is locked for the + duration of this function. + * dtable.h (dtable::lock): Make public. + (dtable::unlock): Ditto. + (dtable): Remove friends. + 2013-12-01 Corinna Vinschen <corinna@vinschen.de> * dtable.cc (dtable::extend): Change local variable new_size to size_t diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 3934e008a..485e79c5d 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -223,17 +223,22 @@ dtable::delete_archetype (fhandler_base *fh) int dtable::find_unused_handle (size_t start) { - size_t extendby = (start > size) ? start - size : NOFILE_INCR; + size_t extendby = (start >= size) ? 1 + start - size : NOFILE_INCR; + /* This do loop should only ever execute twice. */ + int res = -1; do { for (size_t i = start; i < size; i++) /* See if open -- no need for overhead of not_open */ if (fds[i] == NULL) - return i; + { + res = (int) i; + break; + } } while (extend (extendby)); - return -1; + return res; } void @@ -251,14 +256,19 @@ extern "C" int cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin, DWORD myaccess) { + cygheap->fdtab.lock (); if (fd == -1) fd = cygheap->fdtab.find_unused_handle (); fhandler_base *fh = build_fh_name (name); if (!fh) - return -1; - cygheap->fdtab[fd] = fh; - cygheap->fdtab[fd]->inc_refcnt (); - fh->init (handle, myaccess, bin ?: fh->pc_binmode ()); + fd = -1; + else + { + cygheap->fdtab[fd] = fh; + cygheap->fdtab[fd]->inc_refcnt (); + fh->init (handle, myaccess, bin ?: fh->pc_binmode ()); + } + cygheap->fdtab.unlock (); return fd; } diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index f0e484c01..0ec7b3a75 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -34,8 +34,6 @@ class dtable static const int initial_archetype_size = 8; size_t first_fd_for_open; int cnt_need_fixup_before; - void lock () {lock_process::locker.acquire ();} - void unlock () {lock_process::locker.release ();} public: size_t size; @@ -87,15 +85,8 @@ public: void delete_archetype (fhandler_base *); void fixup_before_exec (DWORD win_proc_id); void fixup_before_fork (DWORD win_proc_id); - friend void dtable_init (); - friend void __stdcall close_all_files (bool); - friend int dup_finish (int, int, int); - friend class fhandler_base; - friend class cygheap_fdmanip; - friend class cygheap_fdget; - friend class cygheap_fdnew; - friend class cygheap_fdenum; - friend class lock_process; + void lock () {lock_process::locker.acquire ();} + void unlock () {lock_process::locker.release ();} }; fhandler_base *build_fh_dev (const device&, const char * = NULL); |