From: Nick Alcock Date: Wed, 19 Nov 2025 13:58:14 +0000 (+0000) Subject: libctf: API review: report error code in ctf_errwarning_next stream X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff15b4c4ef19d090ffe07c55ba3a905b8b11a02f;p=thirdparty%2Fbinutils-gdb.git libctf: API review: report error code in ctf_errwarning_next stream The ctf_err_warn internal function that pushes new errors onto the ctf_errwarning_next stream takes a ctf_error_t as well as an error string. It doesn't put this onto the error it saves, but only debugging-printf()s it. This means that it throws away the error code and relies on the textual error redundantly transmitting the same information, which is quite undesirable, particularly if the caller wants to take note of the errors programmatically. So store each error code with the corresponding error string, and report it via the error pointer argument that ctf_errwarning_next is already being provided (and which has never been initialized unless ctf_errwarning_next itself encountered an error and returned NULL, so this isn't even an API break). --- diff --git a/libctf/ctf-api.c b/libctf/ctf-api.c index 2c3afd04feb..8c89836f99b 100644 --- a/libctf/ctf-api.c +++ b/libctf/ctf-api.c @@ -213,6 +213,7 @@ ctf_err_warn (ctf_dict_t *fp, int is_warning, ctf_error_t err, return; cew->cew_is_warning = is_warning; + cew->cew_err = (err != 0 || !fp) ? err : ctf_errno (fp); va_start (alist, format); if (vasprintf (&cew->cew_text, format, alist) < 0) { @@ -277,19 +278,25 @@ ctf_err_copy (ctf_dict_t *dest, ctf_dict_t *src) /* Error-warning reporting: an 'iterator' that returns errors and warnings from the error/warning list, in order of emission. Errors and warnings are popped - after return: the caller must free the returned error-text pointer. + after return: the caller must free the returned error-text pointer. The + optional errp argument is overwritten with the associated error code, if + non-NULL: it is also used to report errors with this function itself. An fp of NULL returns CTF-open-time errors from the open_errors variable above. The treatment of errors from this function itself is somewhat unusual: it will often be called on an error path, so we don't want to overwrite the - ctf_errno unless we have no choice. So, like ctf_bufopen et al, this - function takes an errp pointer where errors are reported. The pointer is - optional: if not set, errors are reported via the fp (if non-NULL). Calls - with neither fp nor errp set are mildly problematic because there is no clear - way to report end-of-iteration: you just have to assume that a NULL return - means the end, and not an iterator error. */ + ctf_errno unless we have no choice. So the errp argument is preferentially + used to store errors, if it is provided. The pointer is optional: if not + set, errors are reported via the fp (if non-NULL). Calls with neither fp nor + errp set are mildly problematic because there is no clear way to report + end-of-iteration: you just have to assume that a NULL return means the end, + and not an iterator error. + + ERRP is also used to report the error code associated with a reported + error; error returns from this function always return NULL and set ERRP; + non-error returns never return NULL. */ char * ctf_errwarning_next (ctf_dict_t *fp, ctf_next_t **it, int *is_warning, @@ -344,6 +351,8 @@ ctf_errwarning_next (ctf_dict_t *fp, ctf_next_t **it, int *is_warning, if (is_warning) *is_warning = cew->cew_is_warning; + if (errp) + *errp = cew->cew_err; ret = cew->cew_text; ctf_list_delete (errlist, cew); free (cew); diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 731f991b844..cdb558fe455 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -204,6 +204,7 @@ typedef struct ctf_err_warning { ctf_list_t cew_list; /* List forward/back pointers. */ int cew_is_warning; /* 1 if warning, 0 if error. */ + int cew_err; /* Error code (if any). */ char *cew_text; /* Error/warning text. */ } ctf_err_warning_t;