2007-07-13 Marcus Brinkmann <marcus@g10code.de>
+ * Revert the "close_notify_handler" returns int stuff. Always
+ close in the _gpgme_io_close implementations.
+ * engine-gpgsm.c (status_handler): Try to terminate the connection
+ in case of error.
+ * w32-io.c (_gpgme_io_read): Return C->error_code in ERRNO.
+ (_gpgme_io_write): Likewise.
+
* priv-io.h (_gpgme_io_set_close_notify): Change type of HANDLER
to _gpgme_close_notify_handler.
(_gpgme_close_notify_handler): New type.
}
\f
-static int
+static void
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 (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
- if (gpgsm->status_cb.fd != -1)
- _gpgme_io_close (gpgsm->status_cb.fd);
if (gpgsm->input_cb.fd != -1)
_gpgme_io_close (gpgsm->input_cb.fd);
if (gpgsm->output_cb.fd != -1)
err = gpg_error (GPG_ERR_GENERAL);
DEBUG2 ("fd %d: ERR line - mapped to: %s\n",
fd, err? gpg_strerror (err):"ok");
+ /* Try our best to terminate the connection friendly. */
+ assuan_write_line (gpgsm->assuan_ctx, "BYE");
}
else if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
gpgsm->colon.any = 0;
err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, NULL);
}
- _gpgme_io_close (gpgsm->status_cb.fd);
DEBUG2 ("fd %d: OK line - final status: %s\n",
fd, err? gpg_strerror (err):"ok");
return err;
/* 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). */
+ but leave it to Assuan to close it. */
gpgsm->status_cb.fd = fdlist[0];
if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
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)
{
- really_close = notify_table[fd].handler (fd, notify_table[fd].value);
+ notify_table[fd].handler (fd, notify_table[fd].value);
notify_table[fd].handler = NULL;
notify_table[fd].value = NULL;
}
}
/* Then do the close. */
- if (really_close)
- return close (fd);
-
- return 0;
+ return close (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);
-typedef int (*_gpgme_close_notify_handler_t) (int,void*);
+typedef void (*_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);
}
-static int
+static void
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
_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)
{
- really_close = notify_table[fd].handler (fd, notify_table[fd].value);
+ notify_table[fd].handler (fd, notify_table[fd].value);
notify_table[fd].handler = NULL;
notify_table[fd].value = NULL;
}
/* Then do the close. */
- if (really_close)
+ chan = giochannel_table[fd];
+ if (chan)
{
- 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);
+ g_io_channel_shutdown (chan, 1, NULL);
+ g_io_channel_unref (chan);
+ giochannel_table[fd] = NULL;
}
+ else
+ _close (fd);
return 0;
}
DEBUG2 ("fd %d: about to read %d bytes\n", fd, (int)count );
if ( !c ) {
DEBUG0 ( "no reader thread\n");
+ errno = EBADF;
return -1;
}
if (c->eof_shortcut) {
return 0;
}
DEBUG1 ("fd %d: read error", fd );
+ errno = c->error_code;
return -1;
}
_gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer);
if ( !c ) {
DEBUG0 ( "no writer thread\n");
+ errno = EBADF;
return -1;
}
LOCK (c->mutex);
- if ( c->nbytes ) { /* bytes are pending for send */
+ if ( !c->error && c->nbytes ) { /* bytes are pending for send */
/* Reset the is_empty event. Better safe than sorry. */
if (!ResetEvent (c->is_empty))
DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
if ( c->error) {
UNLOCK (c->mutex);
DEBUG1 ("fd %d: write error", fd );
+ errno = c->error_code;
return -1;
}
int i;
_gpgme_close_notify_handler_t handler = NULL;
void *value = NULL;
- int really_close = 1;
if ( fd == -1 )
return -1;
}
UNLOCK (notify_table_lock);
if (handler)
- really_close = handler (fd, value);
+ handler (fd, value);
- if ( really_close && !CloseHandle (fd_to_handle (fd)) ) {
+ if ( !CloseHandle (fd_to_handle (fd)) ) {
DEBUG2 ("CloseHandle for fd %d failed: ec=%d\n",
fd, (int)GetLastError ());
return -1;