From c4bb93ec28db2bab7e02c5e6c76645a7367bf4b2 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 13 Jul 2007 00:43:17 +0000 Subject: [PATCH] 2007-07-13 Marcus Brinkmann * assuan/assuan-io.c (_assuan_simple_read, _assuan_simple_write): Always use read/write (which means _gpgme_io_read and _gpgme_io_write). gpgme/ 2007-07-13 Marcus Brinkmann * priv-io.h (_gpgme_io_set_close_notify): Change type of HANDLER to _gpgme_close_notify_handler. (_gpgme_close_notify_handler): New type. (_gpgme_io_dup): Remove prototype. * posix-io.c (notify_table, _gpgme_io_set_close_notify): Change type of HANDLER to _gpgme_close_notify_handler_t. (_gpgme_io_close): Do not close the FD if handler returns 0. (_gpgme_io_dup): Remove function. * w32-io.c (notify_table, _gpgme_io_set_close_notify, _gpgme_io_close): Change type of HANDLER to _gpgme_close_notify_handler_t. (_gpgme_io_close): Do not close the FD if handler returns 0. (_gpgme_io_dup): Remove function. * w32-glib-io.c (_gpgme_io_dup): Remove function. (_gpgme_io_set_close_notify, notify_table): Change type of HANDLER to _gpgme_close_notify_handler_t. (_gpgme_io_close): Do not close the FD if handler returns 0. * rungpg.c (close_notify_handler): Change return type to int, return 1. * engine-gpgsm.c (close_notify_handler): Change return type to int, return 0 for status FD and 1 for all other FDs. (start): Do not duplicate the status FD. --- ChangeLog | 6 ++++++ assuan/README.1st | 8 +++++++- assuan/assuan-io.c | 4 ++-- gpgme/ChangeLog | 25 +++++++++++++++++++++++++ gpgme/engine-gpgsm.c | 22 +++++++++++----------- gpgme/posix-io.c | 21 ++++++++++----------- gpgme/priv-io.h | 6 ++---- gpgme/rungpg.c | 3 ++- gpgme/w32-glib-io.c | 35 ++++++++++++++++------------------- gpgme/w32-io.c | 42 +++++++++++++----------------------------- 10 files changed, 94 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff4d875c..e97bff37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-07-13 Marcus Brinkmann + + * assuan/assuan-io.c (_assuan_simple_read, _assuan_simple_write): + Always use read/write (which means _gpgme_io_read and + _gpgme_io_write). + 2007-07-09 Marcus Brinkmann Released 1.1.5. diff --git a/assuan/README.1st b/assuan/README.1st index c755cfec..8e805c39 100644 --- a/assuan/README.1st +++ b/assuan/README.1st @@ -27,7 +27,13 @@ updating this directory, are: We don't need this file as GPGME doesn't use sendmsg and recvmsg. If it would, we would need to pick up the W32 implementation. - Copyright 2004 g10 Code GmbH +* assuan-io.c +** _assuan_simple_read() and _assuan_simple_write() must always use + read()/write() (which actually translates to _gpgme_io_read() and + _gpgme_io_write()). + + + Copyright 2004, 2007 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/assuan/assuan-io.c b/assuan/assuan-io.c index 066231fb..a7f84492 100644 --- a/assuan/assuan-io.c +++ b/assuan/assuan-io.c @@ -51,7 +51,7 @@ _assuan_waitpid (pid_t pid, int *status, int options) ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN) /* Due to the peculiarities of the W32 API we can't use read for a network socket and thus we try to use recv first and fallback to read if recv detects that it is not a network socket. */ @@ -84,7 +84,7 @@ _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) { -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN) /* Due to the peculiarities of the W32 API we can't use write for a network socket and thus we try to use send first and fallback to write if send detects that it is not a network socket. */ diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 7b016259..33f9b23d 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,28 @@ +2007-07-13 Marcus Brinkmann + + * priv-io.h (_gpgme_io_set_close_notify): Change type of HANDLER + to _gpgme_close_notify_handler. + (_gpgme_close_notify_handler): New type. + (_gpgme_io_dup): Remove prototype. + * posix-io.c (notify_table, _gpgme_io_set_close_notify): Change + type of HANDLER to _gpgme_close_notify_handler_t. + (_gpgme_io_close): Do not close the FD if handler returns 0. + (_gpgme_io_dup): Remove function. + * w32-io.c (notify_table, _gpgme_io_set_close_notify, + _gpgme_io_close): Change type of HANDLER to + _gpgme_close_notify_handler_t. + (_gpgme_io_close): Do not close the FD if handler returns 0. + (_gpgme_io_dup): Remove function. + * w32-glib-io.c (_gpgme_io_dup): Remove function. + (_gpgme_io_set_close_notify, notify_table): Change type of HANDLER + to _gpgme_close_notify_handler_t. + (_gpgme_io_close): Do not close the FD if handler returns 0. + * rungpg.c (close_notify_handler): Change return type to int, + return 1. + * engine-gpgsm.c (close_notify_handler): Change return type to + int, return 0 for status FD and 1 for all other FDs. + (start): Do not duplicate the status FD. + 2007-07-12 Marcus Brinkmann * Makefile.am: Replace implicite rule by suffix rule. Add diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 0b78c29c..4827fbee 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -112,7 +112,7 @@ gpgsm_get_req_version (void) } -static void +static int close_notify_handler (int fd, void *opaque) { engine_gpgsm_t gpgsm = opaque; @@ -124,6 +124,9 @@ close_notify_handler (int fd, void *opaque) (*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag); gpgsm->status_cb.fd = -1; gpgsm->status_cb.tag = NULL; + /* We do not want to close the status FD, as it is controled by + Assuan. */ + return 0; } else if (gpgsm->input_cb.fd == fd) { @@ -146,6 +149,7 @@ close_notify_handler (int fd, void *opaque) gpgsm->message_cb.fd = -1; gpgsm->message_cb.tag = NULL; } + return 1; } @@ -983,20 +987,16 @@ start (engine_gpgsm_t gpgsm, const char *command) if (nfds < 1) return gpg_error (GPG_ERR_GENERAL); /* FIXME */ - /* We duplicate the file descriptor, so we can close it without - disturbing assuan. Alternatively, we could special case - status_fd and register/unregister it manually as needed, but this - increases code duplication and is more complicated as we can not - use the close notifications etc. */ - - gpgsm->status_cb.fd = _gpgme_io_dup (fdlist[0]); - if (gpgsm->status_cb.fd < 0) - return gpg_error_from_syserror (); + /* We used to duplicate the file descriptor so that we do not + disturb Assuan. But this gets in the way of the Handle-to-Thread + mapping in w32-io.c, so instead we just share the file descriptor + *carefully*, by avoiding to close it ourselves (this is achieved by + returning 0 from the close_notify_handler for this descriptor). */ + gpgsm->status_cb.fd = fdlist[0]; if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd, close_notify_handler, gpgsm)) { - close (gpgsm->status_cb.fd); gpgsm->status_cb.fd = -1; return gpg_error (GPG_ERR_GENERAL); } diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index 82142f84..6ebe42ae 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -69,7 +69,7 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd) static struct { - void (*handler) (int,void*); + _gpgme_close_notify_handler_t handler; void *value; } notify_table[256]; @@ -139,6 +139,8 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx) int _gpgme_io_close (int fd) { + int really_close = 1; + if (fd == -1) return -1; /* First call the notify handler. */ @@ -147,18 +149,22 @@ _gpgme_io_close (int fd) { if (notify_table[fd].handler) { - notify_table[fd].handler (fd, notify_table[fd].value); + really_close = notify_table[fd].handler (fd, notify_table[fd].value); notify_table[fd].handler = NULL; notify_table[fd].value = NULL; } } /* Then do the close. */ - return close (fd); + if (really_close) + return close (fd); + + return 0; } int -_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value) +_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, + void *value) { assert (fd != -1); @@ -493,10 +499,3 @@ _gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags) errno = saved_errno; return nwritten; } - - -int -_gpgme_io_dup (int fd) -{ - return dup (fd); -} diff --git a/gpgme/priv-io.h b/gpgme/priv-io.h index 6b422840..602fedee 100644 --- a/gpgme/priv-io.h +++ b/gpgme/priv-io.h @@ -47,7 +47,8 @@ int _gpgme_io_read (int fd, void *buffer, size_t count); int _gpgme_io_write (int fd, const void *buffer, size_t count); int _gpgme_io_pipe (int filedes[2], int inherit_idx); int _gpgme_io_close (int fd); -int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *), +typedef int (*_gpgme_close_notify_handler_t) (int,void*); +int _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, void *value); int _gpgme_io_set_nonblocking (int fd); @@ -64,7 +65,4 @@ int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock); line that the child process expects. */ int _gpgme_io_fd2str (char *buf, int buflen, int fd); -/* Like dup(). */ -int _gpgme_io_dup (int fd); - #endif /* IO_H */ diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index d6fd8fe1..91fc1adf 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -141,7 +141,7 @@ gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data) } -static void +static int close_notify_handler (int fd, void *opaque) { engine_gpg_t gpg = opaque; @@ -183,6 +183,7 @@ close_notify_handler (int fd, void *opaque) } } } + return 1; } /* If FRONT is true, push at the front of the list. Use this for diff --git a/gpgme/w32-glib-io.c b/gpgme/w32-glib-io.c index 183a560c..33727766 100644 --- a/gpgme/w32-glib-io.c +++ b/gpgme/w32-glib-io.c @@ -123,10 +123,11 @@ _gpgme_io_subsystem_init (void) static struct { - void (*handler) (int,void*); + _gpgme_close_notify_handler_t handler; void *value; } notify_table[MAX_SLAFD]; + int _gpgme_io_read (int fd, void *buffer, size_t count) { @@ -270,6 +271,7 @@ int _gpgme_io_close (int fd) { GIOChannel *chan; + int really_close = 1; if (fd < 0 || fd >= MAX_SLAFD) { @@ -281,29 +283,32 @@ _gpgme_io_close (int fd) DEBUG1 ("closing fd %d", fd); if (notify_table[fd].handler) { - notify_table[fd].handler (fd, notify_table[fd].value); + really_close = notify_table[fd].handler (fd, notify_table[fd].value); notify_table[fd].handler = NULL; notify_table[fd].value = NULL; } /* Then do the close. */ - chan = giochannel_table[fd]; - if (chan) + if (really_close) { - g_io_channel_shutdown (chan, 1, NULL); - g_io_channel_unref (chan); - giochannel_table[fd] = NULL; + chan = giochannel_table[fd]; + if (chan) + { + g_io_channel_shutdown (chan, 1, NULL); + g_io_channel_unref (chan); + giochannel_table[fd] = NULL; + } + else + _close (fd); } - else - _close (fd); - return 0; } int -_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value) +_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, + void *value) { assert (fd != -1); @@ -660,11 +665,3 @@ leave: free (pollfds_map); return count; } - - -int -_gpgme_io_dup (int fd) -{ - return _dup (fd); -} - diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 947bb62e..3b034f65 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -55,11 +55,12 @@ #define MAX_READERS 20 #define MAX_WRITERS 20 -static struct { - int inuse; - int fd; - void (*handler)(int,void*); - void *value; +static struct +{ + int inuse; + int fd; + _gpgme_close_notify_handler_t handler; + void *value; } notify_table[256]; DEFINE_STATIC_LOCK (notify_table_lock); @@ -726,8 +727,9 @@ int _gpgme_io_close ( int fd ) { int i; - void (*handler)(int, void*) = NULL; + _gpgme_close_notify_handler_t handler = NULL; void *value = NULL; + int really_close = 1; if ( fd == -1 ) return -1; @@ -738,7 +740,7 @@ _gpgme_io_close ( int fd ) LOCK (notify_table_lock); for ( i=0; i < DIM (notify_table); i++ ) { if (notify_table[i].inuse && notify_table[i].fd == fd) { - handler = notify_table[i].handler; + handler = notify_table[i].handler; value = notify_table[i].value; notify_table[i].handler = NULL; notify_table[i].value = NULL; @@ -748,9 +750,9 @@ _gpgme_io_close ( int fd ) } UNLOCK (notify_table_lock); if (handler) - handler (fd, value); + really_close = handler (fd, value); - if ( !CloseHandle (fd_to_handle (fd)) ) { + if ( really_close && !CloseHandle (fd_to_handle (fd)) ) { DEBUG2 ("CloseHandle for fd %d failed: ec=%d\n", fd, (int)GetLastError ()); return -1; @@ -760,7 +762,8 @@ _gpgme_io_close ( int fd ) } int -_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value) +_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, + void *value) { int i; @@ -1140,25 +1143,6 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd) return snprintf (buf, buflen, "%d", fd); } - -int -_gpgme_io_dup (int fd) -{ - HANDLE handle = fd_to_handle (fd); - HANDLE new_handle = fd_to_handle (fd); - - /* For NT we have to set the sync flag. It seems that the only - * way to do it is by duplicating the handle. Tsss.. */ - if (!DuplicateHandle( GetCurrentProcess(), handle, - GetCurrentProcess(), &new_handle, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - { - DEBUG1 ("** DuplicateHandle failed: ec=%d\n", (int) GetLastError()); - } - - return handle_to_fd (new_handle); -} - /* The following interface is only useful for GPGME Glib. */