doc/
authorMarcus Brinkmann <mb@g10code.com>
Wed, 6 Feb 2002 01:20:49 +0000 (01:20 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Wed, 6 Feb 2002 01:20:49 +0000 (01:20 +0000)
2002-02-06  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (Waiting For Completion): Adjust doc to changes in
the code.

gpgme/
2002-02-06  Marcus Brinkmann  <marcus@g10code.de>

* wait.c (gpgme_wait): Add new argument STATUS, in which the
status of the returned context is returned.
(_gpgme_wait_on_condition): Rework the function a bit, to make it
aware of cancelled processes, and to allow to use gpgme_wait with
CTX being NULL (as documented in the source).
(struct proc_s): New member REPORTED.
* gpgme.h: Fix prototype.
* verify.c (gpgme_op_verify): Fix use of gpgme_wait.
* sign.c (gpgme_op_sign):
* import.c (gpgme_op_import):
* genkey.c (gpgme_op_genkey):
* export.c (gpgme_op_export):
* encrypt.c (gpgme_op_encrypt):
* delete.c (gpgme_op_delete):
* decrypt-verify.c (gpgme_op_decrypt_verify):

16 files changed:
NEWS
TODO
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/decrypt-verify.c
gpgme/decrypt.c
gpgme/delete.c
gpgme/encrypt.c
gpgme/export.c
gpgme/genkey.c
gpgme/gpgme.h
gpgme/import.c
gpgme/sign.c
gpgme/verify.c
gpgme/wait.c

diff --git a/NEWS b/NEWS
index 5375328614730c2bca81724812ae95ddab873a23..27bcb132eee0f44dc79bf46a677130828e05059c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,10 @@
    current setting, a fucntion gpgme_get_keylist_mode was added to
    retrieve the current mode.
 
+ * gpgme_wait accepts a new argument STATUS to return the error status
+   of the operation on the context.  Its definition is closer to
+   waitpid() now than before.
+
  * The LENGTH argument to gpgme_data_new_from_filepart changed its
    type from off_t to the unsigned size_t.
 
@@ -27,6 +31,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 gpgme_data_new_from_filepart   CHANGED: Type of LENGTH is size_t.
 GpgmePassphraseCb               CHANGED: Type of R_HD is void **.
+gpgme_wait                      CHANGED: New argument STATUS.
 gpgme_set_keylist_mode          CHANGED: Type of return value is GpgmeError.
                                 The function has a new meaning!
 gpgme_get_keylist_mode          NEW
diff --git a/TODO b/TODO
index 7eb7de964250b33036e6e2be5bbbc4ad7e1d5cd3..ac886cf6473408d289c2fd6da982eaf06cd8040a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,11 +1,6 @@
 Hey Emacs, this is -*- outline -*- mode!
 
 * ABI's to break:
-** The resulting error of an operation can not be retrieved
-   seperately; the op_foobar operations can't be implemented by the
-   user, they are not merely convenience, but necessity, while the
-   op_foobar_start functions for these are unusable (or render the
-   context unusable, your choice).
 ** string representation of non-secret keys and ATTR_IS_SECRET is NULL,
    which can not be differentiated from the case that it is not
    representable.
index ce4bf44c7ac1ad7132159f845fa6073dd0b78f17..5b617efa28db5516a5ca7486dfa143308ab8ca3b 100644 (file)
@@ -1,3 +1,8 @@
+2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (Waiting For Completion): Adjust doc to changes in
+       the code.
+
 2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.texi (Key Listing Mode): Update documentation.
index e2f68ef82890a01f8f1945a0412f1b2434267866..2b4cf5a070e6e6b7f1d043fdb7fab2c40ad94416 100644 (file)
@@ -1337,7 +1337,7 @@ This is the type of a trust item.
 @item GPGME_ATTR_IS_SECRET
 This specifies if the key is a secret key.  It is representable as a
 string or a number.  If the key is a secret key, the representation is
-``1'' or @code{1}, otherwise it is NULL or @code{0}.
+``1'' or @code{1}, otherwise it is @code{NULL} or @code{0}.
 
 @item GPGME_ATTR_KEY_REVOKED
 This specifies if a sub key is revoked.  It is representable as a
@@ -2233,7 +2233,7 @@ later point.
 @cindex cryptographic operation, wait for
 @cindex wait for completion
 
-@deftypefun GpgmeCtx gpgme_wait (@w{GpgmeCtx @var{ctx}}, @w{int @var{hang}})
+@deftypefun GpgmeCtx gpgme_wait (@w{GpgmeCtx @var{ctx}}, @w{GpgmeError *@var{status}}, @w{int @var{hang}})
 The function @code{gpgme_wait} does continue the pending operation
 within the context @var{ctx}.  In particular, it ensures the data
 exchange between @acronym{GPGME} and the crypto backend and watches
@@ -2243,7 +2243,14 @@ If @var{hang} is true, the function does not return until the
 operation is completed or cancelled.  Otherwise the function will not
 block for a long time.
 
-The function returns @var{ctx}.
+The error status of the finished operation is returned in
+@var{status}.
+
+The @var{ctx} argument can be @code{NULL}.  In that case,
+@code{gpgme_wait} waits for any context to complete its operation.
+
+The function returns the @var{ctx} of the context which has finished
+the operation.
 @end deftypefun
 
 
index 05cae535df7706f84179a80d482fa872ef312528..8d0a863fb6c582639f3dfadad8f39ff5cd9ee7cb 100644 (file)
@@ -1,3 +1,21 @@
+2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+       * wait.c (gpgme_wait): Add new argument STATUS, in which the
+       status of the returned context is returned.
+       (_gpgme_wait_on_condition): Rework the function a bit, to make it
+       aware of cancelled processes, and to allow to use gpgme_wait with
+       CTX being NULL (as documented in the source).
+       (struct proc_s): New member REPORTED.
+       * gpgme.h: Fix prototype.
+       * verify.c (gpgme_op_verify): Fix use of gpgme_wait.
+       * sign.c (gpgme_op_sign): 
+       * import.c (gpgme_op_import): 
+       * genkey.c (gpgme_op_genkey): 
+       * export.c (gpgme_op_export): 
+       * encrypt.c (gpgme_op_encrypt): 
+       * delete.c (gpgme_op_delete): 
+       * decrypt-verify.c (gpgme_op_decrypt_verify): 
+
 2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.c (gpgme_set_keylist_mode): Possibly return an error
index bfdc011d4988297c5c53535215249aa590fa5974..940b53cd2926e4ab057ddc6c2e4ae24b2aed86c5 100644 (file)
@@ -72,8 +72,7 @@ gpgme_op_decrypt_verify (GpgmeCtx ctx,
   err = gpgme_op_decrypt_verify_start (ctx, in, out);
   if (!err)
     {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
+      gpgme_wait (ctx, &err, 1);
       if (!err)
        *r_stat = _gpgme_intersect_stati (ctx->result.verify);
     }
index ff834b5227ae99a9d392fab5b527f16ba655ac1a..8374c0fef4ffbc1c71583fdb850d3ac784af57ad 100644 (file)
@@ -160,9 +160,6 @@ gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
 {
   GpgmeError err = gpgme_op_decrypt_start (ctx, in, out);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index 5116877974aaabd89237b377fd5360b93ac67095..9b2735a43e24595f443deb3505194df01273b877 100644 (file)
@@ -152,9 +152,6 @@ gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
 {
   GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index 37c509645030cab98edd836db58261fc24b42d99..1984db3b21b38fb382cb0ec0fd3ce8a79400a37d 100644 (file)
@@ -212,7 +212,7 @@ gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
   int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher);
   if (!err)
     {
-      gpgme_wait (ctx, 1);
+      gpgme_wait (ctx, &err, 1);
       /* Old gpg versions don't return status info for invalid
         recipients, so we simply check whether we got any output at
         all, and if not we assume that we don't have valid
index da86967f4992d2f8949d44c7d44284fc17634a5b..bbee68d8c9ae061d1b4448b7801612abc43dde25 100644 (file)
@@ -102,9 +102,6 @@ gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata)
 {
   GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index 94d0e37d51eda3c71db0790d5faedc6e41125307..2537c8ce12bba559c08abaa1fc3a46ec7279db1e 100644 (file)
@@ -224,9 +224,6 @@ gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
 {
   GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index 60dd975a49386170a7f120cecd3f375d13d3a163..a16d03e856fb124d792352e237a0c0780507c3c3 100644 (file)
@@ -275,7 +275,7 @@ void       gpgme_cancel (GpgmeCtx ctx);
 
 /* Process the pending operation and, if HANG is non-zero, wait for
    the pending operation to finish.  */
-GpgmeCtx gpgme_wait (GpgmeCtx ctx, int hang);
+GpgmeCtx gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang);
 
 
 /* Functions to handle recipients.  */
index 63e4d6d635b7861b8f66adae151bd43ba50f6c1e..6d0705102f22dd6630043d7f62fa5f083e2c4833 100644 (file)
@@ -218,9 +218,6 @@ gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
 {
   GpgmeError err = gpgme_op_import_start (ctx, keydata);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index 0c2514c80e3bc49225a18153b276dd8e9facf461..3d4896f05e030ad063a94895f8780f7b21760e72 100644 (file)
@@ -255,9 +255,6 @@ gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode)
 {
   GpgmeError err = gpgme_op_sign_start (ctx, in, out, mode);
   if (!err)
-    {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
-    }
+    gpgme_wait (ctx, &err, 1);
   return err;
 }
index bd66dd5e2804dd915a13c9054a1c6b3c02fe2974..2cc8893622f5d76579e450bdd0c5447c25e63f7c 100644 (file)
@@ -353,8 +353,7 @@ gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig, GpgmeData text,
   err = gpgme_op_verify_start (ctx, sig, text);
   if (!err)
     {
-      gpgme_wait (ctx, 1);
-      err = ctx->error;
+      gpgme_wait (ctx, &err, 1);
       if (!err)
        *r_stat = _gpgme_intersect_stati (ctx->result.verify);
     }
index 639f2070d1687cf7af8be700c54a33c5cea1bdcd..83b8908d33a095c24efdc064fc89e12fa29ec30c 100644 (file)
@@ -49,12 +49,17 @@ DEFINE_STATIC_LOCK (fd_table_lock);
 static GpgmeIdleFunc idle_function;
 
 
-struct proc_s {
-    struct proc_s *next;
-    int pid;
-    GpgmeCtx ctx;
-    struct wait_item_s *handler_list;
-    int done;
+struct proc_s
+{
+  struct proc_s *next;
+  int pid;
+  GpgmeCtx ctx;
+  struct wait_item_s *handler_list;
+  /* Non-zero if the process has been completed.  */
+  int done;
+  /* Non-zero if the status for this process has been returned
+     already.  */
+  int reported;
 };
 
 struct wait_item_s {
@@ -154,9 +159,12 @@ _gpgme_remove_proc_from_wait_queue (int pid)
  *  and no (or the given) request has finished.
  **/
 GpgmeCtx 
-gpgme_wait (GpgmeCtx ctx, int hang)
+gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang)
 {
-  return _gpgme_wait_on_condition (ctx, hang, NULL);
+  GpgmeCtx retctx = _gpgme_wait_on_condition (ctx, hang, NULL);
+  if (status)
+    *status = retctx->error;
+  return retctx;
 }
 
 GpgmeCtx 
@@ -177,15 +185,29 @@ _gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
          LOCK (proc_queue_lock);
          for (proc = proc_queue; proc; proc = proc->next)
            {
+             /* A process is done if it has completed voluntarily, or
+                if the context it lived in was canceled.  */
              if (!proc->done && !count_running_fds (proc))
                set_process_done (proc);
-             if (ctx && proc->done && proc->ctx == ctx)
+             else if (!proc->done && proc->ctx->cancel)
+               {
+                 set_process_done (proc);
+                 proc->ctx->cancel = 0;
+                 proc->ctx->error = mk_error (Canceled);
+               }
+             /* A process that is done is eligible for election if it
+                is in the requested context or if it was not yet
+                reported.  */
+             if (proc->done && (proc->ctx == ctx || (!ctx && !proc->reported)))
                {
+                 if (!ctx)
+                   ctx = proc->ctx;
                  hang = 0;
                  ctx->pending = 0;
+                 proc->reported = 1;
                }
-                if (!proc->done)
-                 any = 1;
+             if (!proc->done)
+               any = 1;
             }
          UNLOCK (proc_queue_lock);
          if (!any)
@@ -196,12 +218,13 @@ _gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
       if (hang)
        run_idle ();
     }
-  while (hang && !ctx->cancel);
-  if (ctx->cancel)
+  while (hang && (!ctx || !ctx->cancel));
+  if (ctx && ctx->cancel)
     {
+      /* FIXME: Paranoia?  */
       ctx->cancel = 0;
-      ctx->error = mk_error (Canceled);
       ctx->pending = 0;
+      ctx->error = mk_error (Canceled);
     }
   return ctx;
 }