Changed the close notify implementaion to allow for more than 256 fds.
We should write a test case for it, though.
This commit is contained in:
parent
2281024d4c
commit
01ad3b7562
@ -1,3 +1,10 @@
|
|||||||
|
2010-02-17 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* posix-io.c (notify_table): Change implementation.
|
||||||
|
(notify_table_item_t, notify_table_size, notify_table_lock): New.
|
||||||
|
(_gpgme_io_close, _gpgme_io_set_close_notify): Adjust for new
|
||||||
|
implementation.
|
||||||
|
|
||||||
2010-02-16 Werner Koch <wk@g10code.com>
|
2010-02-16 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpgme-tool.c (spacep, has_option, skip_options): New.
|
* gpgme-tool.c (spacep, has_option, skip_options): New.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* posix-io.c - Posix I/O functions
|
/* posix-io.c - Posix I/O functions
|
||||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
Copyright (C) 2001, 2002, 2004, 2005, 2007 g10 Code GmbH
|
Copyright (C) 2001, 2002, 2004, 2005, 2007, 2010 g10 Code GmbH
|
||||||
|
|
||||||
This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
|
|
||||||
@ -15,9 +15,8 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this program; if not, write to the Free Software
|
License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
*/
|
||||||
02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -73,13 +72,22 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct
|
/* The table to hold notification handlers. We use a linear search
|
||||||
|
and extend the table as needed. */
|
||||||
|
struct notify_table_item_s
|
||||||
{
|
{
|
||||||
|
int fd; /* -1 indicates an unused entry. */
|
||||||
_gpgme_close_notify_handler_t handler;
|
_gpgme_close_notify_handler_t handler;
|
||||||
void *value;
|
void *value;
|
||||||
} notify_table[256];
|
};
|
||||||
|
typedef struct notify_table_item_s *notify_table_item_t;
|
||||||
|
|
||||||
|
static notify_table_item_t notify_table;
|
||||||
|
static size_t notify_table_size;
|
||||||
|
DEFINE_STATIC_LOCK (notify_table_lock);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_gpgme_io_read (int fd, void *buffer, size_t count)
|
_gpgme_io_read (int fd, void *buffer, size_t count)
|
||||||
{
|
{
|
||||||
@ -149,6 +157,9 @@ int
|
|||||||
_gpgme_io_close (int fd)
|
_gpgme_io_close (int fd)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
_gpgme_close_notify_handler_t handler = NULL;
|
||||||
|
void *handler_value;
|
||||||
|
int idx;
|
||||||
|
|
||||||
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);
|
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);
|
||||||
|
|
||||||
@ -159,17 +170,26 @@ _gpgme_io_close (int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* First call the notify handler. */
|
/* First call the notify handler. */
|
||||||
if (fd >= 0 && fd < (int) DIM (notify_table))
|
LOCK (notify_table_lock);
|
||||||
|
for (idx=0; idx < notify_table_size; idx++)
|
||||||
{
|
{
|
||||||
if (notify_table[fd].handler)
|
if (notify_table[idx].fd == fd)
|
||||||
{
|
{
|
||||||
TRACE_LOG2 ("invoking close handler %p/%p",
|
handler = notify_table[idx].handler;
|
||||||
notify_table[fd].handler, notify_table[fd].value);
|
handler_value = notify_table[idx].value;
|
||||||
notify_table[fd].handler (fd, notify_table[fd].value);
|
notify_table[idx].handler = NULL;
|
||||||
notify_table[fd].handler = NULL;
|
notify_table[idx].value = NULL;
|
||||||
notify_table[fd].value = NULL;
|
notify_table[idx].fd = -1; /* Mark slot as free. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNLOCK (notify_table_lock);
|
||||||
|
if (handler)
|
||||||
|
{
|
||||||
|
TRACE_LOG2 ("invoking close handler %p/%p", handler, handler_value);
|
||||||
|
handler (fd, handler_value);
|
||||||
|
}
|
||||||
|
|
||||||
/* Then do the close. */
|
/* Then do the close. */
|
||||||
res = close (fd);
|
res = close (fd);
|
||||||
return TRACE_SYSRES (res);
|
return TRACE_SYSRES (res);
|
||||||
@ -180,19 +200,52 @@ int
|
|||||||
_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
|
_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
|
||||||
void *value)
|
void *value)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
|
int idx;
|
||||||
|
|
||||||
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd,
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd,
|
||||||
"close_handler=%p/%p", handler, value);
|
"close_handler=%p/%p", handler, value);
|
||||||
|
|
||||||
assert (fd != -1);
|
assert (fd != -1);
|
||||||
|
|
||||||
if (fd < 0 || fd >= (int) DIM (notify_table))
|
LOCK (notify_table_lock);
|
||||||
|
for (idx=0; idx < notify_table_size; idx++)
|
||||||
|
if (notify_table[idx].fd == -1)
|
||||||
|
break;
|
||||||
|
if (idx == notify_table_size)
|
||||||
{
|
{
|
||||||
errno = EINVAL;
|
/* We need to increase the size of the table. The approach we
|
||||||
return TRACE_SYSRES (-1);
|
take is straightforward to minimize the risk of bugs. */
|
||||||
|
notify_table_item_t newtbl;
|
||||||
|
size_t newsize = notify_table_size + 64;
|
||||||
|
|
||||||
|
newtbl = calloc (newsize, sizeof *newtbl);
|
||||||
|
if (!newtbl)
|
||||||
|
{
|
||||||
|
res = -1;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
for (idx=0; idx < notify_table_size; idx++)
|
||||||
|
newtbl[idx] = notify_table[idx];
|
||||||
|
for (; idx < newsize; idx++)
|
||||||
|
{
|
||||||
|
newtbl[idx].fd = -1;
|
||||||
|
newtbl[idx].handler = NULL;
|
||||||
|
newtbl[idx].value = NULL;
|
||||||
|
}
|
||||||
|
free (notify_table);
|
||||||
|
notify_table = newtbl;
|
||||||
|
idx = notify_table_size;
|
||||||
|
notify_table_size = newsize;
|
||||||
}
|
}
|
||||||
notify_table[fd].handler = handler;
|
notify_table[idx].fd = fd;
|
||||||
notify_table[fd].value = value;
|
notify_table[idx].handler = handler;
|
||||||
return TRACE_SYSRES (0);
|
notify_table[idx].value = value;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
UNLOCK (notify_table_lock);
|
||||||
|
|
||||||
|
return TRACE_SYSRES (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user