Make gpgme_new return a proper error if no engines are installed.

* src/engine.c (gpgme_get_engine_info): Improve error handling.
(_gpgme_engine_info_copy): Ditto.
* src/gpgme.c (gpgme_new): Return error GPG_ERR_NO_ENGINE.
This commit is contained in:
Werner Koch 2014-01-07 13:32:08 +01:00
parent d63058b852
commit 121efcc561
2 changed files with 34 additions and 15 deletions

View File

@ -182,6 +182,8 @@ _gpgme_engine_info_release (gpgme_engine_info_t info)
gpgme_error_t gpgme_error_t
gpgme_get_engine_info (gpgme_engine_info_t *info) gpgme_get_engine_info (gpgme_engine_info_t *info)
{ {
gpgme_error_t err;
LOCK (engine_info_lock); LOCK (engine_info_lock);
if (!engine_info) if (!engine_info)
{ {
@ -194,6 +196,7 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
GPGME_PROTOCOL_UISERVER }; GPGME_PROTOCOL_UISERVER };
unsigned int proto; unsigned int proto;
err = 0;
for (proto = 0; proto < DIM (proto_list); proto++) for (proto = 0; proto < DIM (proto_list); proto++)
{ {
const char *ofile_name = engine_get_file_name (proto_list[proto]); const char *ofile_name = engine_get_file_name (proto_list[proto]);
@ -205,13 +208,24 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
continue; continue;
file_name = strdup (ofile_name); file_name = strdup (ofile_name);
home_dir = ohome_dir? strdup (ohome_dir): NULL; if (!file_name)
err = gpg_error_from_syserror ();
if (ohome_dir)
{
home_dir = strdup (ohome_dir);
if (!home_dir && !err)
err = gpg_error_from_syserror ();
}
else
home_dir = NULL;
*lastp = malloc (sizeof (*engine_info)); *lastp = malloc (sizeof (*engine_info));
if (!*lastp || !file_name) if (!*lastp && !err)
{ err = gpg_error_from_syserror ();
int saved_err = gpg_error_from_syserror ();
if (err)
{
_gpgme_engine_info_release (engine_info); _gpgme_engine_info_release (engine_info);
engine_info = NULL; engine_info = NULL;
@ -221,7 +235,7 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
free (home_dir); free (home_dir);
UNLOCK (engine_info_lock); UNLOCK (engine_info_lock);
return saved_err; return err;
} }
(*lastp)->protocol = proto_list[proto]; (*lastp)->protocol = proto_list[proto];
@ -273,11 +287,13 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
assert (info->file_name); assert (info->file_name);
file_name = strdup (info->file_name); file_name = strdup (info->file_name);
if (!file_name)
err = gpg_error_from_syserror ();
if (info->home_dir) if (info->home_dir)
{ {
home_dir = strdup (info->home_dir); home_dir = strdup (info->home_dir);
if (!home_dir) if (!home_dir && !err)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
} }
else else
@ -286,19 +302,19 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
if (info->version) if (info->version)
{ {
version = strdup (info->version); version = strdup (info->version);
if (!version) if (!version && !err)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
} }
else else
version = NULL; version = NULL;
*lastp = malloc (sizeof (*engine_info)); *lastp = malloc (sizeof (*engine_info));
if (!*lastp || !file_name || err) if (!*lastp && !err)
err = gpg_error_from_syserror ();
if (err)
{ {
int saved_err = gpg_error_from_syserror ();
_gpgme_engine_info_release (new_info); _gpgme_engine_info_release (new_info);
if (file_name) if (file_name)
free (file_name); free (file_name);
if (home_dir) if (home_dir)
@ -307,7 +323,7 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
free (version); free (version);
UNLOCK (engine_info_lock); UNLOCK (engine_info_lock);
return saved_err; return err;
} }
(*lastp)->protocol = info->protocol; (*lastp)->protocol = info->protocol;

View File

@ -86,6 +86,7 @@ gpgme_set_global_flag (const char *name, const char *value)
gpgme_error_t gpgme_error_t
gpgme_new (gpgme_ctx_t *r_ctx) gpgme_new (gpgme_ctx_t *r_ctx)
{ {
gpgme_error_t err;
gpgme_ctx_t ctx; gpgme_ctx_t ctx;
TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx); TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
@ -101,11 +102,13 @@ gpgme_new (gpgme_ctx_t *r_ctx)
INIT_LOCK (ctx->lock); INIT_LOCK (ctx->lock);
_gpgme_engine_info_copy (&ctx->engine_info); err = _gpgme_engine_info_copy (&ctx->engine_info);
if (!ctx->engine_info) if (!err && !ctx->engine_info)
err = gpg_error (GPG_ERR_NO_ENGINE);
if (err)
{ {
free (ctx); free (ctx);
return TRACE_ERR (gpg_error_from_syserror ()); return TRACE_ERR (err);
} }
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL; ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;