+2007-07-13 Marcus Brinkmann <marcus@g10code.de>
+
+ * 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 <marcus@g10code.de>
Released 1.1.5.
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
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. */
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. */
+2007-07-13 Marcus Brinkmann <marcus@g10code.de>
+
+ * 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 <marcus@g10code.de>
* Makefile.am: Replace implicite rule by suffix rule. Add
}
\f
-static void
+static int
close_notify_handler (int fd, void *opaque)
{
engine_gpgsm_t gpgsm = 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)
{
gpgsm->message_cb.fd = -1;
gpgsm->message_cb.tag = NULL;
}
+ return 1;
}
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);
}
\f
static struct
{
- void (*handler) (int,void*);
+ _gpgme_close_notify_handler_t handler;
void *value;
} notify_table[256];
int
_gpgme_io_close (int fd)
{
+ int really_close = 1;
+
if (fd == -1)
return -1;
/* First call the notify handler. */
{
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);
errno = saved_errno;
return nwritten;
}
-
-
-int
-_gpgme_io_dup (int fd)
-{
- return dup (fd);
-}
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);
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 */
}
-static void
+static int
close_notify_handler (int fd, void *opaque)
{
engine_gpg_t gpg = opaque;
}
}
}
+ return 1;
}
/* If FRONT is true, push at the front of the list. Use this for
\f
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)
{
_gpgme_io_close (int fd)
{
GIOChannel *chan;
+ int really_close = 1;
if (fd < 0 || fd >= MAX_SLAFD)
{
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);
free (pollfds_map);
return count;
}
-
-
-int
-_gpgme_io_dup (int fd)
-{
- return _dup (fd);
-}
-
#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);
_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;
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;
}
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;
}
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;
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);
-}
-
\f
/* The following interface is only useful for GPGME Glib. */