[issue98] gpgme_cancel()
Marcus Brinkmann <[email protected]>
| Newsgroups | gmane.comp.encryption.gpg.gpa.devel |
|---|---|
| Message-ID | <[email protected]> |
New submission from Marcus Brinkmann <[email protected]>: I implemented gpgme_cancel() for gpgsm (is not implemented for gpg yet). Please try out if that works for you. This should even work if dirmngr hangs, but remember you must not call any I/O callbacks or anything during cancellation. The function is gpgme_cancel(ctx), it can potentially return an error. I compiled it, but didn't try to run it in any way. I will add a testcase later. ---------- assignedto: marc files: gpgme-cancel.diff messages: 408 nosy: marc, marcus priority: feature status: testing title: gpgme_cancel() topic: GPGME, KMail ______________________________________________________ Aegypten issue tracker <[email protected]> <https://intevation.de/roundup/aegypten/issue98> ______________________________________________________ _______________________________________________ Gpa-dev mailing list [email protected] http://lists.gnupg.org/mailman/listinfo/gpa-dev
gpgme-cancel.diff
(text/plain, 8.1 KB)
cvs server: Diffing . cvs server: Diffing assuan cvs server: Diffing complus cvs server: Diffing doc Index: doc/ChangeLog =================================================================== RCS file: /cvs/gnupg/gpgme/doc/ChangeLog,v retrieving revision 1.115 diff -u -r1.115 ChangeLog --- doc/ChangeLog 17 Feb 2004 15:27:42 -0000 1.115 +++ doc/ChangeLog 24 Feb 2004 22:40:56 -0000 @@ -1,3 +1,7 @@ +2004-02-24 Marcus Brinkmann <[email protected]> + + * gpgme.texi (cancellation): New section. + 2004-02-17 Werner Koch <[email protected]> * gpgme.texi (Key Listing Mode): Doc KEYLIST_MODE_VALIDATE. Index: doc/gpgme.texi =================================================================== RCS file: /cvs/gnupg/gpgme/doc/gpgme.texi,v retrieving revision 1.117 diff -u -r1.117 gpgme.texi --- doc/gpgme.texi 17 Feb 2004 15:27:42 -0000 1.117 +++ doc/gpgme.texi 24 Feb 2004 22:41:25 -0000 @@ -201,6 +201,7 @@ * 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 @@ @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 @@ -4896,6 +4898,43 @@ return 0; @} @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 cvs server: Diffing gpgme Index: gpgme/ChangeLog =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/ChangeLog,v retrieving revision 1.346 diff -u -r1.346 ChangeLog --- gpgme/ChangeLog 17 Feb 2004 15:27:42 -0000 1.346 +++ gpgme/ChangeLog 24 Feb 2004 22:41:38 -0000 @@ -1,3 +1,14 @@ +2004-02-24 Marcus Brinkmann <[email protected]> + + * 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 <[email protected]> * gpgme.h: Add GPGME_KEYLIST_MODE_VALIDATE. Index: gpgme/engine-backend.h =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/engine-backend.h,v retrieving revision 1.14 diff -u -r1.14 engine-backend.h --- gpgme/engine-backend.h 2 Oct 2003 15:03:01 -0000 1.14 +++ gpgme/engine-backend.h 24 Feb 2004 22:41:38 -0000 @@ -84,6 +84,8 @@ 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); }; Index: gpgme/engine-gpgsm.c =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/engine-gpgsm.c,v retrieving revision 1.91 diff -u -r1.91 engine-gpgsm.c --- gpgme/engine-gpgsm.c 17 Feb 2004 15:27:42 -0000 1.91 +++ gpgme/engine-gpgsm.c 24 Feb 2004 22:41:40 -0000 @@ -273,7 +273,7 @@ static void -gpgsm_release (void *engine) +gpgsm_cancel (void *engine) { engine_gpgsm_t gpgsm = engine; @@ -290,6 +290,18 @@ _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 @@ NULL, /* trustlist */ gpgsm_verify, gpgsm_set_io_cbs, - gpgsm_io_event + gpgsm_io_event, + gpgsm_cancel }; Index: gpgme/engine.c =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/engine.c,v retrieving revision 1.43 diff -u -r1.43 engine.c --- gpgme/engine.c 2 Oct 2003 15:03:01 -0000 1.43 +++ gpgme/engine.c 24 Feb 2004 22:41:41 -0000 @@ -484,3 +484,16 @@ (*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); + + (*engine->ops->cancel) (engine->engine); +} Index: gpgme/engine.h =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/engine.h,v retrieving revision 1.33 diff -u -r1.33 engine.h --- gpgme/engine.h 2 Oct 2003 15:03:01 -0000 1.33 +++ gpgme/engine.h 24 Feb 2004 22:41:41 -0000 @@ -110,4 +110,6 @@ 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 */ Index: gpgme/gpgme.c =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/gpgme.c,v retrieving revision 1.75 diff -u -r1.75 gpgme.c --- gpgme/gpgme.c 30 Sep 2003 17:19:13 -0000 1.75 +++ gpgme/gpgme.c 24 Feb 2004 22:41:42 -0000 @@ -90,6 +90,22 @@ } +/* 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) Index: gpgme/gpgme.h =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/gpgme.h,v retrieving revision 1.136 diff -u -r1.136 gpgme.h --- gpgme/gpgme.h 17 Feb 2004 15:27:42 -0000 1.136 +++ gpgme/gpgme.h 24 Feb 2004 22:41:46 -0000 @@ -995,6 +995,10 @@ /* 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; Index: gpgme/rungpg.c =================================================================== RCS file: /cvs/gnupg/gpgme/gpgme/rungpg.c,v retrieving revision 1.96 diff -u -r1.96 rungpg.c --- gpgme/rungpg.c 1 Feb 2004 14:34:54 -0000 1.96 +++ gpgme/rungpg.c 24 Feb 2004 22:41:49 -0000 @@ -1664,5 +1664,6 @@ gpg_trustlist, gpg_verify, gpg_set_io_cbs, - gpg_io_event + gpg_io_event, + NULL }; cvs server: Diffing m4 cvs server: Diffing tests cvs server: Diffing tests/gpg cvs server: Diffing tests/gpgsm