From b92c8f057ce62a6676955dccdbae2aa8d083d0ee Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 3 Jul 2002 01:57:03 +0000 Subject: [PATCH] 2002-07-03 Marcus Brinkmann * gpgme.c (gpgme_set_io_cbs): Deal with CTX being NULL. * gpgme.c (_gpgme_op_event_cb_user): New function. * op-support.c (_gpgme_op_reset): Support a new mode of operation for private or user event loop. Use new user event callback wrapper. * trustlist.c (gpgme_op_trustlist_start): Use this new mode. * keylist.c (gpgme_op_keylist_start): Likewise. * rungpg.c (_gpgme_gpg_io_event): New function. * rungpg.h (_gpgme_gpg_io_event): New prototype. * engine-gpgsm.c (_gpgme_gpg_io_event): New function. * engine-gpgsm.h (_gpgme_gpgsm_io_event): New prototype. * engine.c (_gpgme_engine_io_event): New function. * engine.h (_gpgme_engine_io_event): New prototype. * keylist.c (finish_key): Call _gpgme_engine_io_event, and move the real work for the default IO callback routines to ... (_gpgme_op_keylist_event_cb): ... here. New function. * trustlist.c (trustlist_colon_handler): Signal GPGME_EVENT_NEXT_TRUSTITEM. Move queue manipulation to ... (_gpgme_op_trustlist_event_cb): ... here. New function. * gpgme.c (_gpgme_op_event_cb): Call _gpgme_op_keylist_event_cb and _gpgme_op_trustlist_event_cb when appropriate. * ops.h (_gpgme_op_keylist_event_cb): New prototype. (_gpgme_op_trustlist_event_cb): Likewise. * op-support.c (_gpgme_op_reset): Add comment why we don't use the user provided event handler directly. * gpgme.h (GpgmeRegisterIOCb): Return GpgmeError value, and TAG in a pointer argument. * wait.c (_gpgme_add_io_cb): Likewise. * wait.h (_gpgme_add_io_cb): Likewise for prototype. * rungpg.c (_gpgme_gpg_add_io_cb): Call IO_CBS->add with new argument. Fix up error handling. * engine-gpgsm.c (_gpgme_gpgsm_add_io_cb): Call IO_CBS->add with new argument, fix up error handling. --- gpgme/ChangeLog | 38 ++++++++++++++++++++++++++ gpgme/engine-gpgsm.c | 25 ++++++++++++----- gpgme/engine-gpgsm.h | 1 + gpgme/engine.c | 20 ++++++++++++++ gpgme/engine.h | 2 ++ gpgme/gpgme.c | 40 +++++++++++++++++++++++---- gpgme/gpgme.h | 17 ++++++------ gpgme/keylist.c | 64 ++++++++++++++++++++++++------------------- gpgme/op-support.c | 16 +++++++++-- gpgme/ops.h | 5 ++++ gpgme/rungpg.c | 22 ++++++++++----- gpgme/rungpg.h | 1 + gpgme/trustlist.c | 65 ++++++++++++++++++++++++++------------------ gpgme/wait.c | 17 ++++++------ gpgme/wait.h | 4 +-- 15 files changed, 242 insertions(+), 95 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index ebae975..86df1c7 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,41 @@ +2002-07-03 Marcus Brinkmann + + * gpgme.c (gpgme_set_io_cbs): Deal with CTX being NULL. + + * gpgme.c (_gpgme_op_event_cb_user): New function. + * op-support.c (_gpgme_op_reset): Support a new mode of operation + for private or user event loop. Use new user event callback + wrapper. + * trustlist.c (gpgme_op_trustlist_start): Use this new mode. + * keylist.c (gpgme_op_keylist_start): Likewise. + + * rungpg.c (_gpgme_gpg_io_event): New function. + * rungpg.h (_gpgme_gpg_io_event): New prototype. + * engine-gpgsm.c (_gpgme_gpg_io_event): New function. + * engine-gpgsm.h (_gpgme_gpgsm_io_event): New prototype. + * engine.c (_gpgme_engine_io_event): New function. + * engine.h (_gpgme_engine_io_event): New prototype. + * keylist.c (finish_key): Call _gpgme_engine_io_event, and move + the real work for the default IO callback routines to ... + (_gpgme_op_keylist_event_cb): ... here. New function. + * trustlist.c (trustlist_colon_handler): Signal + GPGME_EVENT_NEXT_TRUSTITEM. Move queue manipulation to ... + (_gpgme_op_trustlist_event_cb): ... here. New function. + * gpgme.c (_gpgme_op_event_cb): Call _gpgme_op_keylist_event_cb + and _gpgme_op_trustlist_event_cb when appropriate. + * ops.h (_gpgme_op_keylist_event_cb): New prototype. + (_gpgme_op_trustlist_event_cb): Likewise. + * op-support.c (_gpgme_op_reset): Add comment why we don't use the + user provided event handler directly. + * gpgme.h (GpgmeRegisterIOCb): Return GpgmeError value, and TAG in + a pointer argument. + * wait.c (_gpgme_add_io_cb): Likewise. + * wait.h (_gpgme_add_io_cb): Likewise for prototype. + * rungpg.c (_gpgme_gpg_add_io_cb): Call IO_CBS->add with new + argument. Fix up error handling. + * engine-gpgsm.c (_gpgme_gpgsm_add_io_cb): Call IO_CBS->add with + new argument, fix up error handling. + 2002-06-28 Marcus Brinkmann * keylist.c (gpgme_op_keylist_ext_start): Always use our own FD diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 67f1e7c..5dd28f9 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -1290,14 +1290,14 @@ static GpgmeError _gpgme_gpgsm_add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd, GpgmeIOCb handler) { - GpgmeError err = 0; + GpgmeError err; - iocbd->tag = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv, - iocbd->fd, iocbd->dir, - handler, iocbd->data); - if (!iocbd->tag) - err = mk_error (General_Error); - if (!err && !iocbd->dir) + err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv, + iocbd->fd, iocbd->dir, + handler, iocbd->data, &iocbd->tag); + if (err) + return err; + if (!iocbd->dir) /* FIXME Kludge around poll() problem. */ err = _gpgme_io_set_nonblocking (iocbd->fd); return err; @@ -1338,6 +1338,12 @@ _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs) gpgsm->io_cbs = *io_cbs; } +void +_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data) +{ + if (gpgsm->io_cbs.event) + (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data); +} #else /* ENABLE_GPGSM */ @@ -1486,4 +1492,9 @@ _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs) { } +void +_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data) +{ +} + #endif /* ! ENABLE_GPGSM */ diff --git a/gpgme/engine-gpgsm.h b/gpgme/engine-gpgsm.h index cbfc4d9..6092829 100644 --- a/gpgme/engine-gpgsm.h +++ b/gpgme/engine-gpgsm.h @@ -64,5 +64,6 @@ GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text); GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque); void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs); +void _gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data); #endif /* ENGINE_GPGSM_H */ diff --git a/gpgme/engine.c b/gpgme/engine.c index 91d10c0..52d00e1 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -587,6 +587,26 @@ _gpgme_engine_set_io_cbs (EngineObject engine, } } +void +_gpgme_engine_io_event (EngineObject engine, + GpgmeEventIO type, void *type_data) +{ + if (!engine) + return; + + switch (engine->protocol) + { + case GPGME_PROTOCOL_OpenPGP: + _gpgme_gpg_io_event (engine->engine.gpg, type, type_data); + break; + case GPGME_PROTOCOL_CMS: + _gpgme_gpgsm_io_event (engine->engine.gpgsm, type, type_data); + break; + default: + break; + } +} + void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid) diff --git a/gpgme/engine.h b/gpgme/engine.h index a364031..5f23d2f 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -78,6 +78,8 @@ GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque); void _gpgme_engine_set_io_cbs (EngineObject engine, struct GpgmeIOCbs *io_cbs); +void _gpgme_engine_io_event (EngineObject engine, + GpgmeEventIO type, void *type_data); void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid); void _gpgme_engine_housecleaning (void); diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index ed14996..2caa737 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -507,7 +507,10 @@ gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value) void gpgme_set_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs) { - if (ctx && io_cbs) + if (!ctx) + return; + + if (io_cbs) ctx->io_cbs = *io_cbs; else { @@ -544,9 +547,36 @@ _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data) { GpgmeCtx ctx = data; - if (type == GPGME_EVENT_DONE) - ctx->pending = 0; + switch (type) + { + case GPGME_EVENT_DONE: + ctx->pending = 0; + break; + + case GPGME_EVENT_NEXT_KEY: + _gpgme_op_keylist_event_cb (data, type, type_data); + break; - if (ctx->io_cbs.add && ctx->io_cbs.event) - (*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data); + case GPGME_EVENT_NEXT_TRUSTITEM: + _gpgme_op_trustlist_event_cb (data, type, type_data); + break; + } +} + +void +_gpgme_op_event_cb_user (void *data, GpgmeEventIO type, void *type_data) +{ + GpgmeCtx ctx = data; + + if (type == GPGME_EVENT_DONE) + { + ctx->pending = 0; + if (ctx->io_cbs.event) + (*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, &ctx->error); + } + else + { + if (ctx->io_cbs.event) + (*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data); + } } diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index a4afc92..7f0a9bf 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -339,12 +339,13 @@ char *gpgme_get_op_info (GpgmeCtx ctx, int reserved); typedef void (*GpgmeIOCb) (void *data, int fd); /* The type of a function that can register FNC as the I/O callback - function for the file descriptor FD with direction dir (0: inbound, - 1: outbound). FNC_DATA should be passed as DATA to FNC. The + function for the file descriptor FD with direction dir (0: for writing, + 1: for reading). FNC_DATA should be passed as DATA to FNC. The function should return a TAG suitable for the corresponding - GpgmeRemoveIOCb. */ -typedef void *(*GpgmeRegisterIOCb) (void *data, int fd, int dir, - GpgmeIOCb fnc, void *fnc_data); + GpgmeRemoveIOCb, and an error value. */ +typedef GpgmeError (*GpgmeRegisterIOCb) (void *data, int fd, int dir, + GpgmeIOCb fnc, void *fnc_data, + void **tag); /* The type of a function that can remove a previously registered I/O callback function given TAG as returned by the register @@ -370,13 +371,13 @@ struct GpgmeIOCbs }; /* Set the I/O callback functions in CTX to IO_CBS. */ -void gpgme_set_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs); +void gpgme_set_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs); /* Get the current I/O callback functions. */ -void gpgme_get_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs); +void gpgme_get_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs); /* Cancel a pending operation in CTX. */ -void gpgme_cancel (GpgmeCtx ctx); +void gpgme_cancel (GpgmeCtx ctx); /* Process the pending operation and, if HANG is non-zero, wait for the pending operation to finish. */ diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 5fe3701..baf1efc 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -514,35 +514,45 @@ static void finish_key (GpgmeCtx ctx) { GpgmeKey key = ctx->tmp_key; - struct key_queue_item_s *q, *q2; + + ctx->tmp_key = NULL; if (key) + _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key); +} + + +void +_gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data) +{ + GpgmeCtx ctx = (GpgmeCtx) data; + GpgmeKey key = (GpgmeKey) type_data; + struct key_queue_item_s *q, *q2; + + assert (type == GPGME_EVENT_NEXT_KEY); + + _gpgme_key_cache_add (key); + + q = xtrymalloc (sizeof *q); + if (!q) { - ctx->tmp_key = NULL; - - _gpgme_key_cache_add (key); - - q = xtrymalloc (sizeof *q); - if (!q) - { - gpgme_key_release (key); - ctx->error = mk_error (Out_Of_Core); - return; - } - q->key = key; - q->next = NULL; - /* FIXME: Lock queue. Use a tail pointer? */ - if (!(q2 = ctx->key_queue)) - ctx->key_queue = q; - else - { - for (; q2->next; q2 = q2->next) - ; - q2->next = q; - } - ctx->key_cond = 1; - /* FIXME: Unlock queue. */ + gpgme_key_release (key); + ctx->error = mk_error (Out_Of_Core); + return; } + q->key = key; + q->next = NULL; + /* FIXME: Lock queue. Use a tail pointer? */ + if (!(q2 = ctx->key_queue)) + ctx->key_queue = q; + else + { + for (; q2->next; q2 = q2->next) + ; + q2->next = q; + } + ctx->key_cond = 1; + /* FIXME: Unlock queue. */ } @@ -563,9 +573,7 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only) { GpgmeError err = 0; - /* Keylist operations are always "synchronous" in the sense that we - don't add ourself to the global FD table. */ - err = _gpgme_op_reset (ctx, 1); + err = _gpgme_op_reset (ctx, 2); if (err) goto leave; diff --git a/gpgme/op-support.c b/gpgme/op-support.c index bf61c72..125b723 100644 --- a/gpgme/op-support.c +++ b/gpgme/op-support.c @@ -24,8 +24,12 @@ #include "context.h" #include "ops.h" +/* type is: 0: asynchronous operation (use global or user event loop). + 1: synchronous operation (always use private event loop). + 2: asynchronous private operation (use private or user + event loop). */ GpgmeError -_gpgme_op_reset (GpgmeCtx ctx, int synchronous) +_gpgme_op_reset (GpgmeCtx ctx, int type) { GpgmeError err = 0; struct GpgmeIOCbs io_cbs; @@ -43,8 +47,9 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous) if (err) return err; - if (synchronous) + if (type == 1 || (type == 2 && !ctx->io_cbs.add)) { + /* Use private event loop. */ io_cbs.add = _gpgme_add_io_cb; io_cbs.add_priv = &ctx->fdt; io_cbs.remove = _gpgme_remove_io_cb; @@ -53,6 +58,7 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous) } else if (! ctx->io_cbs.add) { + /* Use global event loop. */ io_cbs.add = _gpgme_add_io_cb; io_cbs.add_priv = NULL; io_cbs.remove = _gpgme_remove_io_cb; @@ -61,8 +67,12 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous) } else { + /* Use user event loop. */ io_cbs = ctx->io_cbs; - io_cbs.event = _gpgme_op_event_cb; + /* We have to make sure that we notice the termination of the + operation ourself, so we stack another event handler on top + of the user-provided one. */ + io_cbs.event = _gpgme_op_event_cb_user; io_cbs.event_priv = ctx; } _gpgme_engine_set_io_cbs (ctx->engine, &io_cbs); diff --git a/gpgme/ops.h b/gpgme/ops.h index 56da5d3..8eebfb5 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -47,6 +47,7 @@ void _gpgme_release_result ( GpgmeCtx c ); void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info); void _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data); +void _gpgme_op_event_cb_user (void *data, GpgmeEventIO type, void *type_data); /*-- wait.c --*/ GpgmeError _gpgme_wait_one (GpgmeCtx ctx); @@ -131,6 +132,10 @@ void _gpgme_release_genkey_result (GenKeyResult res); /*-- keylist.c --*/ void _gpgme_release_keylist_result (KeylistResult res); +void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data); + +/*-- trustlist.c --*/ +void _gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data); /*-- version.c --*/ const char *_gpgme_compare_versions (const char *my_version, diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index dcc96bf..f200d08 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -212,8 +212,8 @@ close_notify_handler (int fd, void *opaque) break; } } - if (!not_done && gpg->io_cbs.event) - (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_DONE, NULL); + if (!not_done) + _gpgme_gpg_io_event (gpg, GPGME_EVENT_DONE, NULL); } const char * @@ -807,12 +807,12 @@ static GpgmeError _gpgme_gpg_add_io_cb (GpgObject gpg, int fd, int dir, GpgmeIOCb handler, void *data, void **tag) { - GpgmeError err = 0; + GpgmeError err; - *tag = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data); - if (!tag) - err = mk_error (General_Error); - if (!err && !dir) + err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag); + if (err) + return err; + if (!dir) /* FIXME Kludge around poll() problem. */ err = _gpgme_io_set_nonblocking (fd); return err; @@ -1749,3 +1749,11 @@ _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs) { gpg->io_cbs = *io_cbs; } + + +void +_gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data) +{ + if (gpg->io_cbs.event) + (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data); +} diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h index a798caf..2c6fcb7 100644 --- a/gpgme/rungpg.h +++ b/gpgme/rungpg.h @@ -162,5 +162,6 @@ GpgmeError _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern); GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text); GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque); void _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs); +void _gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data); #endif /* RUNGPG_H */ diff --git a/gpgme/trustlist.c b/gpgme/trustlist.c index 3d10e51..2fd4b9c 100644 --- a/gpgme/trustlist.c +++ b/gpgme/trustlist.c @@ -87,7 +87,6 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line) char *p, *pend; int field = 0; GpgmeTrustItem item = NULL; - struct trust_queue_item_s *q, *q2; if (ctx->error) return; @@ -104,31 +103,12 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line) switch (field) { case 1: /* level */ - q = xtrymalloc (sizeof *q); - if (!q) - { - ctx->error = mk_error (Out_Of_Core); - return; - } - q->next = NULL; - q->item = item = trust_item_new (); - if (!q->item) + item = trust_item_new (); + if (!item) { - xfree (q); ctx->error = mk_error (Out_Of_Core); return; } - /* fixme: lock queue, keep a tail pointer */ - q2 = ctx->trust_queue; - if (!q2) - ctx->trust_queue = q; - else - { - while (q2->next) - q2 = q2->next; - q2->next = q; - } - /* fixme: unlock queue */ item->level = atoi (p); break; case 2: /* long keyid */ @@ -154,8 +134,41 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line) } } - if (field) - ctx->key_cond = 1; + if (item) + _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item); +} + + +void +_gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data) +{ + GpgmeCtx ctx = (GpgmeCtx) data; + GpgmeTrustItem item = (GpgmeTrustItem) type_data; + struct trust_queue_item_s *q, *q2; + + assert (type == GPGME_EVENT_NEXT_KEY); + + q = xtrymalloc (sizeof *q); + if (!q) + { + gpgme_trust_item_release (item); + ctx->error = mk_error (Out_Of_Core); + return; + } + q->item = item; + q->next = NULL; + /* FIXME: lock queue, keep a tail pointer */ + q2 = ctx->trust_queue; + if (!q2) + ctx->trust_queue = q; + else + { + while (q2->next) + q2 = q2->next; + q2->next = q; + } + /* FIXME: unlock queue */ + ctx->key_cond = 1; } @@ -167,9 +180,7 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level) if (!pattern || !*pattern) return mk_error (Invalid_Value); - /* Trustlist operations are always "synchronous" in the sense that - we don't add ourself to the global FD table. */ - err = _gpgme_op_reset (ctx, 1); + err = _gpgme_op_reset (ctx, 2); if (err) goto leave; diff --git a/gpgme/wait.c b/gpgme/wait.c index 79f3ca7..c73f486 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -332,9 +332,9 @@ struct tag int idx; }; -void * +GpgmeError _gpgme_add_io_cb (void *data, int fd, int dir, - GpgmeIOCb fnc, void *fnc_data) + GpgmeIOCb fnc, void *fnc_data, void **r_tag) { GpgmeError err; fd_table_t fdt = (fd_table_t) (data ? data : &fdt_global); @@ -344,9 +344,10 @@ _gpgme_add_io_cb (void *data, int fd, int dir, assert (fdt); assert (fnc); + *r_tag = NULL; tag = xtrymalloc (sizeof *tag); if (!tag) - return NULL; + return mk_error (Out_Of_Core); tag->fdt = fdt; /* Allocate a structure to hold info about the handler. */ @@ -354,7 +355,7 @@ _gpgme_add_io_cb (void *data, int fd, int dir, if (!item) { xfree (tag); - return NULL; + return mk_error (Out_Of_Core); } item->dir = dir; item->handler = fnc; @@ -365,11 +366,11 @@ _gpgme_add_io_cb (void *data, int fd, int dir, { xfree (tag); xfree (item); - errno = ENOMEM; - return 0; + return mk_error (Out_Of_Core); } - - return tag; + + *r_tag = tag; + return 0; } void diff --git a/gpgme/wait.h b/gpgme/wait.h index b782876..de459cc 100644 --- a/gpgme/wait.h +++ b/gpgme/wait.h @@ -36,8 +36,8 @@ typedef struct fd_table *fd_table_t; void _gpgme_fd_table_init (fd_table_t fdt); void _gpgme_fd_table_deinit (fd_table_t fdt); -void *_gpgme_add_io_cb (void *data, int fd, int dir, - GpgmeIOCb fnc, void *fnc_data); +GpgmeError _gpgme_add_io_cb (void *data, int fd, int dir, + GpgmeIOCb fnc, void *fnc_data, void **r_tag); void _gpgme_remove_io_cb (void *tag); void _gpgme_wait_event_cb (void *data, GpgmeEventIO type, void *type_data); -- 2.26.2