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):
This commit is contained in:
Marcus Brinkmann 2002-02-06 01:20:49 +00:00
parent 4fa3008950
commit 69ab559a7b
16 changed files with 85 additions and 52 deletions

5
NEWS
View File

@ -9,6 +9,10 @@
current setting, a fucntion gpgme_get_keylist_mode was added to current setting, a fucntion gpgme_get_keylist_mode was added to
retrieve the current mode. 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 * The LENGTH argument to gpgme_data_new_from_filepart changed its
type from off_t to the unsigned size_t. 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. gpgme_data_new_from_filepart CHANGED: Type of LENGTH is size_t.
GpgmePassphraseCb CHANGED: Type of R_HD is void **. 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. gpgme_set_keylist_mode CHANGED: Type of return value is GpgmeError.
The function has a new meaning! The function has a new meaning!
gpgme_get_keylist_mode NEW gpgme_get_keylist_mode NEW

5
TODO
View File

@ -1,11 +1,6 @@
Hey Emacs, this is -*- outline -*- mode! Hey Emacs, this is -*- outline -*- mode!
* ABI's to break: * 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, ** string representation of non-secret keys and ATTR_IS_SECRET is NULL,
which can not be differentiated from the case that it is not which can not be differentiated from the case that it is not
representable. representable.

View 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> 2002-02-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Listing Mode): Update documentation. * gpgme.texi (Key Listing Mode): Update documentation.

View File

@ -1337,7 +1337,7 @@ This is the type of a trust item.
@item GPGME_ATTR_IS_SECRET @item GPGME_ATTR_IS_SECRET
This specifies if the key is a secret key. It is representable as a 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 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 @item GPGME_ATTR_KEY_REVOKED
This specifies if a sub key is revoked. It is representable as a 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 cryptographic operation, wait for
@cindex wait for completion @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 The function @code{gpgme_wait} does continue the pending operation
within the context @var{ctx}. In particular, it ensures the data within the context @var{ctx}. In particular, it ensures the data
exchange between @acronym{GPGME} and the crypto backend and watches 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 operation is completed or cancelled. Otherwise the function will not
block for a long time. 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 @end deftypefun

View 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> 2002-02-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.c (gpgme_set_keylist_mode): Possibly return an error * gpgme.c (gpgme_set_keylist_mode): Possibly return an error

View File

@ -72,8 +72,7 @@ gpgme_op_decrypt_verify (GpgmeCtx ctx,
err = gpgme_op_decrypt_verify_start (ctx, in, out); err = gpgme_op_decrypt_verify_start (ctx, in, out);
if (!err) if (!err)
{ {
gpgme_wait (ctx, 1); gpgme_wait (ctx, &err, 1);
err = ctx->error;
if (!err) if (!err)
*r_stat = _gpgme_intersect_stati (ctx->result.verify); *r_stat = _gpgme_intersect_stati (ctx->result.verify);
} }

View File

@ -160,9 +160,6 @@ gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
{ {
GpgmeError err = gpgme_op_decrypt_start (ctx, in, out); GpgmeError err = gpgme_op_decrypt_start (ctx, in, out);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View 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); GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View File

@ -212,7 +212,7 @@ gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher); int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher);
if (!err) if (!err)
{ {
gpgme_wait (ctx, 1); gpgme_wait (ctx, &err, 1);
/* Old gpg versions don't return status info for invalid /* Old gpg versions don't return status info for invalid
recipients, so we simply check whether we got any output at recipients, so we simply check whether we got any output at
all, and if not we assume that we don't have valid all, and if not we assume that we don't have valid

View File

@ -102,9 +102,6 @@ gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata)
{ {
GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata); GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View File

@ -224,9 +224,6 @@ gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
{ {
GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey); GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View File

@ -275,7 +275,7 @@ void gpgme_cancel (GpgmeCtx ctx);
/* Process the pending operation and, if HANG is non-zero, wait for /* Process the pending operation and, if HANG is non-zero, wait for
the pending operation to finish. */ 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. */ /* Functions to handle recipients. */

View File

@ -218,9 +218,6 @@ gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
{ {
GpgmeError err = gpgme_op_import_start (ctx, keydata); GpgmeError err = gpgme_op_import_start (ctx, keydata);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View 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); GpgmeError err = gpgme_op_sign_start (ctx, in, out, mode);
if (!err) if (!err)
{ gpgme_wait (ctx, &err, 1);
gpgme_wait (ctx, 1);
err = ctx->error;
}
return err; return err;
} }

View File

@ -353,8 +353,7 @@ gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig, GpgmeData text,
err = gpgme_op_verify_start (ctx, sig, text); err = gpgme_op_verify_start (ctx, sig, text);
if (!err) if (!err)
{ {
gpgme_wait (ctx, 1); gpgme_wait (ctx, &err, 1);
err = ctx->error;
if (!err) if (!err)
*r_stat = _gpgme_intersect_stati (ctx->result.verify); *r_stat = _gpgme_intersect_stati (ctx->result.verify);
} }

View File

@ -49,12 +49,17 @@ DEFINE_STATIC_LOCK (fd_table_lock);
static GpgmeIdleFunc idle_function; static GpgmeIdleFunc idle_function;
struct proc_s { struct proc_s
struct proc_s *next; {
int pid; struct proc_s *next;
GpgmeCtx ctx; int pid;
struct wait_item_s *handler_list; GpgmeCtx ctx;
int done; 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 { struct wait_item_s {
@ -154,9 +159,12 @@ _gpgme_remove_proc_from_wait_queue (int pid)
* and no (or the given) request has finished. * and no (or the given) request has finished.
**/ **/
GpgmeCtx 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 GpgmeCtx
@ -177,15 +185,29 @@ _gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
LOCK (proc_queue_lock); LOCK (proc_queue_lock);
for (proc = proc_queue; proc; proc = proc->next) 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)) if (!proc->done && !count_running_fds (proc))
set_process_done (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; hang = 0;
ctx->pending = 0; ctx->pending = 0;
proc->reported = 1;
} }
if (!proc->done) if (!proc->done)
any = 1; any = 1;
} }
UNLOCK (proc_queue_lock); UNLOCK (proc_queue_lock);
if (!any) if (!any)
@ -196,12 +218,13 @@ _gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
if (hang) if (hang)
run_idle (); run_idle ();
} }
while (hang && !ctx->cancel); while (hang && (!ctx || !ctx->cancel));
if (ctx->cancel) if (ctx && ctx->cancel)
{ {
/* FIXME: Paranoia? */
ctx->cancel = 0; ctx->cancel = 0;
ctx->error = mk_error (Canceled);
ctx->pending = 0; ctx->pending = 0;
ctx->error = mk_error (Canceled);
} }
return ctx; return ctx;
} }