[issue98] gpgme_cancel()

Marcus Brinkmann aegypten-issues at intevation.de
Tue Feb 24 23:02:05 CET 2004


New submission from Marcus Brinkmann <Marcus.Brinkmann at ruhr-uni-bochum.de>:

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 <aegypten-issues at intevation.de>
<https://intevation.de/roundup/aegypten/issue98>
______________________________________________________
-------------- next part --------------
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  <marcus at g10code.de>
+
+	* gpgme.texi (cancellation): New section.
+
 2004-02-17  Werner Koch  <wk at gnupg.org>
 
 	* 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
+
+
+ at node Cancellation
+ at subsection Cancellation
+ at cindex cryptographic operation, aborting
+ at cindex cryptographic operation, cancelling
+ at cindex aborting operations
+ at 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.
+
+ at 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
+ at 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).
+ at 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  <marcus at g10code.de>
+
+	* 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  <wk at gnupg.org>
 
 	* 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


More information about the Gpa-dev mailing list