summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-02-18 13:48:58 +1100
committerMichael Cahill <michael.cahill@mongodb.com>2015-02-18 13:48:58 +1100
commit84c66e709b9ff0d4f993fc231c507034e6e9220a (patch)
tree2a3294f17619b098efebde251933742c87f8e146 /src
parent6ad817ec5df8131a642bf79c3bb79a6bc6d0aa8a (diff)
parentd5131a90497c19f13d01384cb050a339ab1753c7 (diff)
downloadmongo-84c66e709b9ff0d4f993fc231c507034e6e9220a.tar.gz
Merge pull request #1629 from wiredtiger/session-strerror
WT_SESSION.strerror
Diffstat (limited to 'src')
-rw-r--r--src/config/config_def.c4
-rw-r--r--src/conn/api_strerror.c39
-rw-r--r--src/conn/conn_api.c2
-rw-r--r--src/include/config.h17
-rw-r--r--src/include/extern.h4
-rw-r--r--src/include/session.h2
-rw-r--r--src/include/wiredtiger.in23
-rw-r--r--src/include/wiredtiger_ext.h11
-rw-r--r--src/os_posix/os_errno.c30
-rw-r--r--src/os_win/os_errno.c30
-rw-r--r--src/session/session_api.c25
-rw-r--r--src/support/err.c14
12 files changed, 110 insertions, 91 deletions
diff --git a/src/config/config_def.c b/src/config/config_def.c
index b04cd823055..43d87c518e4 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -668,6 +668,10 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"force=0",
confchk_session_salvage
},
+ { "session.strerror",
+ "",
+ NULL
+ },
{ "session.truncate",
"",
NULL
diff --git a/src/conn/api_strerror.c b/src/conn/api_strerror.c
index 4b2f6f12f7c..f08d70969dd 100644
--- a/src/conn/api_strerror.c
+++ b/src/conn/api_strerror.c
@@ -5,7 +5,7 @@
/*
* Historically, there was only the wiredtiger_strerror call because the POSIX
* port didn't need anything more complex; Windows requires memory allocation
- * of error strings, so we added the wiredtiger_strerror_r call. Because we
+ * of error strings, so we added the WT_SESSION.strerror method. Because we
* want wiredtiger_strerror to continue to be as thread-safe as possible, errors
* are split into three categories: WiredTiger constant strings, system constant
* strings and Everything Else, and we check constant strings before Everything
@@ -16,8 +16,8 @@
* __wiredtiger_error --
* Return a constant string for the WiredTiger errors.
*/
-static const char *
-__wiredtiger_error(int error)
+const char *
+__wt_wiredtiger_error(int error)
{
switch (error) {
case WT_ROLLBACK:
@@ -49,34 +49,15 @@ wiredtiger_strerror(int error)
const char *p;
/* Check for a constant string. */
- if ((p = __wiredtiger_error(error)) != NULL ||
- (p = __wt_strerror(error)) != NULL)
+ if ((p = __wt_wiredtiger_error(error)) != NULL)
+ return (p);
+ if ((p = __wt_strerror(error)) != NULL)
return (p);
/* Else, fill in the non-thread-safe static buffer. */
- 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);
-
- /* Check for a constant string. */
- if ((p = __wiredtiger_error(error)) != NULL ||
- (p = __wt_strerror(error)) != NULL)
- return (snprintf(buf, buflen, "%s", p) > 0 ? 0 : ENOMEM);
+ if (snprintf(buf, sizeof(buf), "error return: %d", error) > 0)
+ return (buf);
- return (__wt_strerror_r(error, buf, buflen));
+ /* OK, we're done. */
+ return ("Unable to return error string");
}
diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c
index 5be55a77f24..0562f9cfc34 100644
--- a/src/conn/conn_api.c
+++ b/src/conn/conn_api.c
@@ -117,7 +117,7 @@ __conn_get_extension_api(WT_CONNECTION *wt_conn)
conn->extension_api.conn = wt_conn;
conn->extension_api.err_printf = __wt_ext_err_printf;
conn->extension_api.msg_printf = __wt_ext_msg_printf;
- conn->extension_api.strerror = wiredtiger_strerror;
+ conn->extension_api.strerror = __wt_ext_strerror;
conn->extension_api.scr_alloc = __wt_ext_scr_alloc;
conn->extension_api.scr_free = __wt_ext_scr_free;
conn->extension_api.collator_config = ext_collator_config;
diff --git a/src/include/config.h b/src/include/config.h
index 65757c2ef6d..046f515188c 100644
--- a/src/include/config.h
+++ b/src/include/config.h
@@ -73,14 +73,15 @@ struct __wt_config_parser_impl {
#define WT_CONFIG_ENTRY_session_rename 24
#define WT_CONFIG_ENTRY_session_rollback_transaction 25
#define WT_CONFIG_ENTRY_session_salvage 26
-#define WT_CONFIG_ENTRY_session_truncate 27
-#define WT_CONFIG_ENTRY_session_upgrade 28
-#define WT_CONFIG_ENTRY_session_verify 29
-#define WT_CONFIG_ENTRY_table_meta 30
-#define WT_CONFIG_ENTRY_wiredtiger_open 31
-#define WT_CONFIG_ENTRY_wiredtiger_open_all 32
-#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 33
-#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 34
+#define WT_CONFIG_ENTRY_session_strerror 27
+#define WT_CONFIG_ENTRY_session_truncate 28
+#define WT_CONFIG_ENTRY_session_upgrade 29
+#define WT_CONFIG_ENTRY_session_verify 30
+#define WT_CONFIG_ENTRY_table_meta 31
+#define WT_CONFIG_ENTRY_wiredtiger_open 32
+#define WT_CONFIG_ENTRY_wiredtiger_open_all 33
+#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 34
+#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 35
/*
* configuration section: END
* DO NOT EDIT: automatically built by dist/flags.py.
diff --git a/src/include/extern.h b/src/include/extern.h
index 40493b4aab4..3b08d79e842 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -198,6 +198,7 @@ extern void __wt_conn_config_discard(WT_SESSION_IMPL *session);
extern int __wt_ext_config_parser_open(WT_EXTENSION_API *wt_ext, WT_SESSION *wt_session, const char *config, size_t len, WT_CONFIG_PARSER **config_parserp);
extern int __wt_ext_config_get(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_CONFIG_ARG *cfg_arg, const char *key, WT_CONFIG_ITEM *cval);
extern int __wt_config_upgrade(WT_SESSION_IMPL *session, WT_ITEM *buf);
+extern const char *__wt_wiredtiger_error(int error);
extern int __wt_collator_config(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM *cname, WT_CONFIG_ITEM *metadata, WT_COLLATOR **collatorp, int *ownp);
extern int __wt_conn_remove_collator(WT_SESSION_IMPL *session);
extern int __wt_conn_remove_compressor(WT_SESSION_IMPL *session);
@@ -438,7 +439,7 @@ extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, i
extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh);
extern int __wt_errno(void);
extern const char *__wt_strerror(int error);
-extern int __wt_strerror_r(int error, char *buf, size_t buflen);
+extern const char *__wt_session_strerror(WT_SESSION_IMPL *session, int error);
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);
@@ -574,6 +575,7 @@ extern void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUN
extern int __wt_ext_err_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4)));
extern int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3)));
extern int __wt_ext_msg_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4)));
+extern const char *__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error);
extern int __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v);
extern void __wt_assert(WT_SESSION_IMPL *session, int error, const char *file_name, int line_number, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 5, 6)));
extern int __wt_panic(WT_SESSION_IMPL *session);
diff --git a/src/include/session.h b/src/include/session.h
index 909f1daf5a4..36df35a104e 100644
--- a/src/include/session.h
+++ b/src/include/session.h
@@ -111,6 +111,8 @@ struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) __wt_session_impl {
} *scratch_track;
#endif
+ WT_ITEM err; /* Error buffer */
+
WT_TXN_ISOLATION isolation;
WT_TXN txn; /* Transaction state */
u_int ncursors; /* Count of active file cursors. */
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index 772295f7104..d0d0f9eec77 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -835,6 +835,17 @@ struct __wt_session {
int __F(reconfigure)(WT_SESSION *session, const char *config);
/*!
+ * Return information about an error as a string.
+ *
+ * @snippet ex_all.c Display an error thread safe
+ *
+ * @param session the session handle
+ * @param error a return value from a WiredTiger function
+ * @returns a string representation of the error
+ */
+ const char *__F(strerror)(WT_SESSION *session, int error);
+
+ /*!
* @name Cursor handles
* @{
*/
@@ -2092,18 +2103,6 @@ int wiredtiger_open(const char *home,
*/
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)
/*!
* The interface implemented by applications to accept notifications
diff --git a/src/include/wiredtiger_ext.h b/src/include/wiredtiger_ext.h
index ee27b32ddf7..28fd8e18329 100644
--- a/src/include/wiredtiger_ext.h
+++ b/src/include/wiredtiger_ext.h
@@ -118,16 +118,17 @@ struct __wt_extension_api {
WT_EXTENSION_API *, WT_SESSION *session, const char *fmt, ...);
/*!
- * Return information about an error as a string; the strerror method
- * is a superset of the ISO C99/POSIX 1003.1-2001 function strerror.
+ * Return information about an error as a string.
*
* @snippet ex_data_source.c WT_EXTENSION_API strerror
*
- * @param err a return value from a WiredTiger, C library or POSIX
- * function
+ * @param wt_api the extension handle
+ * @param session the session handle (or NULL if none available)
+ * @param error a return value from a WiredTiger function
* @returns a string representation of the error
*/
- const char *(*strerror)(int err);
+ const char *(*strerror)(
+ WT_EXTENSION_API *, WT_SESSION *session, int error);
/*!
* Allocate short-term use scratch memory.
diff --git a/src/os_posix/os_errno.c b/src/os_posix/os_errno.c
index a58f13583ce..c022cfda6bc 100644
--- a/src/os_posix/os_errno.c
+++ b/src/os_posix/os_errno.c
@@ -43,27 +43,23 @@ __wt_strerror(int error)
}
/*
- * __wt_strerror_r --
- * POSIX implementation of wiredtiger_strerror_r.
+ * __wt_session_strerror --
+ * POSIX implementation of WT_SESSION.strerror.
*/
-int
-__wt_strerror_r(int error, char *buf, size_t buflen)
+const char *
+__wt_session_strerror(WT_SESSION_IMPL *session, int error)
{
const char *p;
- /* Require at least 2 bytes, printable character and trailing nul. */
- if (buflen < 2)
- return (ENOMEM);
+ /* Check for POSIX errors. */
+ if ((p = __wt_strerror(error)) != NULL)
+ return (p);
- /*
- * Check for POSIX errors then fallback to something generic. Copy the
- * string into the user's buffer, return success if anything printed.
- */
- p = __wt_strerror(error);
- if (p != NULL && snprintf(buf, buflen, "%s", p) > 0)
- return (0);
+ /* Fallback to a generic message. */
+ if (__wt_buf_fmt(
+ session, &session->err, "error return: %d", error) == 0)
+ return (session->err.data);
- /* Fallback to a generic message, then guess it's a memory problem. */
- return (
- snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM);
+ /* Defeated. */
+ return ("Unable to return error string");
}
diff --git a/src/os_win/os_errno.c b/src/os_win/os_errno.c
index 00ee638fbe3..c81432299a3 100644
--- a/src/os_win/os_errno.c
+++ b/src/os_win/os_errno.c
@@ -77,27 +77,23 @@ __wt_strerror(int error)
}
/*
- * __wt_strerror_r --
- * Windows implementation of wiredtiger_strerror_r.
+ * __wt_session_strerror --
+ * Windows implementation of WT_SESSION.strerror.
*/
-int
-__wt_strerror_r(int error, char *buf, size_t buflen)
+const char *
+__wt_session_strerror(WT_SESSION_IMPL *session, int error)
{
DWORD lasterror;
const char *p;
-
- /* Require at least 2 bytes, printable character and trailing nul. */
- if (buflen < 2)
- return (ENOMEM);
+ char buf[256];
/*
* Check for POSIX errors, Windows errors, then fallback to something
* generic. Copy the string into the user's buffer, return success if
* anything printed.
*/
- p = __wt_strerror(error);
- if (p != NULL && snprintf(buf, buflen, "%s", p) > 0)
- return (0);
+ if ((p = __wt_strerror(error)) != NULL)
+ return (p);
if (error < 0) {
error = __wt_map_error_to_windows_error(error);
@@ -109,16 +105,16 @@ __wt_strerror_r(int error, char *buf, size_t buflen)
error,
0, /* let system choose the correct LANGID */
buf,
- buflen,
+ sizeof(buf),
NULL);
- if (lasterror != 0)
- return (0);
+ if (lasterror != 0 &&
+ __wt_buf_set(session, &session->err, buf, strlen(buf)) == 0)
+ return (session->err.data);
/* Fall through to the fallback error code */
}
- /* Fallback to a generic message, then guess it's a memory problem. */
- return (
- snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM);
+ /* Defeated. */
+ return ("Unable to return error string");
}
diff --git a/src/session/session_api.c b/src/session/session_api.c
index 0affc567583..986473ae1cc 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -128,8 +128,9 @@ __session_close(WT_SESSION *wt_session, const char *config)
/* Discard metadata tracking. */
__wt_meta_track_discard(session);
- /* Discard scratch buffers. */
+ /* Discard scratch buffers, error memory. */
__wt_scr_discard(session);
+ __wt_buf_free(session, &session->err);
/* Free transaction information. */
__wt_txn_destroy(session);
@@ -902,6 +903,27 @@ err: F_CLR(session, WT_SESSION_CAN_WAIT | WT_SESSION_NO_CACHE_CHECK);
}
/*
+ * __session_strerror --
+ * WT_SESSION->strerror method.
+ */
+static const char *
+__session_strerror(WT_SESSION *wt_session, int error)
+{
+ WT_SESSION_IMPL *session;
+ const char *p;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+
+ /* Check for a constant string. */
+ if ((p = __wt_wiredtiger_error(error)) != NULL)
+ return (p);
+ if ((p = __wt_strerror(error)) != NULL)
+ return (p);
+
+ return (__wt_session_strerror(session, error));
+}
+
+/*
* __wt_open_internal_session --
* Allocate a session for WiredTiger's use.
*/
@@ -963,6 +985,7 @@ __wt_open_session(WT_CONNECTION_IMPL *conn,
NULL,
__session_close,
__session_reconfigure,
+ __session_strerror,
__session_open_cursor,
__session_create,
__session_compact,
diff --git a/src/support/err.c b/src/support/err.c
index d766fcba33a..49a3891c58a 100644
--- a/src/support/err.c
+++ b/src/support/err.c
@@ -409,6 +409,20 @@ __wt_ext_msg_printf(
}
/*
+ * __wt_ext_strerror --
+ * Extension API call to return an error as a string.
+ */
+const char *
+__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error)
+{
+ if (wt_session == NULL)
+ wt_session = (WT_SESSION *)
+ ((WT_CONNECTION_IMPL *)wt_api->conn)->default_session;
+
+ return (wt_session->strerror(wt_session, error));
+}
+
+/*
* __wt_progress --
* Progress message.
*/