aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS11
-rw-r--r--doc/ChangeLog4
-rw-r--r--doc/gpgme.texi39
-rw-r--r--gpgme/ChangeLog11
-rw-r--r--gpgme/engine-backend.h2
-rw-r--r--gpgme/engine-gpgsm.c19
-rw-r--r--gpgme/engine.c13
-rw-r--r--gpgme/engine.h2
-rw-r--r--gpgme/gpgme.c16
-rw-r--r--gpgme/gpgme.h4
-rw-r--r--gpgme/rungpg.c3
11 files changed, 116 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 5812dcfc..ae000522 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 809cc14d..4bad3c37 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -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.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 3e5e8989..4edf9edc 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 2a3488bf..9000c172 100644
--- a/gpgme/ChangeLog
+++ b/gpgme/ChangeLog
@@ -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.
diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h
index 0632fb66..32fd242e 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 46c8090c..99812552 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 4c525990..6128c2f7 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 d3a54036..42cec55c 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 84862fe5..de707671 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 4dd72ff2..04615e63 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 5a80f72e..58c12f92 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
};