diff options
author | Keith Bostic <keith@wiredtiger.com> | 2014-12-24 11:15:21 -0500 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2014-12-24 11:15:21 -0500 |
commit | baa157b40673c027acf1ddcb99fedb848a660885 (patch) | |
tree | a69a301ed798ffd3bfd7b533cb8a8cfbdfcb2674 /src | |
parent | bc7ed41d8e3d9c268c0d57600a36d32c98bdf8b0 (diff) | |
download | mongo-baa157b40673c027acf1ddcb99fedb848a660885.tar.gz |
Add wiredtiger_strerror_r, a thread-safe version of wiredtiger_strerror,
which allows us to support Windows' errors where we have to allocate a
buffer to get the error string.
Diffstat (limited to 'src')
-rw-r--r-- | src/conn/api_strerror.c | 56 | ||||
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 19 | ||||
-rw-r--r-- | src/os_posix/os_errno.c | 27 | ||||
-rw-r--r-- | src/os_win/os_errno.c | 27 |
5 files changed, 108 insertions, 22 deletions
diff --git a/src/conn/api_strerror.c b/src/conn/api_strerror.c index caf536b24f7..5cabe55d3f6 100644 --- a/src/conn/api_strerror.c +++ b/src/conn/api_strerror.c @@ -4,40 +4,60 @@ /* * wiredtiger_strerror -- - * Return a string for any error value. + * Return a string for any error value in a static buffer. */ const char * wiredtiger_strerror(int error) { - static char errbuf[64]; - char *p; + static char buf[128]; - if (error == 0) - return ("Successful return: 0"); + if (wiredtiger_strerror_r(error, buf, sizeof(buf)) != 0) + (void)snprintf(buf, sizeof(buf), "error return: %d", error); + return (buf); +} + +/* + * wiredtiger_strerror_r -- + * Return a string for any error value, thread-safe version. + */ +int +wiredtiger_strerror_r(int error, char *buf, size_t buflen) +{ + const char *p; + + /* Require at least 2 bytes, printable character and trailing nul. */ + if (buflen < 2) + return (ENOMEM); switch (error) { + case 0: + p = "Successful return: 0"; + break; case WT_ROLLBACK: - return ("WT_ROLLBACK: conflict between concurrent operations"); + p = "WT_ROLLBACK: conflict between concurrent operations"; + break; case WT_DUPLICATE_KEY: - return ("WT_DUPLICATE_KEY: attempt to insert an existing key"); + p = "WT_DUPLICATE_KEY: attempt to insert an existing key"; + break; case WT_ERROR: - return ("WT_ERROR: non-specific WiredTiger error"); + p = "WT_ERROR: non-specific WiredTiger error"; + break; case WT_NOTFOUND: - return ("WT_NOTFOUND: item not found"); + p = "WT_NOTFOUND: item not found"; + break; case WT_PANIC: - return ("WT_PANIC: WiredTiger library panic"); + p = "WT_PANIC: WiredTiger library panic"; + break; case WT_RESTART: - return ("WT_RESTART: restart the operation (internal)"); - default: - if (error > 0 && (p = strerror(error)) != NULL) - return (p); + p = "WT_RESTART: restart the operation (internal)"; break; + default: + return (__wt_strerror_r(error, buf, buflen)); } /* - * !!! - * Not thread-safe, but this is never supposed to happen. + * Return success if anything printed (we checked if the buffer had + * space for at least one character). */ - (void)snprintf(errbuf, sizeof(errbuf), "Unknown error: %d", error); - return (errbuf); + return (snprintf(buf, buflen, "%s", p) > 0 ? 0 : ENOMEM); } diff --git a/src/include/extern.h b/src/include/extern.h index 056058f3828..b5c71aa7c15 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -431,6 +431,7 @@ extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, int fail, void *sym_ret); extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh); extern int __wt_errno(void); +extern int __wt_strerror_r(int error, char *buf, size_t buflen); extern int __wt_exist(WT_SESSION_IMPL *session, const char *filename, int *existp); extern void __wt_fallocate_config(WT_SESSION_IMPL *session, WT_FH *fh); extern int __wt_fallocate( WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len); diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in index 075514e02b4..20991278440 100644 --- a/src/include/wiredtiger.in +++ b/src/include/wiredtiger.in @@ -2019,15 +2019,26 @@ int wiredtiger_open(const char *home, WT_CONNECTION **connectionp); /*! - * Return information about an error as a string; wiredtiger_strerror is a - * superset of the ISO C99/POSIX 1003.1-2001 function strerror. + * Return information about a WiredTiger error as a string, not thread-safe. * * @snippet ex_all.c Display an error * - * @param err a return value from a WiredTiger, C library or POSIX function + * @param error a return value from a WiredTiger call * @returns a string representation of the error */ -const char *wiredtiger_strerror(int err); +const char *wiredtiger_strerror(int error); + +/*! + * Return information about a WiredTiger error as a string, thread-safe version. + * + * @snippet ex_all.c Display an error thread safe + * + * @param error a return value from a WiredTiger call + * @param buf a buffer of at least \c buflen bytes + * @param buflen the length of the buffer + * @returns zero for success, non-zero to indicate an error. + */ +int wiredtiger_strerror_r(int error, char *buf, size_t buflen); #if !defined(SWIG) /*! diff --git a/src/os_posix/os_errno.c b/src/os_posix/os_errno.c index 9290f7d651f..b0cb288ea74 100644 --- a/src/os_posix/os_errno.c +++ b/src/os_posix/os_errno.c @@ -20,3 +20,30 @@ __wt_errno(void) */ return (errno == 0 ? WT_ERROR : errno); } + +/* + * __wt_strerror_r -- + * POSIX implementation of strerror_r. + */ +int +__wt_strerror_r(int error, char *buf, size_t buflen) +{ + char *p; + + /* Require at least 2 bytes, printable character and trailing nul. */ + if (buflen < 2) + return (ENOMEM); + + /* + * POSIX errors are non-negative integers, copy the string into the + * user's buffer. Return success if anything printed (we checked if + * the buffer had space for at least one character). + */ + if (error > 0 && + (p = strerror(error)) != NULL && snprintf(buf, buflen, "%s", p) > 0) + return (0); + + /* Fallback to a generic message, then guess it's a memory problem. */ + return ( + snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM); +} diff --git a/src/os_win/os_errno.c b/src/os_win/os_errno.c index ce50106b0cc..856db1ae96d 100644 --- a/src/os_win/os_errno.c +++ b/src/os_win/os_errno.c @@ -25,3 +25,30 @@ __wt_errno(void) return (err == ERROR_SUCCESS ? WT_ERROR : err); } + +/* + * __wt_strerror_r -- + * Windows implementation of strerror_r. + */ +int +__wt_strerror_r(int error, char *buf, size_t buflen) +{ + char *p; + + /* Require at least 2 bytes, printable character and trailing nul. */ + if (buflen < 2) + return (ENOMEM); + + /* + * POSIX errors are non-negative integers, copy the string into the + * user's buffer. Return success if anything printed (we checked if + * the buffer had space for at least one character). + */ + if (error > 0 && + (p = strerror(error)) != NULL && snprintf(buf, buflen, "%s", p) > 0) + return (0); + + /* Fallback to a generic message, then guess it's a memory problem. */ + return ( + snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM); +} |