From 61cc5004fb8e14464ae0afcffc6e2ee852b45a41 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 28 Jul 2017 15:17:22 -0400 Subject: [PATCH 2/4] kludge poptBadOption() to return value on exec alias failure Patch by Panu Matilainen for popt <= 1.16 which kludges poptBadOption() to return something semi-meaningful on exec alias fail: - poptBadOption() is totally unaware of exec alias failures, and will return either the first argument or last option, giving wonderfully misleading error messages (#697435, #710267). - Remember execvp() first argument on failure and return that from poptBadOption() if present to give the user a reasonable clue what exactly went wrong. This patch was proposed to upstream: http://rpm5.org/community/popt-devel/0264.html --- popt.c | 19 +++++++++++++++---- poptint.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/popt.c b/popt.c index a1c38a5..1a53f40 100644 --- a/popt.c +++ b/popt.c @@ -192,6 +192,7 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv, con->flags = flags; con->execs = NULL; con->numExecs = 0; + con->execFail = NULL; con->finalArgvAlloced = argc * 2; con->finalArgv = calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) ); con->execAbsolute = 1; @@ -236,6 +237,7 @@ void poptResetContext(poptContext con) con->nextLeftover = 0; con->restLeftover = 0; con->doExec = NULL; + con->execFail = _free(con->execFail); if (con->finalArgv != NULL) for (i = 0; i < con->finalArgvCount; i++) { @@ -564,6 +566,7 @@ if (_popt_debug) /*@-nullstate@*/ rc = execvp(argv[0], (char *const *)argv); /*@=nullstate@*/ + con->execFail = xstrdup(argv[0]); exit: if (argv) { @@ -1697,11 +1700,19 @@ int poptAddItem(poptContext con, poptItem newItem, int flags) const char * poptBadOption(poptContext con, unsigned int flags) { struct optionStackEntry * os = NULL; + const char *badOpt = NULL; + + if (con != NULL) { + /* Stupid hack to return something semi-meaningful from exec failure */ + if (con->execFail) { + badOpt = con->execFail; + } else { + os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; + badOpt = os->argv[os->next - 1]; + } + } - if (con != NULL) - os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; - - return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL); + return badOpt; } const char * poptStrerror(const int error) diff --git a/poptint.h b/poptint.h index 80cbaca..0fcb26e 100644 --- a/poptint.h +++ b/poptint.h @@ -132,6 +132,7 @@ struct poptContext_s { /*@owned@*/ /*@null@*/ poptItem execs; int numExecs; + char * execFail; /*@only@*/ /*@null@*/ poptArgv finalArgv; int finalArgvCount; -- 2.13.3