From ed314ff7665c452389c34163c6b82eea9b3b804f Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 24 Feb 2004 23:08:48 +0000 Subject: [PATCH] doc/ 2004-02-24 Marcus Brinkmann * gpgme.texi (cancellation): New section. gpgme/ 2004-02-24 Marcus Brinkmann * gpgme.c (gpgme_cancel): New function. * engine-backend.h (struct engine_ops): New member cancel. * engine.h (_gpgme_engine_cancel): New prototype. * engine.c (_gpgme_engine_cancel): New function. * engine-gpgsm.c: Add new member cancel. (gpgsm_cancel): New function. (gpgsm_release): Use it. * rungpg.c: Add new member cancel. --- NEWS | 11 +++++++---- doc/ChangeLog | 4 ++++ doc/gpgme.texi | 39 +++++++++++++++++++++++++++++++++++++++ gpgme/ChangeLog | 11 +++++++++++ gpgme/engine-backend.h | 2 ++ gpgme/engine-gpgsm.c | 19 ++++++++++++++++--- gpgme/engine.c | 13 +++++++++++++ gpgme/engine.h | 2 ++ gpgme/gpgme.c | 16 ++++++++++++++++ gpgme/gpgme.h | 4 ++++ gpgme/rungpg.c | 3 ++- 11 files changed, 116 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 5812dcf..ae00052 100644 --- a/NEWS +++ b/NEWS @@ -54,16 +54,19 @@ Noteworthy changes in version 0.4.5 (unreleased) needed. Still, it is there if necessary. If in doubt, contact us and we will give our advise for your specific situation. - * A new key listing mode for validation of the key has been added. - See the manual. + * New key listing mode GPGME_KEYLIST_MODE_VALIDATE for validation of + the listed keys. + + * New interface gpgme_cancel() that can be used to cancel + asynchronous operations. * Interface changes relative to the 0.4.4 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_data_seek_cb_t CHANGED: off_t is now a largefile type. gpgme_data_seek CHANGED: off_t is now a largefile type. gpgme_data_new_from_filepart CHANGED: off_t is now a largefile type. -GPGME_KEYLIST_MODE_VALIDATE NEW. - +GPGME_KEYLIST_MODE_VALIDATE NEW +gpgme_cancel NEW Noteworthy changes in version 0.4.4 (2004-01-12) ------------------------------------------------ diff --git a/doc/ChangeLog b/doc/ChangeLog index 809cc14..4bad3c3 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2004-02-24 Marcus Brinkmann + + * gpgme.texi (cancellation): New section. + 2004-02-17 Werner Koch * gpgme.texi (Key Listing Mode): Doc KEYLIST_MODE_VALIDATE. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 3e5e898..4edf9ed 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -201,6 +201,7 @@ Run Control * Waiting For Completion:: Waiting until an operation is completed. * Using External Event Loops:: Advanced control over what happens when. +* Cancellation:: How to end pending operations prematurely. Using External Event Loops @@ -4315,6 +4316,7 @@ time. @menu * Waiting For Completion:: Waiting until an operation is completed. * Using External Event Loops:: Advanced control over what happens when. +* Cancellation:: How to end pending operations prematurely. @end menu @@ -4898,6 +4900,43 @@ my_gpgme_register_io_callback (void *data, int fd, int dir, gpgme_io_cb_t fnc, @end example +@node Cancellation +@subsection Cancellation +@cindex cryptographic operation, aborting +@cindex cryptographic operation, cancelling +@cindex aborting operations +@cindex cancelling operations + +Sometimes you do not want to wait for an operation to finish. If you +use external I/O callbacks, you can cancel a pending operation. +However, you must ensure that no other thread is currently using the +context in which the operation you want to cancel runs. This includes +callback handlers. So your external event loop must either be halted +or otherwise it must be guaranteed that no installed I/O callbacks are +run for this context. + +@deftypefun gpgme_ctx_t gpgme_cancel (@w{gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_cancel} attempts to cancel a pending +operation in the context @var{ctx}. This only works if you use the +global event loop or your own event loop. + +If you use the global event loop, you must not call @code{gpgme_wait} +or @code{gpgme_wait} during cancellation. After successful +cancellation, you can call @code{gpgme_wait} (optionally waiting on +@var{ctx}), and the context @var{ctx} will appear as if it had +finished with the error code @code{GPG_ERR_CANCEL}. + +If you use your an external event loop, you must ensure that no I/O +callbacks are invoked for this context (for example by halting the +event loop). On successful cancellation, all registered I/O callbacks +for this context will be unregistered, and a @code{GPGME_EVENT_DONE} +event with the error code @code{GPG_ERR_CANCEL} will be signaled. + +The function returns an error code if the cancellation failed (in this +case the state of @var{ctx} is not modified). +@end deftypefun + + @include gpl.texi diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 2a3488b..9000c17 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,14 @@ +2004-02-24 Marcus Brinkmann + + * gpgme.c (gpgme_cancel): New function. + * engine-backend.h (struct engine_ops): New member cancel. + * engine.h (_gpgme_engine_cancel): New prototype. + * engine.c (_gpgme_engine_cancel): New function. + * engine-gpgsm.c: Add new member cancel. + (gpgsm_cancel): New function. + (gpgsm_release): Use it. + * rungpg.c: Add new member cancel. + 2004-02-17 Werner Koch * gpgme.h: Add GPGME_KEYLIST_MODE_VALIDATE. diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h index 0632fb6..32fd242 100644 --- a/gpgme/engine-backend.h +++ b/gpgme/engine-backend.h @@ -84,6 +84,8 @@ struct engine_ops void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs); void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data); + + gpgme_error_t (*cancel) (void *engine); }; diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 46c8090..9981255 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -272,8 +272,8 @@ map_assuan_error (AssuanError err) } -static void -gpgsm_release (void *engine) +static gpgme_error_t +gpgsm_cancel (void *engine) { engine_gpgsm_t gpgsm = engine; @@ -290,6 +290,18 @@ gpgsm_release (void *engine) _gpgme_io_close (gpgsm->message_cb.fd); assuan_disconnect (gpgsm->assuan_ctx); +} + + +static void +gpgsm_release (void *engine) +{ + engine_gpgsm_t gpgsm = engine; + + if (!gpgsm) + return; + + gpgsm_cancel (engine); free (gpgsm->colon.attic.line); free (gpgsm); @@ -1540,5 +1552,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm = NULL, /* trustlist */ gpgsm_verify, gpgsm_set_io_cbs, - gpgsm_io_event + gpgsm_io_event, + gpgsm_cancel }; diff --git a/gpgme/engine.c b/gpgme/engine.c index 4c52599..6128c2f 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -484,3 +484,16 @@ _gpgme_engine_io_event (engine_t engine, (*engine->ops->io_event) (engine->engine, type, type_data); } + + +gpgme_error_t +_gpgme_engine_cancel (engine_t engine) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->cancel) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->cancel) (engine->engine); +} diff --git a/gpgme/engine.h b/gpgme/engine.h index d3a5403..42cec55 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -110,4 +110,6 @@ void _gpgme_engine_set_io_cbs (engine_t engine, void _gpgme_engine_io_event (engine_t engine, gpgme_event_io_t type, void *type_data); +gpgme_error_t _gpgme_engine_cancel (engine_t engine); + #endif /* ENGINE_H */ diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 84862fe..de70767 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -90,6 +90,22 @@ gpgme_new (gpgme_ctx_t *r_ctx) } +/* Cancel a pending asynchronous operation. */ +gpgme_error_t +gpgme_cancel (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + + err = _gpgme_engine_cancel (ctx->engine); + if (err) + return err; + + err = gpg_error (GPG_ERR_CANCELED); + _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err); + + return 0; +} + /* Release all resources associated with the given context. */ void gpgme_release (gpgme_ctx_t ctx) diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 4dd72ff..04615e6 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -995,6 +995,10 @@ unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, /* Crypto Operations. */ +/* Cancel a pending asynchronous operation. */ +gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx); + + struct _gpgme_invalid_key { struct _gpgme_invalid_key *next; diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 5a80f72..58c12f9 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -1664,5 +1664,6 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_trustlist, gpg_verify, gpg_set_io_cbs, - gpg_io_event + gpg_io_event, + NULL }; -- 2.26.2