diff options
-rw-r--r-- | build_win/wiredtiger.def | 1 | ||||
-rw-r--r-- | dist/api_data.py | 1 | ||||
-rw-r--r-- | dist/api_err.py | 39 | ||||
-rw-r--r-- | dist/s_export.list | 1 | ||||
-rw-r--r-- | examples/c/ex_all.c | 8 | ||||
-rw-r--r-- | examples/c/ex_data_source.c | 5 | ||||
-rw-r--r-- | ext/datasources/helium/helium.c | 55 | ||||
-rw-r--r-- | ext/test/kvs_bdb/kvs_bdb.c | 15 | ||||
-rw-r--r-- | src/config/config_def.c | 4 | ||||
-rw-r--r-- | src/conn/api_strerror.c | 39 | ||||
-rw-r--r-- | src/conn/conn_api.c | 2 | ||||
-rw-r--r-- | src/include/config.h | 17 | ||||
-rw-r--r-- | src/include/extern.h | 4 | ||||
-rw-r--r-- | src/include/session.h | 2 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 23 | ||||
-rw-r--r-- | src/include/wiredtiger_ext.h | 11 | ||||
-rw-r--r-- | src/os_posix/os_errno.c | 30 | ||||
-rw-r--r-- | src/os_win/os_errno.c | 30 | ||||
-rw-r--r-- | src/session/session_api.c | 25 | ||||
-rw-r--r-- | src/support/err.c | 14 |
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. */ |