[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.