summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build_win/wiredtiger.def1
-rw-r--r--dist/api_data.py1
-rw-r--r--dist/api_err.py39
-rw-r--r--dist/s_export.list1
-rw-r--r--examples/c/ex_all.c8
-rw-r--r--examples/c/ex_data_source.c5
-rw-r--r--ext/datasources/helium/helium.c55
-rw-r--r--ext/test/kvs_bdb/kvs_bdb.c15
-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
20 files changed, 168 insertions, 158 deletions
diff --git a/build_win/wiredtiger.def b/build_win/wiredtiger.def
index 02884e4fd65..86096fb778d 100644
--- a/build_win/wiredtiger.def
+++ b/build_win/wiredtiger.def
@@ -9,7 +9,6 @@ EXPORTS
wiredtiger_pack_str
wiredtiger_pack_uint
wiredtiger_strerror
- wiredtiger_strerror_r
wiredtiger_struct_pack
wiredtiger_struct_size
wiredtiger_struct_unpack
diff --git a/dist/api_data.py b/dist/api_data.py
index 65af833c4a2..14ffa8d7ef8 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -713,6 +713,7 @@ methods = {
files''',
type='boolean'),
]),
+'session.strerror' : Method([]),
'session.truncate' : Method([]),
'session.upgrade' : Method([]),
'session.verify' : Method([
diff --git a/dist/api_err.py b/dist/api_err.py
index 6c893c9af82..d1ab1bca65d 100644
--- a/dist/api_err.py
+++ b/dist/api_err.py
@@ -88,7 +88,7 @@ tfile.write('''/* DO NOT EDIT: automatically built by dist/api_err.py. */
/*
* 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
@@ -99,8 +99,8 @@ tfile.write('''/* DO NOT EDIT: automatically built by dist/api_err.py. */
* __wiredtiger_error --
*\tReturn a constant string for the WiredTiger errors.
*/
-static const char *
-__wiredtiger_error(int error)
+const char *
+__wt_wiredtiger_error(int error)
{
\tswitch (error) {
''')
@@ -124,36 +124,17 @@ wiredtiger_strerror(int error)
\tconst char *p;
\t/* Check for a constant string. */
-\tif ((p = __wiredtiger_error(error)) != NULL ||
-\t (p = __wt_strerror(error)) != NULL)
+\tif ((p = __wt_wiredtiger_error(error)) != NULL)
+\t\treturn (p);
+\tif ((p = __wt_strerror(error)) != NULL)
\t\treturn (p);
\t/* Else, fill in the non-thread-safe static buffer. */
-\tif (wiredtiger_strerror_r(error, buf, sizeof(buf)) != 0)
-\t\t(void)snprintf(buf, sizeof(buf), "error return: %d", error);
-
-\treturn (buf);
-}
-
-/*
- * wiredtiger_strerror_r --
- *\tReturn a string for any error value, thread-safe version.
- */
-int
-wiredtiger_strerror_r(int error, char *buf, size_t buflen)
-{
-\tconst char *p;
-
-\t/* Require at least 2 bytes, printable character and trailing nul. */
-\tif (buflen < 2)
-\t\treturn (ENOMEM);
-
-\t/* Check for a constant string. */
-\tif ((p = __wiredtiger_error(error)) != NULL ||
-\t (p = __wt_strerror(error)) != NULL)
-\t\treturn (snprintf(buf, buflen, "%s", p) > 0 ? 0 : ENOMEM);
+\tif (snprintf(buf, sizeof(buf), "error return: %d", error) > 0)
+\t\treturn (buf);
-\treturn (__wt_strerror_r(error, buf, buflen));
+\t/* OK, we're done. */
+\treturn ("Unable to return error string");
}
''')
tfile.close()
diff --git a/dist/s_export.list b/dist/s_export.list
index 8f469e94433..d3803bc3afa 100644
--- a/dist/s_export.list
+++ b/dist/s_export.list
@@ -8,7 +8,6 @@ wiredtiger_pack_start
wiredtiger_pack_str
wiredtiger_pack_uint
wiredtiger_strerror
-wiredtiger_strerror_r
wiredtiger_struct_pack
wiredtiger_struct_size
wiredtiger_struct_unpack
diff --git a/examples/c/ex_all.c b/examples/c/ex_all.c
index 51b4bb42040..51c63e307c6 100644
--- a/examples/c/ex_all.c
+++ b/examples/c/ex_all.c
@@ -357,12 +357,8 @@ cursor_ops(WT_SESSION *session)
const char *key = "non-existent key";
cursor->set_key(cursor, key);
if ((ret = cursor->remove(cursor)) != 0) {
- char buf[128];
-
- if (wiredtiger_strerror_r(ret, buf, sizeof(buf)) != 0)
- (void)snprintf(
- buf, sizeof(buf), "error value: %d\n", ret);
- fprintf(stderr, "cursor.remove: %s\n", buf);
+ fprintf(stderr,
+ "cursor.remove: %s\n", session->strerror(session, ret));
return (ret);
}
/*! [Display an error thread safe] */
diff --git a/examples/c/ex_data_source.c b/examples/c/ex_data_source.c
index 5043fa1b67d..7fb400b5922 100644
--- a/examples/c/ex_data_source.c
+++ b/examples/c/ex_data_source.c
@@ -75,8 +75,9 @@ my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
{
int ret = 0;
/*! [WT_EXTENSION_API strerror] */
- (void)wt_api->err_printf(wt_api,
- session, "WiredTiger error return: %s", wt_api->strerror(ret));
+ (void)wt_api->err_printf(wt_api, session,
+ "WiredTiger error return: %s",
+ wt_api->strerror(wt_api, session, ret));
/*! [WT_EXTENSION_API strerror] */
}
diff --git a/ext/datasources/helium/helium.c b/ext/datasources/helium/helium.c
index d62ecb846e9..3fc521d93b2 100644
--- a/ext/datasources/helium/helium.c
+++ b/ext/datasources/helium/helium.c
@@ -1913,7 +1913,7 @@ bad_name: ERET(wtext, session, EINVAL, "%s: illegal name format", uri);
if (ret != 0 && ret != WT_NOTFOUND)
EMSG_ERR(wtext, session, ret,
"helium_o_truncate configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
if ((ret = ws_source_open_object(
wtds, session, hs, uri, NULL, oflags, &ws->he)) != 0)
@@ -2041,7 +2041,8 @@ master_uri_set(WT_DATA_SOURCE *wtds,
exclusive = a.val != 0;
else if (ret != WT_NOTFOUND)
ERET(wtext, session, ret,
- "exclusive configuration: %s", wtext->strerror(ret));
+ "exclusive configuration: %s",
+ wtext->strerror(wtext, session, ret));
/* Get the key/value format strings. */
if ((ret = wtext->config_get(
@@ -2052,7 +2053,7 @@ master_uri_set(WT_DATA_SOURCE *wtds,
} else
ERET(wtext, session, ret,
"key_format configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
}
if ((ret = wtext->config_get(
wtext, session, config, "value_format", &b)) != 0) {
@@ -2062,7 +2063,7 @@ master_uri_set(WT_DATA_SOURCE *wtds,
} else
ERET(wtext, session, ret,
"value_format configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
}
/* Get the compression configuration. */
@@ -2073,7 +2074,7 @@ master_uri_set(WT_DATA_SOURCE *wtds,
else
ERET(wtext, session, ret,
"helium_o_compress configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
}
/*
@@ -2090,7 +2091,8 @@ master_uri_set(WT_DATA_SOURCE *wtds,
return (0);
if (ret == WT_DUPLICATE_KEY)
return (exclusive ? EEXIST : 0);
- ERET(wtext, session, ret, "%s: %s", uri, wtext->strerror(ret));
+ ERET(wtext,
+ session, ret, "%s: %s", uri, wtext->strerror(wtext, session, ret));
}
/*
@@ -2129,19 +2131,22 @@ helium_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
if ((ret = wtext->config_get( /* Parse configuration */
wtext, session, config, "append", &v)) != 0)
EMSG_ERR(wtext, session, ret,
- "append configuration: %s", wtext->strerror(ret));
+ "append configuration: %s",
+ wtext->strerror(wtext, session, ret));
cursor->config_append = v.val != 0;
if ((ret = wtext->config_get(
wtext, session, config, "overwrite", &v)) != 0)
EMSG_ERR(wtext, session, ret,
- "overwrite configuration: %s", wtext->strerror(ret));
+ "overwrite configuration: %s",
+ wtext->strerror(wtext, session, ret));
cursor->config_overwrite = v.val != 0;
if ((ret = wtext->collator_config(
wtext, session, uri, config, NULL, &own)) != 0)
EMSG_ERR(wtext, session, ret,
- "collator configuration: %s", wtext->strerror(ret));
+ "collator configuration: %s",
+ wtext->strerror(wtext, session, ret));
/* Finish initializing the cursor. */
cursor->wtcursor.close = helium_cursor_close;
@@ -2178,19 +2183,19 @@ helium_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
session, value, strlen(value), &config_parser)) != 0)
EMSG_ERR(wtext, session, ret,
"Configuration string parser: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
if ((ret = config_parser->get(
config_parser, "key_format", &v)) != 0)
EMSG_ERR(wtext, session, ret,
"key_format configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
ws->config_recno = v.len == 1 && v.str[0] == 'r';
if ((ret = config_parser->get(
config_parser, "value_format", &v)) != 0)
EMSG_ERR(wtext, session, ret,
"value_format configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
ws->config_bitfield =
v.len == 2 && isdigit(v.str[0]) && v.str[1] == 't';
@@ -2198,7 +2203,7 @@ helium_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
config_parser, "helium_o_compress", &v)) != 0)
EMSG_ERR(wtext, session, ret,
"helium_o_compress configuration: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, session, ret));
ws->config_compress = v.val ? 1 : 0;
/*
@@ -2237,7 +2242,8 @@ err: if (ws != NULL && locked)
if (config_parser != NULL &&
(tret = config_parser->close(config_parser)) != 0)
EMSG(wtext, session, tret,
- "WT_CONFIG_PARSER.close: %s", wtext->strerror(tret));
+ "WT_CONFIG_PARSER.close: %s",
+ wtext->strerror(wtext, session, tret));
free((void *)value);
return (ret);
@@ -2913,7 +2919,7 @@ helium_config_read(WT_EXTENSION_API *wtext, WT_CONFIG_ITEM *config,
wtext, NULL, config->str, config->len, &config_parser)) != 0)
ERET(wtext, NULL, ret,
"WT_EXTENSION_API.config_parser_open: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, NULL, ret));
while ((ret = config_parser->next(config_parser, &k, &v)) == 0) {
if (string_match("helium_devices", k.str, k.len)) {
if ((*devicep = calloc(1, v.len + 1)) == NULL)
@@ -2944,11 +2950,13 @@ helium_config_read(WT_EXTENSION_API *wtext, WT_CONFIG_ITEM *config,
ret = 0;
if (ret != 0)
EMSG_ERR(wtext, NULL, ret,
- "WT_CONFIG_PARSER.next: %s", wtext->strerror(ret));
+ "WT_CONFIG_PARSER.next: %s",
+ wtext->strerror(wtext, NULL, ret));
err: if ((tret = config_parser->close(config_parser)) != 0)
EMSG(wtext, NULL, tret,
- "WT_CONFIG_PARSER.close: %s", wtext->strerror(tret));
+ "WT_CONFIG_PARSER.close: %s",
+ wtext->strerror(wtext, NULL, tret));
return (ret);
}
@@ -3373,14 +3381,14 @@ wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
if ((ret = wtext->config_get(wtext, NULL, config, "config", &v)) != 0)
EMSG_ERR(wtext, NULL, ret,
"WT_EXTENSION_API.config_get: config: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, NULL, ret));
/* Step through the list of Helium sources, opening each one. */
if ((ret = wtext->config_parser_open(
wtext, NULL, v.str, v.len, &config_parser)) != 0)
EMSG_ERR(wtext, NULL, ret,
"WT_EXTENSION_API.config_parser_open: config: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, NULL, ret));
while ((ret = config_parser->next(config_parser, &k, &v)) == 0) {
if (string_match("helium_verbose", k.str, k.len)) {
verbose = v.val == 0 ? 0 : 1;
@@ -3392,11 +3400,11 @@ wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
if (ret != WT_NOTFOUND)
EMSG_ERR(wtext, NULL, ret,
"WT_CONFIG_PARSER.next: config: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, NULL, ret));
if ((ret = config_parser->close(config_parser)) != 0)
EMSG_ERR(wtext, NULL, ret,
"WT_CONFIG_PARSER.close: config: %s",
- wtext->strerror(ret));
+ wtext->strerror(wtext, NULL, ret));
config_parser = NULL;
/* Find and open the database transaction store. */
@@ -3423,13 +3431,14 @@ wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
EMSG_ERR(wtext, NULL, ret,
"WT_CONNECTION.configure_method: session.create: "
"%s: %s",
- *p, wtext->strerror(ret));
+ *p, wtext->strerror(wtext, NULL, ret));
/* Add the data source */
if ((ret = connection->add_data_source(
connection, "helium:", (WT_DATA_SOURCE *)ds, NULL)) != 0)
EMSG_ERR(wtext, NULL, ret,
- "WT_CONNECTION.add_data_source: %s", wtext->strerror(ret));
+ "WT_CONNECTION.add_data_source: %s",
+ wtext->strerror(wtext, NULL, ret));
return (0);
err: if (ds != NULL)
diff --git a/ext/test/kvs_bdb/kvs_bdb.c b/ext/test/kvs_bdb/kvs_bdb.c
index 48305937236..76dccb89bf2 100644
--- a/ext/test/kvs_bdb/kvs_bdb.c
+++ b/ext/test/kvs_bdb/kvs_bdb.c
@@ -722,7 +722,8 @@ kvs_session_create(WT_DATA_SOURCE *wtds,
if ((ret =
wtext->config_get(wtext, session, config, "key_format", &v)) != 0)
ERET(wtext, session, ret,
- "key_format configuration: %s", wtext->strerror(ret));
+ "key_format configuration: %s",
+ wtext->strerror(wtext, session, ret));
type = v.len == 1 && v.str[0] == 'r' ? DB_RECNO : DB_BTREE;
/* Create the Berkeley DB table */
@@ -798,7 +799,8 @@ kvs_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
if ((ret = wtext->config_get(
wtext, session, config, "append", &v)) != 0) {
ESET(wtext, session, ret,
- "append configuration: %s", wtext->strerror(ret));
+ "append configuration: %s",
+ wtext->strerror(wtext, session, ret));
goto err;
}
cursor->config_append = v.val != 0;
@@ -806,7 +808,8 @@ kvs_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
if ((ret = wtext->config_get(
wtext, session, config, "overwrite", &v)) != 0) {
ESET(wtext, session, ret,
- "overwrite configuration: %s", wtext->strerror(ret));
+ "overwrite configuration: %s",
+ wtext->strerror(wtext, session, ret));
goto err;
}
cursor->config_overwrite = v.val != 0;
@@ -814,7 +817,8 @@ kvs_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
if ((ret = wtext->config_get(
wtext, session, config, "key_format", &v)) != 0) {
ESET(wtext, session, ret,
- "key_format configuration: %s", wtext->strerror(ret));
+ "key_format configuration: %s",
+ wtext->strerror(wtext, session, ret));
goto err;
}
cursor->config_recno = v.len == 1 && v.str[0] == 'r';
@@ -822,7 +826,8 @@ kvs_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
if ((ret = wtext->config_get(
wtext, session, config, "value_format", &v)) != 0) {
ESET(wtext, session, ret,
- "value_format configuration: %s", wtext->strerror(ret));
+ "value_format configuration: %s",
+ wtext->strerror(wtext, session, ret));
goto err;
}
cursor->config_bitfield =
diff --git a/src/config/config_def.c b/src/config/config_def.c
index a7e9419a65c..eac4219871c 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -664,6 +664,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 396ae7a3e0f..07302f5cf20 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:
@@ -47,34 +47,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 e47f4ba09c0..4ce7d39f9e2 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);
@@ -436,7 +437,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);
@@ -572,6 +573,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 21a4a657506..0700f897c57 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
* @{
*/
@@ -2081,18 +2092,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 8ee143133ae..b5021cfbf71 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);
@@ -898,6 +899,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.
*/
@@ -959,6 +981,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.
*/