diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index f1ea70e1..2d04c3cd 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,18 @@ +2007-01-18 Marcus Brinkmann + + * data.h (_gpgme_data_get_fd): Add prototype. + (gpgme_data_get_fd_cb): New type. + (struct _gpgme_data_cbs): New member get_fd. + * data.c (_gpgme_data_get_fd): New function. + * data-fd.c (fd_get_fd): New function. + (fd_cbs): Add fd_get_fd. + * data-stream.c (stream_get_fd): New function. + (stream_cbs): Add stream_get_fd. + * data-mem.c (mem_cbs): Add NULL for get_fd callback. + * data-user.c (user_cbs): Likewise. + * engine-gpgsm.c (gpgsm_set_fd) [USE_DESCRIPTOR_PASSING]: Try to + short-cut by passing the data descriptor directly. + 2007-01-17 Marcus Brinkmann * w32-io.c (build_commandline): Quote all command line arguments. diff --git a/gpgme/data-fd.c b/gpgme/data-fd.c index e3542bad..2c65be19 100644 --- a/gpgme/data-fd.c +++ b/gpgme/data-fd.c @@ -49,12 +49,20 @@ fd_seek (gpgme_data_t dh, off_t offset, int whence) } +static int +fd_get_fd (gpgme_data_t dh) +{ + return (dh->data.fd); +} + + static struct _gpgme_data_cbs fd_cbs = { fd_read, fd_write, fd_seek, - NULL + NULL, + fd_get_fd }; diff --git a/gpgme/data-mem.c b/gpgme/data-mem.c index 6e948ee0..c7698116 100644 --- a/gpgme/data-mem.c +++ b/gpgme/data-mem.c @@ -157,7 +157,8 @@ static struct _gpgme_data_cbs mem_cbs = mem_read, mem_write, mem_seek, - mem_release + mem_release, + NULL }; diff --git a/gpgme/data-stream.c b/gpgme/data-stream.c index e7601685..18ad111d 100644 --- a/gpgme/data-stream.c +++ b/gpgme/data-stream.c @@ -71,12 +71,20 @@ stream_seek (gpgme_data_t dh, off_t offset, int whence) } +static int +stream_get_fd (gpgme_data_t dh) +{ + return fileno (dh->data.stream); +} + + static struct _gpgme_data_cbs stream_cbs = { stream_read, stream_write, stream_seek, - NULL + NULL, + stream_get_fd }; diff --git a/gpgme/data-user.c b/gpgme/data-user.c index f3deb32f..90a0f421 100644 --- a/gpgme/data-user.c +++ b/gpgme/data-user.c @@ -71,7 +71,8 @@ static struct _gpgme_data_cbs user_cbs = user_read, user_write, user_seek, - user_release + user_release, + NULL }; diff --git a/gpgme/data.c b/gpgme/data.c index 788aaf0b..22768ff5 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -280,3 +280,14 @@ _gpgme_data_outbound_handler (void *opaque, int fd) dh->pending_len -= nwritten; return 0; } + + +/* Get the file descriptor associated with DH, if possible. Otherwise + return -1. */ +int +_gpgme_data_get_fd (gpgme_data_t dh) +{ + if (!dh || !dh->cbs->get_fd) + return -1; + return (*dh->cbs->get_fd) (dh); +} diff --git a/gpgme/data.h b/gpgme/data.h index 80a86e69..370751d5 100644 --- a/gpgme/data.h +++ b/gpgme/data.h @@ -52,12 +52,16 @@ typedef off_t (*gpgme_data_seek_cb) (gpgme_data_t dh, off_t offset, /* Release the data object with the handle DH. */ typedef void (*gpgme_data_release_cb) (gpgme_data_t dh); +/* Get the FD associated with the handle DH, or -1. */ +typedef int (*gpgme_data_get_fd_cb) (gpgme_data_t dh); + struct _gpgme_data_cbs { gpgme_data_read_cb read; gpgme_data_write_cb write; gpgme_data_seek_cb seek; gpgme_data_release_cb release; + gpgme_data_get_fd_cb get_fd; }; struct gpgme_data @@ -121,4 +125,8 @@ gpgme_error_t _gpgme_data_new (gpgme_data_t *r_dh, void _gpgme_data_release (gpgme_data_t dh); +/* Get the file descriptor associated with DH, if possible. Otherwise + return -1. */ +int _gpgme_data_get_fd (gpgme_data_t dh); + #endif /* DATA_H */ diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index b170180d..7bb71cf2 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -692,22 +692,26 @@ gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt) dir = iocb_data->dir; #if USE_DESCRIPTOR_PASSING - { - int fds[2]; + /* We try to short-cut the communication by giving GPGSM direct + access to the file descriptor, rather than using a pipe. */ + iocb_data->server_fd = _gpgme_data_get_fd (iocb_data->data); + if (iocb_data->server_fd < 0) + { + int fds[2]; - if (_gpgme_io_pipe (fds, 0) < 0) - return gpg_error_from_errno (errno); + if (_gpgme_io_pipe (fds, 0) < 0) + return gpg_error_from_errno (errno); - iocb_data->fd = dir ? fds[0] : fds[1]; - iocb_data->server_fd = dir ? fds[1] : fds[0]; + iocb_data->fd = dir ? fds[0] : fds[1]; + iocb_data->server_fd = dir ? fds[1] : fds[0]; - if (_gpgme_io_set_close_notify (iocb_data->fd, - close_notify_handler, gpgsm)) - { - err = gpg_error (GPG_ERR_GENERAL); - goto leave_set_fd; - } - } + if (_gpgme_io_set_close_notify (iocb_data->fd, + close_notify_handler, gpgsm)) + { + err = gpg_error (GPG_ERR_GENERAL); + goto leave_set_fd; + } + } #endif fd = iocb_data->server_fd; diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 3e64d47b..dcf897c8 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -72,7 +72,7 @@ extern "C" { AM_PATH_GPGME macro) check that this header matches the installed library. Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "1.1.3-cvs1200" +#define GPGME_VERSION "1.1.3-cvs1202"