diff options
author | Marcus Brinkmann <[email protected]> | 2003-09-30 19:27:21 +0000 |
---|---|---|
committer | Marcus Brinkmann <[email protected]> | 2003-09-30 19:27:21 +0000 |
commit | 3946df08f9f77a441eff9f1a5c67a18d08563237 (patch) | |
tree | 5432214339a655aaac6b8fc1b1c4f832e55d3299 | |
parent | Add item about error code. (diff) | |
download | libgpg-error-3946df08f9f77a441eff9f1a5c67a18d08563237.tar.gz libgpg-error-3946df08f9f77a441eff9f1a5c67a18d08563237.zip |
2003-09-30 Marcus Brinkmann <[email protected]>
* src/gpg-error.h: Include <stddef.h>.
(gpg_strerror_r): Change prototype to match POSIX. Rewritten for
that prototype.
* src/strerror.c: Include <errno.h>.
(gpg_strerror_r, system_strerror_r): Change prototype to match
POSIX. Rewritten for that prototype. Rewritten for that
prototype.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/gpg-error.h | 15 | ||||
-rw-r--r-- | src/strerror.c | 204 |
3 files changed, 79 insertions, 150 deletions
@@ -1,3 +1,13 @@ +2003-09-30 Marcus Brinkmann <[email protected]> + + * src/gpg-error.h: Include <stddef.h>. + (gpg_strerror_r): Change prototype to match POSIX. Rewritten for + that prototype. + * src/strerror.c: Include <errno.h>. + (gpg_strerror_r, system_strerror_r): Change prototype to match + POSIX. Rewritten for that prototype. Rewritten for that + prototype. + 2003-09-30 Werner Koch <[email protected]> * src/gpg-error.h: Add PIN_NOT_SYNCED. diff --git a/src/gpg-error.h b/src/gpg-error.h index cf6d2f5..5f92564 100644 --- a/src/gpg-error.h +++ b/src/gpg-error.h @@ -21,6 +21,8 @@ #ifndef GPG_ERROR_H #define GPG_ERROR_H 1 +#include <stddef.h> + #ifdef __GNUC__ #define GPG_ERR_INLINE __inline__ #elif __STDC_VERSION__ >= 199901L @@ -496,11 +498,14 @@ gpg_err_source (gpg_error_t err) code in the error value ERR. This function is not thread-safe. */ const char *gpg_strerror (gpg_error_t err); -/* Return a pointer to a string containing a description of the error - code in the error value ERR. The buffer for the string is - allocated with malloc(), and has to be released by the user. On - error, NULL is returned. */ -char *gpg_strerror_r (gpg_error_t err); +/* Return the error string for ERR in the user-supplied buffer BUF of + size BUFLEN. This function is, in contrast to gpg_strerror, + thread-safe if a thread-safe strerror_r() function is provided by + the system. If the function succeeds, 0 is returned and BUF + contains the string describing the error. If the buffer was not + large enough, ERANGE is returned and BUF contains as much of the + beginning of the error string as fits into the buffer. */ +int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen); /* Return a pointer to a string containing a description of the error source in the error value ERR. */ diff --git a/src/strerror.c b/src/strerror.c index a8a5a63..dd6a6b3 100644 --- a/src/strerror.c +++ b/src/strerror.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> +#include <errno.h> #include <gpg-error.h> @@ -60,139 +61,39 @@ gpg_strerror (gpg_error_t err) call fails because the error number is not valid, don't set *STR and return 0. */ int -system_strerror_r (int no, char **str) +system_strerror_r (int no, char *buf, size_t buflen) { - int err; - char *buffer; - size_t buffer_len = 128; + char *errstr; - buffer = malloc (buffer_len); - if (!buffer) + errstr = strerror_r (no, buf, buflen); + if (errstr != buf) { - *str = NULL; - return 1; - } + size_t errstr_len = strlen (errstr) + 1; + size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); - do + return cpy_len == errstr_len ? 0 : ERANGE; + } + else { - char *msg = strerror_r (no, buffer, buffer_len); - - if (!msg) - { - /* Possibly this means that the error code is unknown. */ - free (buffer); - return 0; - } - else if (msg != buffer) - { - free (buffer); - *str = strdup (msg); - return 1; - } + /* We can not tell if the buffer was large enough, but we can + try to make a guess. */ + if (strlen (buf) + 1 >= buflen) + return ERANGE; - buffer[buffer_len - 1] = '\0'; - if (strlen (buffer) == buffer_len - 1) - { - /* We might need more space. */ - size_t new_buffer_len = buffer_len * 2; - char *new_buffer; - - if (new_buffer_len < buffer_len) - { - /* Overflow. Now, this is serious. */ - free (buffer); - *str = NULL; - return 1; - } - - new_buffer = realloc (buffer, 2 * buffer_len); - if (!new_buffer) - { - free (buffer); - *str = NULL; - return 1; - } - buffer = new_buffer; - buffer_len = new_buffer_len; - } - else - { - *str = buffer; - return 1; - } + return 0; } - while (1); } #else /* STRERROR_R_CHAR_P */ /* Now the POSIX version. */ -/* Return a dynamically allocated string in *STR describing the system - error NO. If this call succeeds, return 1. If this call fails due - to a resource shortage, set *STR to NULL and return 1. If this - call fails because the error number is not valid, don't set *STR - and return 0. */ int -system_strerror_r (int no, char **str) +system_strerror_r (int no, char *buf, size_t buflen) { - int err; - char *buffer; - size_t buffer_len = 128; - - buffer = malloc (buffer_len); - if (!buffer) - { - *str = NULL; - return 1; - } - - do - { - err = strerror_r (no, buffer, buffer_len); - - if (err == ERANGE) - { - size_t new_buffer_len = buffer_len * 2; - char *new_buffer; - - if (new_buffer_len < buffer_len) - { - /* Overflow. Now, this is serious. */ - free (buffer); - *str = NULL; - return 1; - } - - new_buffer = realloc (buffer, 2 * buffer_len); - if (!new_buffer) - { - free (buffer); - *str = NULL; - return 1; - } - buffer = new_buffer; - buffer_len = new_buffer_len; - } - } - while (err == ERANGE); - - if (err == EINVAL) - { - /* This system error is not known. */ - free (buffer); - return 0; - } - else if (err) - { - /* strerror_r() failed, but we don't know why. */ - free (buffer); - *str = NULL; - return 1; - } - - *str = buffer; - return 1; + return strerror_r (no, buf, buflen); } + #endif /* STRERROR_R_CHAR_P */ #else /* HAVE_STRERROR_H */ @@ -200,55 +101,68 @@ system_strerror_r (int no, char **str) version. Maybe we are even lucky and the system's strerror() is already thread-safe. */ -/* Return a dynamically allocated string in *STR describing the system - error NO. If this call succeeds, return 1. If this call fails due - to a resource shortage, set *STR to NULL and return 1. If this - call fails because the error number is not valid, don't set *STR - and return 0. */ int -system_strerror_r (int no, char **str) +system_strerror_r (int no, char *buf, size_t buflen) { - char *msg = strerror (no); + char *errstr = strerror (no); - if (!msg) + if (!errstr) { - if (errno == EINVAL) - return 0; - else - { - *str = NULL; - return 1; - } + int saved_errno = errno; + + if (saved_errno != EINVAL) + snprintf (buf, buflen, "strerror failed: %i\n", errno); + return saved_errno; } else { - *str = strdup (msg); - return 1; + size_t errstr_len = strlen (errstr) + 1; + size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); + return cpy_len == errstr_len ? 0 : ERANGE; } } #endif -/* Return a pointer to a string containing a description of the error - code in the error value ERR. The buffer for the string is - allocated with malloc(), and has to be released by the user. On - error, NULL is returned. */ -char * -gpg_strerror_r (gpg_error_t err) +/* Return the error string for ERR in the user-supplied buffer BUF of + size BUFLEN. This function is, in contrast to gpg_strerror, + thread-safe if a thread-safe strerror_r() function is provided by + the system. If the function succeeds, 0 is returned and BUF + contains the string describing the error. If the buffer was not + large enough, ERANGE is returned and BUF contains as much of the + beginning of the error string as fits into the buffer. */ +int +gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen) { gpg_err_code_t code = gpg_err_code (err); + const char *errstr; + size_t errstr_len; + size_t cpy_len; if (code & GPG_ERR_SYSTEM_ERROR) { int no = gpg_err_code_to_errno (code); if (no) { - char *str; + int system_err = system_strerror_r (no, buf, buflen); - if (system_strerror_r (no, &str)) - return str; + if (system_err != EINVAL) + { + if (buflen) + buf[buflen - 1] = '\0'; + return system_err; + } } code = GPG_ERR_UNKNOWN_ERRNO; } - return strdup (dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)])); + + errstr = dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]); + errstr_len = strlen (errstr) + 1; + cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); + if (buflen) + buf[buflen - 1] = '\0'; + + return cpy_len == errstr_len ? 0 : ERANGE; } |