diff options
Diffstat (limited to 'db/tcl')
-rw-r--r-- | db/tcl/docs/db.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/env.html | 6 | ||||
-rw-r--r-- | db/tcl/docs/historic.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/index.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/library.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/lock.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/log.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/mpool.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/rep.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/sequence.html | 92 | ||||
-rw-r--r-- | db/tcl/docs/test.html | 2 | ||||
-rw-r--r-- | db/tcl/docs/txn.html | 2 | ||||
-rw-r--r-- | db/tcl/tcl_compat.c | 80 | ||||
-rw-r--r-- | db/tcl/tcl_db.c | 467 | ||||
-rw-r--r-- | db/tcl/tcl_db_pkg.c | 698 | ||||
-rw-r--r-- | db/tcl/tcl_dbcursor.c | 69 | ||||
-rw-r--r-- | db/tcl/tcl_env.c | 364 | ||||
-rw-r--r-- | db/tcl/tcl_internal.c | 169 | ||||
-rw-r--r-- | db/tcl/tcl_lock.c | 59 | ||||
-rw-r--r-- | db/tcl/tcl_log.c | 18 | ||||
-rw-r--r-- | db/tcl/tcl_mp.c | 65 | ||||
-rw-r--r-- | db/tcl/tcl_rep.c | 84 | ||||
-rw-r--r-- | db/tcl/tcl_seq.c | 526 | ||||
-rw-r--r-- | db/tcl/tcl_txn.c | 57 | ||||
-rw-r--r-- | db/tcl/tcl_util.c | 76 |
25 files changed, 2065 insertions, 785 deletions
diff --git a/db/tcl/docs/db.html b/db/tcl/docs/db.html index 8ef5e032a..db8382b75 100644 --- a/db/tcl/docs/db.html +++ b/db/tcl/docs/db.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/env.html b/db/tcl/docs/env.html index 6ac534dba..3203a02b8 100644 --- a/db/tcl/docs/env.html +++ b/db/tcl/docs/env.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <html> <head> @@ -274,10 +274,6 @@ or <b>off</b> for that subsystem. The value of <b><i>which</i></b> must be one of the following: <ul> <li> -<b>chkpt</b> - Chooses the checkpointing code by using the DB_VERB_CHKPOINT -value</li> - -<li> <b>deadlock </b>- Chooses the deadlocking code by using the DB_VERB_DEADLOCK value</li> diff --git a/db/tcl/docs/historic.html b/db/tcl/docs/historic.html index cbea28b20..f5a43e14d 100644 --- a/db/tcl/docs/historic.html +++ b/db/tcl/docs/historic.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/index.html b/db/tcl/docs/index.html index 2b4598b55..4f4e1e90c 100644 --- a/db/tcl/docs/index.html +++ b/db/tcl/docs/index.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/library.html b/db/tcl/docs/library.html index eb313b042..217213ed8 100644 --- a/db/tcl/docs/library.html +++ b/db/tcl/docs/library.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/lock.html b/db/tcl/docs/lock.html index 4e9a13a3f..75e0bb2de 100644 --- a/db/tcl/docs/lock.html +++ b/db/tcl/docs/lock.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <html> <head> diff --git a/db/tcl/docs/log.html b/db/tcl/docs/log.html index de9edb838..5fdd132d5 100644 --- a/db/tcl/docs/log.html +++ b/db/tcl/docs/log.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/mpool.html b/db/tcl/docs/mpool.html index 84bb7beaa..83c1f452c 100644 --- a/db/tcl/docs/mpool.html +++ b/db/tcl/docs/mpool.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/rep.html b/db/tcl/docs/rep.html index 47686d3d5..d50b62375 100644 --- a/db/tcl/docs/rep.html +++ b/db/tcl/docs/rep.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <html> <head> diff --git a/db/tcl/docs/sequence.html b/db/tcl/docs/sequence.html new file mode 100644 index 000000000..a0b3df068 --- /dev/null +++ b/db/tcl/docs/sequence.html @@ -0,0 +1,92 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta http-equiv="content-type" + content="text/html; charset=ISO-8859-1"> + <title>Sequence Commands</title> +</head> +<body> +<h2><a name="Database Commands"></a>Sequence Commands</h2> +<b>> berkdb sequence [-auto_commit] [-txn txnid] [-create] </b><br> +<div style="margin-left: 40px;"> Implements <a + href="file:///home/ubell/db.new/docs/seq/seq_open.html">DBENV->sequence</a> +function. The above options have the usual meanings.<br> +</div> +<span style="font-weight: bold;">[-cachesize]</span><br> +<div style="margin-left: 40px;">Set the size of the cache in this +handle.<br> +</div> +<span style="font-weight: bold;">[-inc]<br> +</span> +<div style="margin-left: 40px;">Sequence increments..<br> +</div> +<span style="font-weight: bold;">[-dec]<br> +</span> +<div style="margin-left: 40px;">Sequence decrements.<br> +</div> +<span style="font-weight: bold;">[-init integer]<br> +</span> +<div style="margin-left: 40px;">Set the initial value for sequence.<br> +</div> +<span style="font-weight: bold;">[-max integer]</span><br> +<div style="margin-left: 40px;">Set the maximum value for the sequence.<br> +</div> +<span style="font-weight: bold;">[-max integer]<br> +</span> +<div style="margin-left: 40px;">Set the minimum value for the sequence.<br> +</div> +<span style="font-weight: bold;">[-wrap]</span><br> +<div style="margin-left: 40px;">Wrap around at max or min.<br> +</div> +<span style="font-weight: bold;"><span style="font-style: italic;">db</span> +key<br> +</span> +<div style="margin-left: 40px;">Database handle and key of sequence.<br> +</div> +<hr width="100%"><span style="font-style: italic;"><span + style="font-weight: bold;">> seq </span></span><span + style="font-weight: bold;">get [-txn <span style="font-style: italic;">txn</span>] +[-auto_commit] [-nosync] delta<br> +</span> +<div style="margin-left: 40px;">Get the nexted sequence value and +increment the sequence by <span style="font-weight: bold;">delta</span>.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq </span>close</span><br> +<div style="margin-left: 40px;">Close the sequence<br> +</div> +<br> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq</span> remove [-auto_commit] [-nosync] +[-txn] <br> +</span> +<div style="margin-left: 40px;">Remove the sequence.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq </span>get_cachesize<br> +</span> +<div style="margin-left: 40px;">Return the size of the cache.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq </span>get_db<br> +</span> +<div style="margin-left: 40px;">Return the underlying db handle.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq </span>get_flags</span><br> +<div style="margin-left: 40px;">Return the flags set on create.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq</span> get_range<br> +</span> +<div style="margin-left: 40px;">Return the min and max set at create.<br> +</div> +<hr width="100%"><span style="font-weight: bold;">> <span + style="font-style: italic;">seq </span>stat<br> +</span> +<div style="margin-left: 40px;">Implements the <a + href="../../docs/seq/seq_stat.html">SEQUENCE->stat</a> function.<br> +</div> +<hr width="100%"> +</body> +</html> diff --git a/db/tcl/docs/test.html b/db/tcl/docs/test.html index cfaaf0de3..a01140183 100644 --- a/db/tcl/docs/test.html +++ b/db/tcl/docs/test.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <HTML> <HEAD> diff --git a/db/tcl/docs/txn.html b/db/tcl/docs/txn.html index 0a6b6f7dd..8abef4b31 100644 --- a/db/tcl/docs/txn.html +++ b/db/tcl/docs/txn.html @@ -1,4 +1,4 @@ -<!--Copyright 1999-2003 by Sleepycat Software, Inc.--> +<!--Copyright 1999-2004 by Sleepycat Software, Inc.--> <!--All rights reserved.--> <html> <head> diff --git a/db/tcl/tcl_compat.c b/db/tcl/tcl_compat.c index 8a25c618b..8b518f761 100644 --- a/db/tcl/tcl_compat.c +++ b/db/tcl/tcl_compat.c @@ -1,17 +1,15 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_compat.c,v 11.46 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_compat.c,v 11.41 2003/03/10 18:22:09 bostic Exp $"; -#endif /* not lint */ - -#if CONFIG_TEST +#ifdef CONFIG_TEST #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -87,8 +85,9 @@ bdb_HCommand(interp, objc, objv) result = Tcl_GetIntFromObj(interp, objv[2], &nelem); if (result == TCL_OK) { _debug_check(); - ret = hcreate(nelem) == 0 ? 1: 0; - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "hcreate"); + ret = hcreate((size_t)nelem) == 0 ? 1: 0; + (void)_ReturnSetup( + interp, ret, DB_RETOK_STD(ret), "hcreate"); } break; case HHSEARCH: @@ -133,7 +132,7 @@ bdb_HCommand(interp, objc, objv) return (TCL_ERROR); } _debug_check(); - (void)hdestroy(); + hdestroy(); res = Tcl_NewIntObj(0); break; } @@ -178,14 +177,11 @@ bdb_NdbmOpen(interp, objc, objv, dbpp) NDB_ENDARG }; - u_int32_t open_flags; - int endarg, i, mode, optindex, read_only, result, ret; + int endarg, i, mode, open_flags, optindex, read_only, result, ret; char *arg, *db; result = TCL_OK; - open_flags = 0; - endarg = mode = 0; - read_only = 0; + endarg = mode = open_flags = read_only = 0; if (objc < 2) { Tcl_WrongNumArgs(interp, 2, objv, "?args?"); @@ -237,7 +233,7 @@ bdb_NdbmOpen(interp, objc, objv, dbpp) case NDB_ENDARG: endarg = 1; break; - } /* switch */ + } /* * If, at any time, parsing the args we get an error, @@ -341,6 +337,8 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) result = TCL_OK; freekey = freedata = 0; + dtmp = ktmp = NULL; + /* * Get the command name index from the object based on the cmds * defined above. This SHOULD NOT fail because we already checked @@ -367,7 +365,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) "Bad interface flag for command", TCL_STATIC); return (TCL_ERROR); } - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbmclose"); + (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbmclose"); break; case DBMINIT: /* @@ -385,7 +383,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) TCL_STATIC); return (TCL_ERROR); } - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbminit"); + (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbminit"); break; case DBMFETCH: /* @@ -401,7 +399,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) DB_RETOK_STD(ret), "dbm fetch"); goto out; } - key.dsize = size; + key.dsize = (int)size; key.dptr = (char *)ktmp; _debug_check(); if (flag == DBTCL_DBM) @@ -415,10 +413,10 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) goto out; } if (data.dptr == NULL || - (ret = __os_malloc(NULL, data.dsize + 1, &t)) != 0) + (ret = __os_malloc(NULL, (size_t)data.dsize + 1, &t)) != 0) Tcl_SetResult(interp, "-1", TCL_STATIC); else { - memcpy(t, data.dptr, data.dsize); + memcpy(t, data.dptr, (size_t)data.dsize); t[data.dsize] = '\0'; Tcl_SetResult(interp, t, TCL_VOLATILE); __os_free(NULL, t); @@ -442,7 +440,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) DB_RETOK_STD(ret), "dbm fetch"); goto out; } - key.dsize = size; + key.dsize = (int)size; key.dptr = (char *)ktmp; if ((ret = _CopyObjBytes( interp, objv[3], &dtmp, &size, &freedata)) != 0) { @@ -450,7 +448,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) DB_RETOK_STD(ret), "dbm fetch"); goto out; } - data.dsize = size; + data.dsize = (int)size; data.dptr = (char *)dtmp; _debug_check(); if (flag == DBTCL_DBM) @@ -473,7 +471,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) "Bad interface flag for command", TCL_STATIC); return (TCL_ERROR); } - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "store"); + (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "store"); break; case DBMDELETE: /* @@ -489,7 +487,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) DB_RETOK_STD(ret), "dbm fetch"); goto out; } - key.dsize = size; + key.dsize = (int)size; key.dptr = (char *)ktmp; _debug_check(); if (flag == DBTCL_DBM) @@ -501,7 +499,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) "Bad interface flag for command", TCL_STATIC); return (TCL_ERROR); } - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "delete"); + (void)_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "delete"); break; case DBMFIRST: /* @@ -522,10 +520,10 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) return (TCL_ERROR); } if (key.dptr == NULL || - (ret = __os_malloc(NULL, key.dsize + 1, &t)) != 0) + (ret = __os_malloc(NULL, (size_t)key.dsize + 1, &t)) != 0) Tcl_SetResult(interp, "-1", TCL_STATIC); else { - memcpy(t, key.dptr, key.dsize); + memcpy(t, key.dptr, (size_t)key.dsize); t[key.dsize] = '\0'; Tcl_SetResult(interp, t, TCL_VOLATILE); __os_free(NULL, t); @@ -547,7 +545,7 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) DB_RETOK_STD(ret), "dbm fetch"); goto out; } - key.dsize = size; + key.dsize = (int)size; key.dptr = (char *)ktmp; data = nextkey(key); } else if (flag == DBTCL_NDBM) { @@ -562,21 +560,21 @@ bdb_DbmCommand(interp, objc, objv, flag, dbm) return (TCL_ERROR); } if (data.dptr == NULL || - (ret = __os_malloc(NULL, data.dsize + 1, &t)) != 0) + (ret = __os_malloc(NULL, (size_t)data.dsize + 1, &t)) != 0) Tcl_SetResult(interp, "-1", TCL_STATIC); else { - memcpy(t, data.dptr, data.dsize); + memcpy(t, data.dptr, (size_t)data.dsize); t[data.dsize] = '\0'; Tcl_SetResult(interp, t, TCL_VOLATILE); __os_free(NULL, t); } break; } -out: - if (freedata) - (void)__os_free(NULL, dtmp); - if (freekey) - (void)__os_free(NULL, ktmp); + +out: if (dtmp != NULL && freedata) + __os_free(NULL, dtmp); + if (ktmp != NULL && freekey) + __os_free(NULL, ktmp); return (result); } @@ -677,8 +675,8 @@ ndbm_Cmd(clientData, interp, objc, objv) _debug_check(); ret = dbm_clearerr(dbp); if (ret) - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "clearerr"); + (void)_ReturnSetup( + interp, ret, DB_RETOK_STD(ret), "clearerr"); else res = Tcl_NewIntObj(ret); break; @@ -731,14 +729,16 @@ ndbm_Cmd(clientData, interp, objc, objv) _debug_check(); ret = dbm_rdonly(dbp); if (ret) - _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "rdonly"); + (void)_ReturnSetup( + interp, ret, DB_RETOK_STD(ret), "rdonly"); else res = Tcl_NewIntObj(ret); break; } + /* - * Only set result if we have a res. Otherwise, lower - * functions have already done so. + * Only set result if we have a res. Otherwise, lower functions have + * already done so. */ if (result == TCL_OK && res) Tcl_SetObjResult(interp, res); diff --git a/db/tcl/tcl_db.c b/db/tcl/tcl_db.c index c5270e656..f60be3f43 100644 --- a/db/tcl/tcl_db.c +++ b/db/tcl/tcl_db.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_db.c,v 11.145 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_db.c,v 11.128 2003/11/18 21:36:02 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -33,7 +31,7 @@ static int tcl_DbClose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *, DBTCL_INFO *)); static int tcl_DbDelete __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *)); static int tcl_DbGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *, int)); -#if CONFIG_TEST +#ifdef CONFIG_TEST static int tcl_DbKeyRange __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *)); #endif static int tcl_DbPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *)); @@ -96,7 +94,7 @@ db_Cmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* The argument objects */ { static const char *dbcmds[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "keyrange", "pget", "rpcid", @@ -136,7 +134,7 @@ db_Cmd(clientData, interp, objc, objv) NULL }; enum dbcmds { -#if CONFIG_TEST +#ifdef CONFIG_TEST DBKEYRANGE, DBPGET, DBRPCID, @@ -213,7 +211,7 @@ db_Cmd(clientData, interp, objc, objv) res = NULL; switch ((enum dbcmds)cmdindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBKEYRANGE: result = tcl_DbKeyRange(interp, objc, objv, dbp); break; @@ -232,7 +230,7 @@ db_Cmd(clientData, interp, objc, objv) * !!! Retrieve the client ID from the dbp handle directly. * This is for testing purposes only. It is dbp-private data. */ - res = Tcl_NewLongObj(dbp->cl_id); + res = Tcl_NewLongObj((long)dbp->cl_id); break; case DBTEST: result = tcl_EnvTest(interp, objc, objv, dbp->dbenv); @@ -279,13 +277,13 @@ db_Cmd(clientData, interp, objc, objv) _debug_check(); ret = dbp->get_type(dbp, &type); if (type == DB_BTREE) - res = Tcl_NewStringObj("btree", strlen("btree")); + res = NewStringObj("btree", strlen("btree")); else if (type == DB_HASH) - res = Tcl_NewStringObj("hash", strlen("hash")); + res = NewStringObj("hash", strlen("hash")); else if (type == DB_RECNO) - res = Tcl_NewStringObj("recno", strlen("recno")); + res = NewStringObj("recno", strlen("recno")); else if (type == DB_QUEUE) - res = Tcl_NewStringObj("queue", strlen("queue")); + res = NewStringObj("queue", strlen("queue")); else { Tcl_SetResult(interp, "db gettype: Returned unknown type\n", TCL_STATIC); @@ -320,11 +318,10 @@ db_Cmd(clientData, interp, objc, objv) if (result == TCL_OK) { dbip->i_dbdbcid++; ip->i_parent = dbip; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)dbc_Cmd, (ClientData)dbc, NULL); - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(ip, dbc); } else _DeleteInfo(ip); @@ -343,11 +340,10 @@ db_Cmd(clientData, interp, objc, objv) if (result == TCL_OK) { dbip->i_dbdbcid++; ip->i_parent = dbip; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)dbc_Cmd, (ClientData)dbc, NULL); - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(ip, dbc); } else _DeleteInfo(ip); @@ -365,7 +361,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_bt_minkey(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_bt_minkey")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETCACHESIZE: if (objc != 2) { @@ -375,9 +371,9 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_cachesize(dbp, &gbytes, &bytes, &ncache); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_cachesize")) == TCL_OK) { - myobjv[0] = Tcl_NewIntObj(gbytes); - myobjv[1] = Tcl_NewIntObj(bytes); - myobjv[2] = Tcl_NewIntObj(ncache); + myobjv[0] = Tcl_NewIntObj((int)gbytes); + myobjv[1] = Tcl_NewIntObj((int)bytes); + myobjv[2] = Tcl_NewIntObj((int)ncache); res = Tcl_NewListObj(3, myobjv); } break; @@ -389,9 +385,8 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_dbname(dbp, &filename, &dbname); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_dbname")) == TCL_OK) { - myobjv[0] = Tcl_NewStringObj(filename, - strlen(filename)); - myobjv[1] = Tcl_NewStringObj(dbname, strlen(dbname)); + myobjv[0] = NewStringObj(filename, strlen(filename)); + myobjv[1] = NewStringObj(dbname, strlen(dbname)); res = Tcl_NewListObj(2, myobjv); } break; @@ -403,15 +398,12 @@ db_Cmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 1, objv, NULL); return (TCL_ERROR); } - ret = dbp->get_env(dbp, &dbenv); - if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "db get_env")) == TCL_OK) { - if (dbenv != NULL && (ip = _PtrToInfo(dbenv)) != NULL) { - envid = ip->i_name; - res = Tcl_NewStringObj(envid, strlen(envid)); - } else - Tcl_ResetResult(interp); - } + dbenv = dbp->get_env(dbp); + if (dbenv != NULL && (ip = _PtrToInfo(dbenv)) != NULL) { + envid = ip->i_name; + res = NewStringObj(envid, strlen(envid)); + } else + Tcl_ResetResult(interp); break; case DBGETERRPFX: if (objc != 2) { @@ -419,7 +411,7 @@ db_Cmd(clientData, interp, objc, objv) return (TCL_ERROR); } dbp->get_errpfx(dbp, &strval); - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case DBGETFLAGS: result = tcl_DbGetFlags(interp, objc, objv, dbp); @@ -432,7 +424,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_h_ffactor(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_h_ffactor")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETHNELEM: if (objc != 2) { @@ -442,7 +434,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_h_nelem(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_h_nelem")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETJOIN: result = tcl_DbGetjoin(interp, objc, objv, dbp); @@ -470,7 +462,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_pagesize(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_pagesize")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETQEXTENTSIZE: if (objc != 2) { @@ -480,7 +472,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_q_extentsize(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_q_extentsize")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETREDELIM: if (objc != 2) { @@ -500,17 +492,17 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_re_len(dbp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_re_len")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case DBGETREPAD: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return (TCL_ERROR); } - ret = dbp->get_re_pad(dbp, &result); + ret = dbp->get_re_pad(dbp, &intval); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_re_pad")) == TCL_OK) - res = Tcl_NewIntObj(result); + res = Tcl_NewIntObj((int)intval); break; case DBGETRESOURCE: if (objc != 2) { @@ -520,7 +512,7 @@ db_Cmd(clientData, interp, objc, objv) ret = dbp->get_re_source(dbp, &strval); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db get_re_source")) == TCL_OK) - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case DBTRUNCATE: result = tcl_DbTruncate(interp, objc, objv, dbp); @@ -545,37 +537,82 @@ tcl_DbStat(interp, objc, objv, dbp) Tcl_Obj *CONST objv[]; /* The argument objects */ DB *dbp; /* Database pointer */ { + static const char *dbstatopts[] = { +#ifdef CONFIG_TEST + "-degree_2", + "-dirty", +#endif + "-faststat", + "-txn", + NULL + }; + enum dbstatopts { +#ifdef CONFIG_TEST + DBCUR_DEGREE2, + DBCUR_DIRTY, +#endif + DBCUR_FASTSTAT, + DBCUR_TXN + }; + DBTYPE type; DB_BTREE_STAT *bsp; DB_HASH_STAT *hsp; DB_QUEUE_STAT *qsp; - void *sp; + DB_TXN *txn; Tcl_Obj *res, *flaglist, *myobjv[2]; - DBTYPE type; u_int32_t flag; - int result, ret; - char *arg; + int i, optindex, result, ret; + char *arg, msg[MSG_SIZE]; + void *sp; result = TCL_OK; flag = 0; - - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "?-faststat?"); - return (TCL_ERROR); - } - - if (objc == 3) { - arg = Tcl_GetStringFromObj(objv[2], NULL); - if (strcmp(arg, "-faststat") == 0) - flag = DB_FAST_STAT; - else { - Tcl_SetResult(interp, - "db stat: unknown arg", TCL_STATIC); - return (TCL_ERROR); + txn = NULL; + sp = NULL; + i = 2; + while (i < objc) { + if (Tcl_GetIndexFromObj(interp, objv[i], dbstatopts, "option", + TCL_EXACT, &optindex) != TCL_OK) { + result = IS_HELP(objv[i]); + goto error; } + i++; + switch ((enum dbstatopts)optindex) { +#ifdef CONFIG_TEST + case DBCUR_DEGREE2: + flag |= DB_DEGREE_2; + break; + case DBCUR_DIRTY: + flag |= DB_DIRTY_READ; + break; +#endif + case DBCUR_FASTSTAT: + flag |= DB_FAST_STAT; + break; + case DBCUR_TXN: + if (i == objc) { + Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?"); + result = TCL_ERROR; + break; + } + arg = Tcl_GetStringFromObj(objv[i++], NULL); + txn = NAME_TO_TXN(arg); + if (txn == NULL) { + snprintf(msg, MSG_SIZE, + "Stat: Invalid txn: %s\n", arg); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + result = TCL_ERROR; + } + break; + } + if (result != TCL_OK) + break; } + if (result != TCL_OK) + goto error; _debug_check(); - ret = dbp->stat(dbp, &sp, flag); + ret = dbp->stat(dbp, txn, &sp, flag); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db stat"); if (result == TCL_ERROR) return (result); @@ -644,6 +681,7 @@ tcl_DbStat(interp, objc, objv, dbp) MAKE_STAT_LIST("Leaf pages", bsp->bt_leaf_pg); MAKE_STAT_LIST("Duplicate pages", bsp->bt_dup_pg); MAKE_STAT_LIST("Overflow pages", bsp->bt_over_pg); + MAKE_STAT_LIST("Empty pages", bsp->bt_empty_pg); MAKE_STAT_LIST("Pages on freelist", bsp->bt_free); MAKE_STAT_LIST("Internal pages bytes free", bsp->bt_int_pgfree); @@ -662,8 +700,8 @@ tcl_DbStat(interp, objc, objv, dbp) * include all the interesting flags, and the integer value * isn't useful from Tcl--return the strings instead. */ - myobjv[0] = Tcl_NewStringObj("Flags", strlen("Flags")); - myobjv[1] = _GetFlagsList(interp, dbp->flags, __db_inmemdbflags); + myobjv[0] = NewStringObj("Flags", strlen("Flags")); + myobjv[1] = _GetFlagsList(interp, dbp->flags, __db_get_flags_fn()); flaglist = Tcl_NewListObj(2, myobjv); if (flaglist == NULL) { result = TCL_ERROR; @@ -675,7 +713,8 @@ tcl_DbStat(interp, objc, objv, dbp) Tcl_SetObjResult(interp, res); error: - (void)__os_ufree(dbp->dbenv, sp); + if (sp != NULL) + __os_ufree(dbp->dbenv, sp); return (result); } @@ -709,8 +748,7 @@ tcl_DbClose(interp, objc, objv, dbp, dbip) return (TCL_ERROR); } - i = 2; - while (i < objc) { + for (i = 2; i < objc; ++i) { if (Tcl_GetIndexFromObj(interp, objv[i], dbclose, "option", TCL_EXACT, &optindex) != TCL_OK) { arg = Tcl_GetStringFromObj(objv[i], NULL); @@ -720,7 +758,6 @@ tcl_DbClose(interp, objc, objv, dbp, dbip) Tcl_ResetResult(interp); break; } - i++; switch ((enum dbclose)optindex) { case TCL_DBCLOSE_NOSYNC: flag = DB_NOSYNC; @@ -760,7 +797,7 @@ tcl_DbPut(interp, objc, objv, dbp) DB *dbp; /* Database pointer */ { static const char *dbputopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-nodupdata", #endif "-append", @@ -771,7 +808,7 @@ tcl_DbPut(interp, objc, objv, dbp) NULL }; enum dbputopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST DBGET_NODUPDATA, #endif DBPUT_APPEND, @@ -803,6 +840,7 @@ tcl_DbPut(interp, objc, objv, dbp) return (TCL_ERROR); } + dtmp = ktmp = NULL; freekey = freedata = 0; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); @@ -850,7 +888,7 @@ tcl_DbPut(interp, objc, objv, dbp) return (IS_HELP(objv[i])); i++; switch ((enum dbputopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBGET_NODUPDATA: FLAG_CHECK(flag); flag = DB_NODUPDATA; @@ -937,6 +975,8 @@ tcl_DbPut(interp, objc, objv, dbp) return (result); } } else { + COMPQUIET(recno, 0); + ret = _CopyObjBytes(interp, objv[objc-2], &ktmp, &key.size, &freekey); if (ret != 0) { @@ -948,8 +988,7 @@ tcl_DbPut(interp, objc, objv, dbp) } if (auto_commit) flag |= DB_AUTO_COMMIT; - ret = _CopyObjBytes(interp, objv[objc-1], &dtmp, - &data.size, &freedata); + ret = _CopyObjBytes(interp, objv[objc-1], &dtmp, &data.size, &freedata); if (ret != 0) { result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put"); @@ -959,16 +998,18 @@ tcl_DbPut(interp, objc, objv, dbp) _debug_check(); ret = dbp->put(dbp, txn, &key, &data, flag); result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put"); + + /* We may have a returned record number. */ if (ret == 0 && - (type == DB_RECNO || type == DB_QUEUE) && flag == DB_APPEND) { + (type == DB_QUEUE || type == DB_RECNO) && flag == DB_APPEND) { res = Tcl_NewWideIntObj((Tcl_WideInt)recno); Tcl_SetObjResult(interp, res); } -out: - if (freedata) - (void)__os_free(dbp->dbenv, dtmp); - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + +out: if (dtmp != NULL && freedata) + __os_free(dbp->dbenv, dtmp); + if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); return (result); } @@ -984,7 +1025,8 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) int ispget; /* 1 for pget, 0 for get */ { static const char *dbgetopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST + "-degree2", "-dirty", "-multi", #endif @@ -1001,7 +1043,8 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) NULL }; enum dbgetopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST + DBGET_DEGREE2, DBGET_DIRTY, DBGET_MULTI, #endif @@ -1021,13 +1064,13 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) DBTYPE ptype, type; DB_TXN *txn; Tcl_Obj **elemv, *retlist; - void *dtmp, *ktmp; + db_recno_t precno, recno; u_int32_t aflag, flag, cflag, isdup, mflag, rmw; int elemc, end, endarg, freekey, freedata, i; int optindex, result, ret, useglob, useprecno, userecno; char *arg, *pattern, *prefix, msg[MSG_SIZE]; - db_recno_t precno, recno; -#if CONFIG_TEST + void *dtmp, *ktmp; +#ifdef CONFIG_TEST int bufsize; #endif @@ -1037,6 +1080,10 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) useglob = userecno = 0; txn = NULL; pattern = prefix = NULL; + dtmp = ktmp = NULL; +#ifdef CONFIG_TEST + COMPQUIET(bufsize, 0); +#endif if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "?-args? key"); @@ -1070,10 +1117,13 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) } i++; switch ((enum dbgetopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBGET_DIRTY: rmw |= DB_DIRTY_READ; break; + case DBGET_DEGREE2: + rmw |= DB_DEGREE_2; + break; case DBGET_MULTI: mflag |= DB_MULTIPLE; result = Tcl_GetIntFromObj(interp, objv[i], &bufsize); @@ -1174,7 +1224,7 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) case DBGET_ENDARG: endarg = 1; break; - } /* switch */ + } if (result != TCL_OK) break; if (endarg) @@ -1336,15 +1386,15 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) } key.data = ktmp; } -#if CONFIG_TEST +#ifdef CONFIG_TEST if (mflag & DB_MULTIPLE) { if ((ret = __os_malloc(dbp->dbenv, - bufsize, &save.data)) != 0) { + (size_t)bufsize, &save.data)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); goto out; } - save.ulen = bufsize; + save.ulen = (u_int32_t)bufsize; F_CLR(&save, DB_DBT_MALLOC); F_SET(&save, DB_DBT_USERMEM); } @@ -1403,19 +1453,22 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) /* * Free space from DBT. * - * If we set DB_DBT_MALLOC, we need to free the space if - * and only if we succeeded (and thus if DB allocated - * anything). If DB_DBT_MALLOC is not set, this is a bulk - * get buffer, and needs to be freed no matter what. + * If we set DB_DBT_MALLOC, we need to free the space if and + * only if we succeeded and if DB allocated anything (the + * pointer has changed from what we passed in). If + * DB_DBT_MALLOC is not set, this is a bulk get buffer, and + * needs to be freed no matter what. */ - if (F_ISSET(&key, DB_DBT_MALLOC) && ret == 0) - (void)__os_ufree(dbp->dbenv, key.data); - if (F_ISSET(&data, DB_DBT_MALLOC) && ret == 0) - (void)__os_ufree(dbp->dbenv, data.data); + if (F_ISSET(&key, DB_DBT_MALLOC) && ret == 0 && + key.data != ktmp) + __os_ufree(dbp->dbenv, key.data); + if (F_ISSET(&data, DB_DBT_MALLOC) && ret == 0 && + data.data != dtmp) + __os_ufree(dbp->dbenv, data.data); else if (!F_ISSET(&data, DB_DBT_MALLOC)) __os_free(dbp->dbenv, data.data); - if (ispget && ret == 0) - (void)__os_ufree(dbp->dbenv, pkey.data); + if (ispget && ret == 0 && pkey.data != save.data) + __os_ufree(dbp->dbenv, pkey.data); if (result == TCL_OK) Tcl_SetObjResult(interp, retlist); goto out; @@ -1496,17 +1549,17 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) "db get (cursor)"); if (result == TCL_ERROR) goto out1; - if (ret == 0 && pattern && - memcmp(key.data, prefix, strlen(prefix)) != 0) { - /* - * Free space from DB_DBT_MALLOC - */ - (void)__os_ufree(dbp->dbenv, data.data); - goto out1; - } - if (pattern) + if (pattern) { + if (ret == 0 && prefix != NULL && + memcmp(key.data, prefix, strlen(prefix)) != 0) { + /* + * Free space from DB_DBT_MALLOC + */ + __os_ufree(dbp->dbenv, data.data); + goto out1; + } cflag = DB_NEXT; - else + } else cflag = DB_NEXT_DUP; while (ret == 0 && result == TCL_OK) { @@ -1523,8 +1576,8 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) * Free space from DB_DBT_MALLOC */ if (ispget) - (void)__os_ufree(dbp->dbenv, pkey.data); - (void)__os_ufree(dbp->dbenv, data.data); + __os_ufree(dbp->dbenv, pkey.data); + __os_ufree(dbp->dbenv, data.data); if (result != TCL_OK) break; /* @@ -1542,17 +1595,17 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) ret = dbc->c_pget(dbc, &key, &pkey, &data, cflag | rmw); } else ret = dbc->c_get(dbc, &key, &data, cflag | rmw); - if (ret == 0 && pattern && + if (ret == 0 && prefix != NULL && memcmp(key.data, prefix, strlen(prefix)) != 0) { /* * Free space from DB_DBT_MALLOC */ - (void)__os_ufree(dbp->dbenv, data.data); + __os_ufree(dbp->dbenv, data.data); break; } } out1: - dbc->c_close(dbc); + (void)dbc->c_close(dbc); if (result == TCL_OK) Tcl_SetObjResult(interp, retlist); out: @@ -1563,10 +1616,10 @@ out: */ if (prefix != NULL) __os_free(dbp->dbenv, prefix); - if (freedata) - (void)__os_free(dbp->dbenv, dtmp); - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + if (dtmp != NULL && freedata) + __os_free(dbp->dbenv, dtmp); + if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); return (result); } @@ -1611,6 +1664,7 @@ tcl_DbDelete(interp, objc, objv, dbp) return (TCL_ERROR); } + ktmp = NULL; memset(&key, 0, sizeof(key)); /* * The first arg must be -auto_commit, -glob, -txn or a list of keys. @@ -1747,8 +1801,8 @@ tcl_DbDelete(interp, objc, objv, dbp) * If we have any error, set up return result and stop * processing keys. */ - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); if (ret != 0) break; } @@ -1815,7 +1869,7 @@ tcl_DbDelete(interp, objc, objv, dbp) * have multiple nuls at the end, so we free using __os_free(). */ __os_free(dbp->dbenv, prefix); - dbc->c_close(dbc); + (void)dbc->c_close(dbc); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db del"); } out: @@ -1834,7 +1888,8 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp) DBC **dbcp; /* Return cursor pointer */ { static const char *dbcuropts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST + "-degree_2", "-dirty", "-update", #endif @@ -1842,7 +1897,8 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp) NULL }; enum dbcuropts { -#if CONFIG_TEST +#ifdef CONFIG_TEST + DBCUR_DEGREE2, DBCUR_DIRTY, DBCUR_UPDATE, #endif @@ -1865,7 +1921,10 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp) } i++; switch ((enum dbcuropts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST + case DBCUR_DEGREE2: + flag |= DB_DEGREE_2; + break; case DBCUR_DIRTY: flag |= DB_DIRTY_READ; break; @@ -1931,6 +1990,31 @@ tcl_DbAssociate(interp, objc, objv, dbp) int i, optindex, result, ret; char *arg, msg[MSG_SIZE]; u_int32_t flag; +#ifdef CONFIG_TEST + /* + * When calling DB->associate over RPC, the Tcl API uses + * special flags that the RPC server interprets to set the + * callback correctly. + */ + const char *cbname; + struct { + const char *name; + u_int32_t flag; + } *cb, callbacks[] = { + { "", 0 }, /* A NULL callback in Tcl. */ + { "_s_reversedata", DB_RPC2ND_REVERSEDATA }, + { "_s_noop", DB_RPC2ND_NOOP }, + { "_s_concatkeydata", DB_RPC2ND_CONCATKEYDATA }, + { "_s_concatdatakey", DB_RPC2ND_CONCATDATAKEY }, + { "_s_reverseconcat", DB_RPC2ND_REVERSECONCAT }, + { "_s_truncdata", DB_RPC2ND_TRUNCDATA }, + { "_s_reversedata", DB_RPC2ND_REVERSEDATA }, + { "_s_constant", DB_RPC2ND_CONSTANT }, + { "sj_getzip", DB_RPC2ND_GETZIP }, + { "sj_getname", DB_RPC2ND_GETNAME }, + { NULL, 0 } + }; +#endif txn = NULL; result = TCL_OK; @@ -2003,7 +2087,48 @@ tcl_DbAssociate(interp, objc, objv, dbp) * callbacks. */ sdbip = (DBTCL_INFO *)sdbp->api_internal; + +#ifdef CONFIG_TEST + if (i != objc - 1 && RPC_ON(dbp->dbenv)) { + /* + * The flag values allowed to DB->associate may have changed to + * overlap with the range we've chosen. If this happens, we + * need to reset all of the RPC_2ND_* flags to a new range. + */ + if ((flag & DB_RPC2ND_MASK) != 0) { + snprintf(msg, MSG_SIZE, + "RPC secondary flags overlap -- recalculate!\n"); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + return (TCL_ERROR); + } + + cbname = Tcl_GetStringFromObj(objv[objc - 2], NULL); + for (cb = callbacks; cb->name != NULL; cb++) + if (strcmp(cb->name, cbname) == 0) { + flag |= cb->flag; + break; + } + + if (cb->name == NULL) { + snprintf(msg, MSG_SIZE, + "Associate: unknown callback: %s\n", cbname); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + return (TCL_ERROR); + } + + ret = dbp->associate(dbp, txn, sdbp, NULL, flag); + + /* + * The primary reference isn't set when calling through + * the RPC server, but the Tcl API peeks at it in other + * places (see tcl_DbGet). + */ + if (ret == 0) + sdbp->s_primary = dbp; + } else if (i != objc - 1) { +#else if (i != objc - 1) { +#endif /* * We have 2 args, get the callback. */ @@ -2039,7 +2164,8 @@ tcl_second_call(dbp, pkey, data, skey) DBTCL_INFO *ip; Tcl_Interp *interp; Tcl_Obj *pobj, *dobj, *objv[3]; - int len, result, ret; + size_t len; + int ilen, result, ret; void *retbuf, *databuf; ip = (DBTCL_INFO *)dbp->api_internal; @@ -2050,9 +2176,9 @@ tcl_second_call(dbp, pkey, data, skey) * Create two ByteArray objects, with the contents of the pkey * and data DBTs that are our inputs. */ - pobj = Tcl_NewByteArrayObj(pkey->data, pkey->size); + pobj = Tcl_NewByteArrayObj(pkey->data, (int)pkey->size); Tcl_IncrRefCount(pobj); - dobj = Tcl_NewByteArrayObj(data->data, data->size); + dobj = Tcl_NewByteArrayObj(data->data, (int)data->size); Tcl_IncrRefCount(dobj); objv[1] = pobj; @@ -2069,8 +2195,8 @@ tcl_second_call(dbp, pkey, data, skey) return (EINVAL); } - retbuf = - Tcl_GetByteArrayFromObj(Tcl_GetObjResult(interp), &len); + retbuf = Tcl_GetByteArrayFromObj(Tcl_GetObjResult(interp), &ilen); + len = (size_t)ilen; /* * retbuf is owned by Tcl; copy it into malloc'ed memory. @@ -2108,8 +2234,9 @@ tcl_DbJoin(interp, objc, objv, dbp, dbcp) DBJ_NOSORT }; DBC **listp; + size_t size; u_int32_t flag; - int adj, i, j, optindex, size, result, ret; + int adj, i, j, optindex, result, ret; char *arg, msg[MSG_SIZE]; result = TCL_OK; @@ -2119,9 +2246,7 @@ tcl_DbJoin(interp, objc, objv, dbp, dbcp) return (TCL_ERROR); } - i = 2; - adj = i; - while (i < objc) { + for (adj = i = 2; i < objc; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], dbjopts, "option", TCL_EXACT, &optindex) != TCL_OK) { result = IS_HELP(objv[i]); @@ -2131,7 +2256,6 @@ tcl_DbJoin(interp, objc, objv, dbp, dbcp) Tcl_ResetResult(interp); break; } - i++; switch ((enum dbjopts)optindex) { case DBJ_NOSORT: flag |= DB_JOIN_NOSORT; @@ -2144,7 +2268,7 @@ tcl_DbJoin(interp, objc, objv, dbp, dbcp) /* * Allocate one more for NULL ptr at end of list. */ - size = sizeof(DBC *) * ((objc - adj) + 1); + size = sizeof(DBC *) * (size_t)((objc - adj) + 1); ret = __os_malloc(dbp->dbenv, size, &listp); if (ret != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); @@ -2184,14 +2308,14 @@ tcl_DbGetjoin(interp, objc, objv, dbp) DB *dbp; /* Database pointer */ { static const char *dbgetjopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-nosort", #endif "-txn", NULL }; enum dbgetjopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST DBGETJ_NOSORT, #endif DBGETJ_TXN @@ -2203,12 +2327,14 @@ tcl_DbGetjoin(interp, objc, objv, dbp) DBT key, data; Tcl_Obj **elemv, *retlist; void *ktmp; + size_t size; u_int32_t flag; - int adj, elemc, freekey, i, j, optindex, result, ret, size; + int adj, elemc, freekey, i, j, optindex, result, ret; char *arg, msg[MSG_SIZE]; result = TCL_OK; flag = 0; + ktmp = NULL; freekey = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "{db1 key1} {db2 key2} ..."); @@ -2230,7 +2356,7 @@ tcl_DbGetjoin(interp, objc, objv, dbp) } i++; switch ((enum dbgetjopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBGETJ_NOSORT: flag |= DB_JOIN_NOSORT; adj++; @@ -2256,7 +2382,7 @@ tcl_DbGetjoin(interp, objc, objv, dbp) } if (result != TCL_OK) return (result); - size = sizeof(DBC *) * ((objc - adj) + 1); + size = sizeof(DBC *) * (size_t)((objc - adj) + 1); ret = __os_malloc(NULL, size, &listp); if (ret != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); @@ -2328,19 +2454,19 @@ tcl_DbGetjoin(interp, objc, objv, dbp) result = _SetListElem(interp, retlist, key.data, key.size, data.data, data.size); - (void)__os_ufree(dbp->dbenv, key.data); - (void)__os_ufree(dbp->dbenv, data.data); + __os_ufree(dbp->dbenv, key.data); + __os_ufree(dbp->dbenv, data.data); } } - dbc->c_close(dbc); + (void)dbc->c_close(dbc); if (result == TCL_OK) Tcl_SetObjResult(interp, retlist); out: - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); while (j) { if (listp[j]) - (listp[j])->c_close(listp[j]); + (void)(listp[j])->c_close(listp[j]); j--; } __os_free(dbp->dbenv, listp); @@ -2370,6 +2496,7 @@ tcl_DbGetFlags(interp, objc, objv, dbp) { DB_DUP, "-dup" }, { DB_DUPSORT, "-dupsort" }, { DB_ENCRYPT, "-encrypt" }, + { DB_INORDER, "-inorder" }, { DB_TXN_NOT_DURABLE, "-notdurable" }, { DB_RECNUM, "-recnum" }, { DB_RENUMBER, "-renumber" }, @@ -2384,18 +2511,19 @@ tcl_DbGetFlags(interp, objc, objv, dbp) } ret = dbp->get_flags(dbp, &flags); - if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "db get_flags")) == TCL_OK) { + if ((result = _ReturnSetup( + interp, ret, DB_RETOK_STD(ret), "db get_flags")) == TCL_OK) { buf[0] = '\0'; for (i = 0; db_flags[i].flag != 0; i++) if (LF_ISSET(db_flags[i].flag)) { if (strlen(buf) > 0) - strncat(buf, " ", sizeof(buf)); - strncat(buf, db_flags[i].arg, sizeof(buf)); + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, db_flags[i].arg, sizeof(buf)); } - res = Tcl_NewStringObj(buf, strlen(buf)); + res = NewStringObj(buf, strlen(buf)); Tcl_SetObjResult(interp, res); } @@ -2423,6 +2551,7 @@ tcl_DbGetOpenFlags(interp, objc, objv, dbp) } open_flags[] = { { DB_AUTO_COMMIT, "-auto_commit" }, { DB_CREATE, "-create" }, + { DB_DEGREE_2, "-degree_2" }, { DB_DIRTY_READ, "-dirty" }, { DB_EXCL, "-excl" }, { DB_NOMMAP, "-nommap" }, @@ -2438,18 +2567,19 @@ tcl_DbGetOpenFlags(interp, objc, objv, dbp) } ret = dbp->get_open_flags(dbp, &flags); - if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "db get_open_flags")) == TCL_OK) { + if ((result = _ReturnSetup( + interp, ret, DB_RETOK_STD(ret), "db get_open_flags")) == TCL_OK) { buf[0] = '\0'; for (i = 0; open_flags[i].flag != 0; i++) if (LF_ISSET(open_flags[i].flag)) { if (strlen(buf) > 0) - strncat(buf, " ", sizeof(buf)); - strncat(buf, open_flags[i].arg, sizeof(buf)); + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, open_flags[i].arg, sizeof(buf)); } - res = Tcl_NewStringObj(buf, strlen(buf)); + res = NewStringObj(buf, strlen(buf)); Tcl_SetObjResult(interp, res); } @@ -2476,6 +2606,7 @@ tcl_DbCount(interp, objc, objv, dbp) res = NULL; count = 0; freekey = ret = 0; + ktmp = NULL; result = TCL_OK; if (objc != 3) { @@ -2535,14 +2666,14 @@ tcl_DbCount(interp, objc, objv, dbp) } res = Tcl_NewWideIntObj((Tcl_WideInt)count); Tcl_SetObjResult(interp, res); -out: - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + +out: if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); (void)dbc->c_close(dbc); return (result); } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_DbKeyRange -- */ @@ -2571,17 +2702,17 @@ tcl_DbKeyRange(interp, objc, objv, dbp) int freekey, i, myobjc, optindex, result, ret; char *arg, msg[MSG_SIZE]; - result = TCL_OK; + ktmp = NULL; flag = 0; freekey = 0; + result = TCL_OK; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "?-txn id? key"); return (TCL_ERROR); } txn = NULL; - i = 2; - while (i < objc) { + for (i = 2; i < objc;) { if (Tcl_GetIndexFromObj(interp, objv[i], dbkeyropts, "option", TCL_EXACT, &optindex) != TCL_OK) { result = IS_HELP(objv[i]); @@ -2656,9 +2787,9 @@ tcl_DbKeyRange(interp, objc, objv, dbp) retlist = Tcl_NewListObj(myobjc, myobjv); if (result == TCL_OK) Tcl_SetObjResult(interp, retlist); -out: - if (freekey) - (void)__os_free(dbp->dbenv, ktmp); + +out: if (ktmp != NULL && freekey) + __os_free(dbp->dbenv, ktmp); return (result); } #endif diff --git a/db/tcl/tcl_db_pkg.c b/db/tcl/tcl_db_pkg.c index 260dfb232..3baeeb9a6 100644 --- a/db/tcl/tcl_db_pkg.c +++ b/db/tcl/tcl_db_pkg.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_db_pkg.c,v 11.188 2004/10/12 23:54:14 ubell Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_db_pkg.c,v 11.164 2003/11/14 18:45:11 sue Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -19,7 +17,7 @@ static const char revid[] = "$Id: tcl_db_pkg.c,v 11.164 2003/11/14 18:45:11 sue #include <tcl.h> #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST #define DB_DBM_HSEARCH 1 #endif @@ -43,11 +41,14 @@ static int bdb_DbOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, static int bdb_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); static int bdb_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); static int bdb_Version __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); +static int bdb_SeqOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, + DBTCL_INFO *, DB_SEQUENCE **)); -#if CONFIG_TEST +#ifdef CONFIG_TEST static int bdb_DbUpgrade __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); static int bdb_DbVerify __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); static int bdb_Handles __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); +static int bdb_MsgType __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); static int tcl_bt_compare __P((DB *, const DBT *, const DBT *)); static int tcl_compare_callback __P((DB *, const DBT *, const DBT *, @@ -82,17 +83,19 @@ Db_tcl_Init(interp) if (code != TCL_OK) return (code); - Tcl_CreateObjCommand(interp, "berkdb", (Tcl_ObjCmdProc *)berkdb_Cmd, - (ClientData)0, NULL); + (void)Tcl_CreateObjCommand(interp, + "berkdb", (Tcl_ObjCmdProc *)berkdb_Cmd, (ClientData)0, NULL); /* * Create shared global debugging variables */ - Tcl_LinkVar(interp, "__debug_on", (char *)&__debug_on, TCL_LINK_INT); - Tcl_LinkVar(interp, "__debug_print", (char *)&__debug_print, - TCL_LINK_INT); - Tcl_LinkVar(interp, "__debug_stop", (char *)&__debug_stop, - TCL_LINK_INT); - Tcl_LinkVar(interp, "__debug_test", (char *)&__debug_test, + (void)Tcl_LinkVar( + interp, "__debug_on", (char *)&__debug_on, TCL_LINK_INT); + (void)Tcl_LinkVar( + interp, "__debug_print", (char *)&__debug_print, TCL_LINK_INT); + (void)Tcl_LinkVar( + interp, "__debug_stop", (char *)&__debug_stop, TCL_LINK_INT); + (void)Tcl_LinkVar( + interp, "__debug_test", (char *)&__debug_test, TCL_LINK_INT); LIST_INIT(&__db_infohead); return (TCL_OK); @@ -119,9 +122,10 @@ berkdb_Cmd(notused, interp, objc, objv) Tcl_Obj *CONST objv[]; /* The argument objects */ { static const char *berkdbcmds[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "dbverify", "handles", + "msgtype", "upgrade", #endif "dbremove", @@ -129,8 +133,11 @@ berkdb_Cmd(notused, interp, objc, objv) "env", "envremove", "open", +#ifdef HAVE_SEQUENCE + "sequence", +#endif "version", -#if CONFIG_TEST +#ifdef CONFIG_TEST /* All below are compatibility functions */ "hcreate", "hsearch", "hdestroy", "dbminit", "fetch", "store", @@ -146,9 +153,10 @@ berkdb_Cmd(notused, interp, objc, objv) * All commands enums below ending in X are compatibility */ enum berkdbcmds { -#if CONFIG_TEST +#ifdef CONFIG_TEST BDB_DBVERIFY, BDB_HANDLES, + BDB_MSGTYPE, BDB_UPGRADE, #endif BDB_DBREMOVE, @@ -156,8 +164,11 @@ berkdb_Cmd(notused, interp, objc, objv) BDB_ENV, BDB_ENVREMOVE, BDB_OPEN, +#ifdef HAVE_SEQUENCE + BDB_SEQUENCE, +#endif BDB_VERSION, -#if CONFIG_TEST +#ifdef CONFIG_TEST BDB_HCREATEX, BDB_HSEARCHX, BDB_HDESTROYX, BDB_DBMINITX, BDB_FETCHX, BDB_STOREX, BDB_DELETEX, BDB_FIRSTKEYX, BDB_NEXTKEYX, @@ -168,9 +179,15 @@ berkdb_Cmd(notused, interp, objc, objv) }; static int env_id = 0; static int db_id = 0; +#ifdef HAVE_SEQUENCE + static int seq_id = 0; +#endif DB *dbp; -#if CONFIG_TEST +#ifdef HAVE_SEQUENCE + DB_SEQUENCE *seq; +#endif +#ifdef CONFIG_TEST DBM *ndbmp; static int ndbm_id = 0; #endif @@ -199,13 +216,16 @@ berkdb_Cmd(notused, interp, objc, objv) return (IS_HELP(objv[1])); res = NULL; switch ((enum berkdbcmds)cmdindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case BDB_DBVERIFY: result = bdb_DbVerify(interp, objc, objv); break; case BDB_HANDLES: result = bdb_Handles(interp, objc, objv); break; + case BDB_MSGTYPE: + result = bdb_MsgType(interp, objc, objv); + break; case BDB_UPGRADE: result = bdb_DbUpgrade(interp, objc, objv); break; @@ -221,12 +241,11 @@ berkdb_Cmd(notused, interp, objc, objv) result = bdb_EnvOpen(interp, objc, objv, ip, &envp); if (result == TCL_OK && envp != NULL) { env_id++; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)env_Cmd, (ClientData)envp, NULL); /* Use ip->i_name - newname is overwritten */ - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(ip, envp); } else _DeleteInfo(ip); @@ -252,12 +271,11 @@ berkdb_Cmd(notused, interp, objc, objv) result = bdb_DbOpen(interp, objc, objv, ip, &dbp); if (result == TCL_OK && dbp != NULL) { db_id++; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)db_Cmd, (ClientData)dbp, NULL); /* Use ip->i_name - newname is overwritten */ - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(ip, dbp); } else _DeleteInfo(ip); @@ -267,7 +285,30 @@ berkdb_Cmd(notused, interp, objc, objv) result = TCL_ERROR; } break; -#if CONFIG_TEST +#ifdef HAVE_SEQUENCE + case BDB_SEQUENCE: + snprintf(newname, sizeof(newname), "seq%d", seq_id); + ip = _NewInfo(interp, NULL, newname, I_SEQ); + if (ip != NULL) { + result = bdb_SeqOpen(interp, objc, objv, ip, &seq); + if (result == TCL_OK && seq != NULL) { + seq_id++; + (void)Tcl_CreateObjCommand(interp, newname, + (Tcl_ObjCmdProc *)seq_Cmd, + (ClientData)seq, NULL); + /* Use ip->i_name - newname is overwritten */ + res = NewStringObj(newname, strlen(newname)); + _SetInfoData(ip, seq); + } else + _DeleteInfo(ip); + } else { + Tcl_SetResult(interp, "Could not set up info", + TCL_STATIC); + result = TCL_ERROR; + } + break; +#endif +#ifdef CONFIG_TEST case BDB_HCREATEX: case BDB_HSEARCHX: case BDB_HDESTROYX: @@ -289,12 +330,11 @@ berkdb_Cmd(notused, interp, objc, objv) result = bdb_NdbmOpen(interp, objc, objv, &ndbmp); if (result == TCL_OK) { ndbm_id++; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)ndbm_Cmd, (ClientData)ndbmp, NULL); /* Use ip->i_name - newname is overwritten */ - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(ip, ndbmp); } else _DeleteInfo(ip); @@ -345,7 +385,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) DB_ENV **env; /* Environment pointer */ { static const char *envopen[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-alloc", "-auto_commit", "-cdb", @@ -361,20 +401,22 @@ bdb_EnvOpen(interp, objc, objv, ip, env) "-lock_timeout", "-log", "-log_buffer", + "-log_inmemory", "-log_max", "-log_regionmax", "-log_remove", - "-mmapsize", - "-nommap", - "-notdurable", + "-mpool_max_openfd", + "-mpool_max_write", + "-mpool_mmap_size", + "-mpool_nommap", "-overwrite", "-region_init", "-rep_client", - "-rep_logsonly", "-rep_master", "-rep_transport", "-server", "-server_timeout", + "-set_intermediate_dir", "-thread", "-time_notgranted", "-txn_timeout", @@ -410,7 +452,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) * which is close to but not quite alphabetical. */ enum envopen { -#if CONFIG_TEST +#ifdef CONFIG_TEST ENV_ALLOC, ENV_AUTO_COMMIT, ENV_CDB, @@ -426,20 +468,22 @@ bdb_EnvOpen(interp, objc, objv, ip, env) ENV_LOCK_TIMEOUT, ENV_LOG, ENV_LOG_BUFFER, + ENV_LOG_INMEMORY, ENV_LOG_MAX, ENV_LOG_REGIONMAX, ENV_LOG_REMOVE, - ENV_MMAPSIZE, - ENV_NOMMAP, - ENV_NOTDURABLE, + ENV_MPOOL_MAX_OPENFD, + ENV_MPOOL_MAX_WRITE, + ENV_MPOOL_MMAP_SIZE, + ENV_MPOOL_NOMMAP, ENV_OVERWRITE, ENV_REGION_INIT, ENV_REP_CLIENT, - ENV_REP_LOGSONLY, ENV_REP_MASTER, ENV_REP_TRANSPORT, ENV_SERVER, ENV_SERVER_TO, + ENV_SET_INTERMEDIATE_DIR, ENV_THREAD, ENV_TIME_NOTGRANTED, ENV_TXN_TIMEOUT, @@ -469,17 +513,18 @@ bdb_EnvOpen(interp, objc, objv, ip, env) ENV_USE_ENVIRON_ROOT }; Tcl_Obj **myobjv; - u_int32_t cr_flags, gbytes, bytes, ncaches, logbufset, logmaxset; + u_int32_t cr_flags, gbytes, bytes, logbufset, logmaxset; u_int32_t open_flags, rep_flags, set_flags, uintarg; - int i, mode, myobjc, optindex, result, ret; + int i, mode, myobjc, ncaches, optindex, result, ret; long client_to, server_to, shm; char *arg, *home, *passwd, *server; -#if CONFIG_TEST +#ifdef CONFIG_TEST Tcl_Obj **myobjv1; time_t timestamp; - u_int32_t detect, size; + long v; + u_int32_t detect; u_int8_t *conflicts; - int intarg, j, nmodes, temp; + int intarg, intarg2, j, nmodes, temp; #endif result = TCL_OK; @@ -521,8 +566,8 @@ bdb_EnvOpen(interp, objc, objv, ip, env) Tcl_ResetResult(interp); continue; } +#ifdef CONFIG_TEST switch ((enum envopen)optindex) { -#if CONFIG_TEST case ENV_SERVER: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -555,10 +600,10 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = Tcl_GetLongFromObj(interp, objv[i++], &client_to); break; -#endif default: break; } +#endif } if (result != TCL_OK) return (TCL_ERROR); @@ -604,7 +649,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) } i++; switch ((enum envopen)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case ENV_SERVER: case ENV_SERVER_TO: case ENV_CLIENT_TO: @@ -667,8 +712,9 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = TCL_ERROR; break; } - size = sizeof(u_int8_t) * nmodes*nmodes; - ret = __os_malloc(*env, size, &conflicts); + + ret = __os_malloc(*env, sizeof(u_int8_t) * + (size_t)nmodes * (size_t)nmodes, &conflicts); if (ret != 0) { result = TCL_ERROR; break; @@ -703,6 +749,8 @@ bdb_EnvOpen(interp, objc, objv, ip, env) detect = DB_LOCK_EXPIRE; else if (strcmp(arg, "maxlocks") == 0) detect = DB_LOCK_MAXLOCKS; + else if (strcmp(arg, "maxwrites") == 0) + detect = DB_LOCK_MAXWRITE; else if (strcmp(arg, "minlocks") == 0) detect = DB_LOCK_MINLOCKS; else if (strcmp(arg, "minwrites") == 0) @@ -770,22 +818,23 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = TCL_ERROR; break; } - result = Tcl_GetLongFromObj(interp, objv[i++], - (long *)×tamp); - if (result == TCL_OK) { - _debug_check(); - if (optindex == ENV_TXN_TIME) - ret = (*env)-> - set_tx_timestamp(*env, ×tamp); - else - ret = (*env)->set_timeout(*env, - (db_timeout_t)timestamp, - optindex == ENV_TXN_TIMEOUT ? - DB_SET_TXN_TIMEOUT : - DB_SET_LOCK_TIMEOUT); - result = _ReturnSetup(interp, ret, - DB_RETOK_STD(ret), "txn_timestamp"); - } + + if ((result = Tcl_GetLongFromObj( + interp, objv[i++], &v)) != TCL_OK) + break; + timestamp = (time_t)v; + + _debug_check(); + if ((enum envopen)optindex == ENV_TXN_TIME) + ret = + (*env)->set_tx_timestamp(*env, ×tamp); + else + ret = (*env)->set_timeout(*env, + (db_timeout_t)timestamp, + (enum envopen)optindex == ENV_TXN_TIMEOUT ? + DB_SET_TXN_TIMEOUT : DB_SET_LOCK_TIMEOUT); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "txn_timestamp"); break; case ENV_LOG: FLD_SET(open_flags, DB_INIT_LOG | DB_INIT_MPOOL); @@ -816,6 +865,9 @@ bdb_EnvOpen(interp, objc, objv, ip, env) } } break; + case ENV_LOG_INMEMORY: + FLD_SET(set_flags, DB_LOG_INMEMORY); + break; case ENV_LOG_MAX: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -852,10 +904,49 @@ bdb_EnvOpen(interp, objc, objv, ip, env) case ENV_LOG_REMOVE: FLD_SET(set_flags, DB_LOG_AUTOREMOVE); break; - case ENV_MMAPSIZE: + case ENV_MPOOL_MAX_OPENFD: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-mpool_max_openfd fd_count?"); + result = TCL_ERROR; + break; + } + result = Tcl_GetIntFromObj(interp, objv[i++], &intarg); + if (result == TCL_OK) { + _debug_check(); + ret = (*env)->set_mp_max_openfd(*env, intarg); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "mpool_max_openfd"); + } + break; + case ENV_MPOOL_MAX_WRITE: + result = Tcl_ListObjGetElements(interp, objv[i], + &myobjc, &myobjv); + if (result == TCL_OK) + i++; + else + break; + if (myobjc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-mpool_max_write {nwrite nsleep}?"); + result = TCL_ERROR; + break; + } + result = Tcl_GetIntFromObj(interp, myobjv[0], &intarg); + if (result != TCL_OK) + break; + result = Tcl_GetIntFromObj(interp, myobjv[1], &intarg2); + if (result != TCL_OK) + break; + _debug_check(); + ret = (*env)->set_mp_max_write(*env, intarg, intarg2); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "set_mp_max_write"); + break; + case ENV_MPOOL_MMAP_SIZE: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, - "?-mmapsize size?"); + "?-mpool_mmap_size size?"); result = TCL_ERROR; break; } @@ -865,10 +956,10 @@ bdb_EnvOpen(interp, objc, objv, ip, env) ret = (*env)->set_mp_mmapsize(*env, (size_t)intarg); result = _ReturnSetup(interp, ret, - DB_RETOK_STD(ret), "mmapsize"); + DB_RETOK_STD(ret), "mpool_mmap_size"); } break; - case ENV_NOMMAP: + case ENV_MPOOL_NOMMAP: FLD_SET(set_flags, DB_NOMMAP); break; case ENV_OVERWRITE: @@ -880,14 +971,26 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "region_init"); break; + case ENV_SET_INTERMEDIATE_DIR: + if (i >= objc) { + Tcl_WrongNumArgs(interp, + 2, objv, "?-set_intermediate_dir mode?"); + result = TCL_ERROR; + break; + } + result = Tcl_GetIntFromObj(interp, objv[i++], &intarg); + if (result == TCL_OK) { + _debug_check(); + ret = (*env)-> + set_intermediate_dir(*env, intarg, 0); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "set_intermediate_dir"); + } + break; case ENV_REP_CLIENT: rep_flags = DB_REP_CLIENT; FLD_SET(open_flags, DB_INIT_REP); break; - case ENV_REP_LOGSONLY: - rep_flags = DB_REP_LOGSONLY; - FLD_SET(open_flags, DB_INIT_REP); - break; case ENV_REP_MASTER: rep_flags = DB_REP_MASTER; FLD_SET(open_flags, DB_INIT_REP); @@ -966,9 +1069,6 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = tcl_EnvVerbose(interp, *env, myobjv[0], myobjv[1]); break; - case ENV_NOTDURABLE: - FLD_SET(set_flags, DB_TXN_NOT_DURABLE); - break; case ENV_WRNOSYNC: FLD_SET(set_flags, DB_TXN_WRITE_NOSYNC); break; @@ -1081,7 +1181,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) result = _GetUInt32(interp, myobjv[1], &bytes); if (result != TCL_OK) break; - result = _GetUInt32(interp, myobjv[2], &ncaches); + result = Tcl_GetIntFromObj(interp, myobjv[2], &ncaches); if (result != TCL_OK) break; _debug_check(); @@ -1128,23 +1228,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) break; } arg = Tcl_GetStringFromObj(objv[i++], NULL); - /* - * If the user already set one, close it. - */ - if (ip->i_err != NULL && - ip->i_err != stdout && ip->i_err != stderr) - fclose(ip->i_err); - - if (strcmp(arg, "/dev/stdout") == 0) - ip->i_err = stdout; - else if (strcmp(arg, "/dev/stderr") == 0) - ip->i_err = stderr; - else - ip->i_err = fopen(arg, "a"); - if (ip->i_err != NULL) { - _debug_check(); - (*env)->set_errfile(*env, ip->i_err); - } + tcl_EnvSetErrfile(interp, *env, ip, arg); break; case ENV_ERRPFX: if (i >= objc) { @@ -1154,21 +1238,8 @@ bdb_EnvOpen(interp, objc, objv, ip, env) break; } arg = Tcl_GetStringFromObj(objv[i++], NULL); - /* - * If the user already set one, free it. - */ - if (ip->i_errpfx != NULL) - __os_free(NULL, ip->i_errpfx); - if ((ret = - __os_strdup(*env, arg, &ip->i_errpfx)) != 0) { - result = _ReturnSetup(interp, ret, - DB_RETOK_STD(ret), "__os_strdup"); - break; - } - if (ip->i_errpfx != NULL) { - _debug_check(); - (*env)->set_errpfx(*env, ip->i_errpfx); - } + _debug_check(); + result = tcl_EnvSetErrpfx(interp, *env, ip, arg); break; case ENV_DATA_DIR: if (i >= objc) { @@ -1268,7 +1339,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env) error: if (result == TCL_ERROR) { if (ip->i_err && ip->i_err != stdout && ip->i_err != stderr) { - fclose(ip->i_err); + (void)fclose(ip->i_err); ip->i_err = NULL; } (void)(*env)->close(*env, 0); @@ -1305,7 +1376,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) TCL_DB_ENV0 }; static const char *bdbopen[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-btcompare", "-dirty", "-dupcompare", @@ -1336,6 +1407,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) "-extent", "-ffactor", "-hash", + "-inorder", "-len", "-maxsize", "-mode", @@ -1356,7 +1428,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) NULL }; enum bdbopen { -#if CONFIG_TEST +#ifdef CONFIG_TEST TCL_DB_BTCOMPARE, TCL_DB_DIRTY, TCL_DB_DUPCOMPARE, @@ -1387,6 +1459,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) TCL_DB_EXTENT, TCL_DB_FFACTOR, TCL_DB_HASH, + TCL_DB_INORDER, TCL_DB_LEN, TCL_DB_MAXSIZE, TCL_DB_MODE, @@ -1411,9 +1484,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) DBTYPE type; DB_ENV *envp; Tcl_Obj **myobjv; - u_int32_t gbytes, bytes, ncaches, open_flags, uintarg; - int endarg, i, intarg, mode, myobjc; - int optindex, result, ret, set_err, set_flags, set_pfx, subdblen; + u_int32_t gbytes, bytes, open_flags, set_flags, uintarg; + int endarg, i, intarg, lorder, mode, myobjc, ncaches; + int optindex, result, ret, set_err, set_pfx, subdblen; u_char *subdbtmp; char *arg, *db, *passwd, *subdb, msg[MSG_SIZE]; @@ -1528,7 +1601,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) } i++; switch ((enum bdbopen)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case TCL_DB_BTCOMPARE: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -1599,10 +1672,10 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) result = TCL_ERROR; break; } - result = _GetUInt32(interp, objv[i++], &uintarg); + result = Tcl_GetIntFromObj(interp, objv[i++], &lorder); if (result == TCL_OK) { _debug_check(); - ret = (*dbp)->set_lorder(*dbp, uintarg); + ret = (*dbp)->set_lorder(*dbp, lorder); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "set_lorder"); } @@ -1632,7 +1705,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) set_flags |= DB_REVSPLITOFF; break; case TCL_DB_TEST: - (*dbp)->set_h_hash(*dbp, __ham_test); + ret = (*dbp)->set_h_hash(*dbp, __ham_test); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "set_h_hash"); break; case TCL_DB_THREAD: /* Enable DB_THREAD when specified in testing. */ @@ -1658,7 +1733,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) txn = NAME_TO_TXN(arg); if (txn == NULL) { snprintf(msg, MSG_SIZE, - "Put: Invalid txn: %s\n", arg); + "Open: Invalid txn: %s\n", arg); Tcl_SetResult(interp, msg, TCL_VOLATILE); result = TCL_ERROR; } @@ -1740,6 +1815,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) case TCL_DB_DUPSORT: set_flags |= DB_DUPSORT; break; + case TCL_DB_INORDER: + set_flags |= DB_INORDER; + break; case TCL_DB_RECNUM: set_flags |= DB_RECNUM; break; @@ -1919,7 +1997,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) result = _GetUInt32(interp, myobjv[1], &bytes); if (result != TCL_OK) break; - result = _GetUInt32(interp, myobjv[2], &ncaches); + result = Tcl_GetIntFromObj(interp, myobjv[2], &ncaches); if (result != TCL_OK) break; _debug_check(); @@ -1957,7 +2035,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) */ if (errip->i_err != NULL && errip->i_err != stdout && errip->i_err != stderr) - fclose(errip->i_err); + (void)fclose(errip->i_err); if (strcmp(arg, "/dev/stdout") == 0) errip->i_err = stdout; else if (strcmp(arg, "/dev/stderr") == 0) @@ -2028,12 +2106,12 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &subdblen); if ((ret = __os_malloc(envp, - subdblen + 1, &subdb)) != 0) { + (size_t)subdblen + 1, &subdb)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(subdb, subdbtmp, subdblen); + memcpy(subdb, subdbtmp, (size_t)subdblen); subdb[subdblen] = '\0'; } } @@ -2079,7 +2157,7 @@ error: */ if (set_err && errip && errip->i_err != NULL && errip->i_err != stdout && errip->i_err != stderr) { - fclose(errip->i_err); + (void)fclose(errip->i_err); errip->i_err = NULL; } if (set_pfx && errip && errip->i_errpfx != NULL) { @@ -2091,6 +2169,245 @@ error: return (result); } +#ifdef HAVE_SEQUENCE +/* + * bdb_SeqOpen -- + * Implements the "Seq_create/Seq_open" command. + */ +static int +bdb_SeqOpen(interp, objc, objv, ip, seqp) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DBTCL_INFO *ip; /* Our internal info */ + DB_SEQUENCE **seqp; /* DB_SEQUENCE handle */ +{ + static const char *seqopen[] = { + "-auto_commit", + "-cachesize", + "-create", + "-inc", + "-init", + "-dec", + "-max", + "-min", + "-txn", + "-wrap", + "--", + NULL + } ; + enum seqopen { + TCL_SEQ_AUTO_COMMIT, + TCL_SEQ_CACHESIZE, + TCL_SEQ_CREATE, + TCL_SEQ_INC, + TCL_SEQ_INIT, + TCL_SEQ_DEC, + TCL_SEQ_MAX, + TCL_SEQ_MIN, + TCL_SEQ_TXN, + TCL_SEQ_WRAP, + TCL_SEQ_ENDARG + }; + DB *dbp; + DBT key; + DBTYPE type; + DB_TXN *txn; + db_recno_t recno; + db_seq_t min, max, value; + u_int32_t flags, oflags; + int cache, endarg, i, optindex, result, ret, setrange, setvalue, v; + char *arg, *db, msg[MSG_SIZE]; + + COMPQUIET(ip, NULL); + COMPQUIET(value, 0); + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?args?"); + return (TCL_ERROR); + } + + txn = NULL; + endarg = 0; + flags = oflags = 0; + setrange = setvalue = 0; + min = INT64_MIN; + max = INT64_MAX; + cache = 0; + + for (i = 2; i < objc;) { + Tcl_ResetResult(interp); + if (Tcl_GetIndexFromObj(interp, objv[i], seqopen, "option", + TCL_EXACT, &optindex) != TCL_OK) { + arg = Tcl_GetStringFromObj(objv[i], NULL); + if (arg[0] == '-') { + result = IS_HELP(objv[i]); + goto error; + } else + Tcl_ResetResult(interp); + break; + } + i++; + result = TCL_OK; + switch ((enum seqopen)optindex) { + case TCL_SEQ_AUTO_COMMIT: + oflags |= DB_AUTO_COMMIT; + break; + case TCL_SEQ_CREATE: + oflags |= DB_CREATE; + break; + case TCL_SEQ_INC: + LF_SET(DB_SEQ_INC); + break; + case TCL_SEQ_CACHESIZE: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-cachesize value?"); + result = TCL_ERROR; + break; + } + result = Tcl_GetIntFromObj(interp, objv[i++], &cache); + break; + case TCL_SEQ_INIT: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-init value?"); + result = TCL_ERROR; + break; + } + result = + Tcl_GetWideIntFromObj(interp, objv[i++], &value); + setvalue = 1; + break; + case TCL_SEQ_DEC: + LF_SET(DB_SEQ_DEC); + break; + case TCL_SEQ_MAX: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-max value?"); + result = TCL_ERROR; + break; + } + if ((result = + Tcl_GetWideIntFromObj(interp, + objv[i++], &max)) != TCL_OK) + goto error; + setrange = 1; + break; + case TCL_SEQ_MIN: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-min value?"); + result = TCL_ERROR; + break; + } + if ((result = + Tcl_GetWideIntFromObj(interp, + objv[i++], &min)) != TCL_OK) + goto error; + setrange = 1; + break; + case TCL_SEQ_TXN: + if (i > (objc - 1)) { + Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?"); + result = TCL_ERROR; + break; + } + arg = Tcl_GetStringFromObj(objv[i++], NULL); + txn = NAME_TO_TXN(arg); + if (txn == NULL) { + snprintf(msg, MSG_SIZE, + "Sequence: Invalid txn: %s\n", arg); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + result = TCL_ERROR; + } + break; + case TCL_SEQ_WRAP: + LF_SET(DB_SEQ_WRAP); + break; + case TCL_SEQ_ENDARG: + endarg = 1; + break; + } + /* + * If, at any time, parsing the args we get an error, + * bail out and return. + */ + if (result != TCL_OK) + goto error; + if (endarg) + break; + } + + if (objc - i != 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?args?"); + return (TCL_ERROR); + } + /* + * The db must be a string but the sequence key may + * be anything. + */ + db = Tcl_GetStringFromObj(objv[i++], NULL); + if ((dbp = NAME_TO_DB(db)) == NULL) { + Tcl_SetResult(interp, "No such dbp", TCL_STATIC); + return (TCL_ERROR); + } + (void)dbp->get_type(dbp, &type); + + memset(&key, 0, sizeof(key)); + if (type == DB_QUEUE || type == DB_RECNO) { + result = _GetUInt32(interp, objv[i++], &recno); + if (result != TCL_OK) + return (result); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = Tcl_GetByteArrayFromObj(objv[i++], &v); + key.size = (u_int32_t)v; + } + ret = db_sequence_create(seqp, dbp, 0); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence create")) != TCL_OK) { + *seqp = NULL; + return (result); + } + + ret = (*seqp)->set_flags(*seqp, flags); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence set_flags")) != TCL_OK) + goto error; + if (setrange) { + ret = (*seqp)->set_range(*seqp, min, max); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence set_range")) != TCL_OK) + goto error; + } + if (cache) { + ret = (*seqp)->set_cachesize(*seqp, cache); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence cachesize")) != TCL_OK) + goto error; + } + if (setvalue) { + ret = (*seqp)->initial_value(*seqp, value); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence init")) != TCL_OK) + goto error; + } + ret = (*seqp)->open(*seqp, txn, &key, oflags); + if ((result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "sequence open")) != TCL_OK) + goto error; + + if (0) { +error: (void) (*seqp)->close(*seqp, 0); + *seqp = NULL; + } + return (result); +} +#endif + /* * bdb_DbRemove -- * Implements the DB_ENV->remove and DB->remove command. @@ -2245,12 +2562,12 @@ bdb_DbRemove(interp, objc, objv) if (i != objc) { subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &subdblen); - if ((ret = __os_malloc(envp, subdblen + 1, + if ((ret = __os_malloc(envp, (size_t)subdblen + 1, &subdb)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(subdb, subdbtmp, subdblen); + memcpy(subdb, subdbtmp, (size_t)subdblen); subdb[subdblen] = '\0'; } } else { @@ -2452,24 +2769,24 @@ bdb_DbRename(interp, objc, objv) if (i == objc - 2) { subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &subdblen); - if ((ret = __os_malloc(envp, subdblen + 1, + if ((ret = __os_malloc(envp, (size_t)subdblen + 1, &subdb)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(subdb, subdbtmp, subdblen); + memcpy(subdb, subdbtmp, (size_t)subdblen); subdb[subdblen] = '\0'; } subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &newlen); - if ((ret = __os_malloc(envp, newlen + 1, + if ((ret = __os_malloc(envp, (size_t)newlen + 1, &newname)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(newname, subdbtmp, newlen); + memcpy(newname, subdbtmp, (size_t)newlen); newname[newlen] = '\0'; } else { Tcl_WrongNumArgs( @@ -2516,7 +2833,7 @@ error: return (result); } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * bdb_DbVerify -- * Implements the DB->verify command. @@ -2534,6 +2851,7 @@ bdb_DbVerify(interp, objc, objv) "-env", "-errfile", "-errpfx", + "-unref", "--", NULL }; @@ -2544,6 +2862,7 @@ bdb_DbVerify(interp, objc, objv) TCL_DBVRFY_ENV, TCL_DBVRFY_ERRFILE, TCL_DBVRFY_ERRPFX, + TCL_DBVRFY_UNREF, TCL_DBVRFY_ENDARG }; DB_ENV *envp; @@ -2634,7 +2953,7 @@ bdb_DbVerify(interp, objc, objv) * If the user already set one, close it. */ if (errf != NULL && errf != stdout && errf != stderr) - fclose(errf); + (void)fclose(errf); if (strcmp(arg, "/dev/stdout") == 0) errf = stdout; else if (strcmp(arg, "/dev/stderr") == 0) @@ -2661,6 +2980,9 @@ bdb_DbVerify(interp, objc, objv) break; } break; + case TCL_DBVRFY_UNREF: + flags |= DB_UNREF; + break; case TCL_DBVRFY_ENDARG: endarg = 1; break; @@ -2717,7 +3039,7 @@ bdb_DbVerify(interp, objc, objv) dbp = NULL; error: if (errf != NULL && errf != stdout && errf != stderr) - fclose(errf); + (void)fclose(errf); if (errpfx != NULL) __os_free(envp, errpfx); if (dbp) @@ -2788,7 +3110,7 @@ bdb_Version(interp, objc, objv) v = db_version(&maj, &min, &patch); if (string) - res = Tcl_NewStringObj(v, strlen(v)); + res = NewStringObj(v, strlen(v)); else { verobjc = 3; verobjv[0] = Tcl_NewIntObj(maj); @@ -2801,7 +3123,7 @@ error: return (result); } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * bdb_Handles -- * Implements the handles command. @@ -2826,7 +3148,7 @@ bdb_Handles(interp, objc, objv) for (p = LIST_FIRST(&__db_infohead); p != NULL; p = LIST_NEXT(p, entries)) { - handle = Tcl_NewStringObj(p->i_name, strlen(p->i_name)); + handle = NewStringObj(p->i_name, strlen(p->i_name)); if (Tcl_ListObjAppendElement(interp, res, handle) != TCL_OK) return (TCL_ERROR); } @@ -2835,6 +3157,58 @@ bdb_Handles(interp, objc, objv) } /* + * bdb_MsgType - + * Implements the msgtype command. + * Given a replication message return its message type name. + */ +static int +bdb_MsgType(interp, objc, objv) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ +{ + REP_CONTROL *rp; + Tcl_Obj *msgname; + u_int32_t len, msgtype; + int freerp, ret; + + /* + * If the messages in rep.h change, this must change too! + * Add "no_type" for 0 so that we directly index. + */ + static const char *msgnames[] = { + "no_type", "alive", "alive_req", "all_req", + "dupmaster", "file", "file_fail", "file_req", "log", + "log_more", "log_req", "master_req", "newclient", + "newfile", "newmaster", "newsite", "page", + "page_fail", "page_req", "update", "update_req", + "verify", "verify_fail", "verify_req", + "vote1", "vote2", NULL + }; + + /* + * 1 arg, the message. Error if different. + */ + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, "msgtype msg"); + return (TCL_ERROR); + } + + ret = _CopyObjBytes(interp, objv[2], (void **)&rp, &len, &freerp); + if (ret != TCL_OK) { + Tcl_SetResult(interp, + "msgtype: bad control message", TCL_STATIC); + return (TCL_ERROR); + } + msgtype = rp->rectype; + msgname = NewStringObj(msgnames[msgtype], strlen(msgnames[msgtype])); + Tcl_SetObjResult(interp, msgname); + if (rp != NULL && freerp) + __os_free(NULL, rp); + return (TCL_OK); +} + +/* * bdb_DbUpgrade -- * Implements the DB->upgrade command. */ @@ -2988,9 +3362,9 @@ tcl_compare_callback(dbp, dbta, dbtb, procobj, errname) * This will involve a copy, which is unpleasantly slow, but there's * little we can do to avoid this (I think). */ - a = Tcl_NewByteArrayObj(dbta->data, dbta->size); + a = Tcl_NewByteArrayObj(dbta->data, (int)dbta->size); Tcl_IncrRefCount(a); - b = Tcl_NewByteArrayObj(dbtb->data, dbtb->size); + b = Tcl_NewByteArrayObj(dbtb->data, (int)dbtb->size); Tcl_IncrRefCount(b); objv[1] = a; @@ -3052,26 +3426,30 @@ tcl_h_hash(dbp, buf, len) /* * Create a ByteArray for the buffer. */ - objv[1] = Tcl_NewByteArrayObj((void *)buf, len); + objv[1] = Tcl_NewByteArrayObj((void *)buf, (int)len); Tcl_IncrRefCount(objv[1]); result = Tcl_EvalObjv(interp, 2, objv, 0); - if (result != TCL_OK) { - /* - * XXX - * We drop core on error. See the comment in - * tcl_compare_callback. - */ -panic: __db_err(dbp->dbenv, "Tcl h_hash callback failed"); - DB_ASSERT(0); - return (__db_panic(dbp->dbenv, DB_RUNRECOVERY)); - } + if (result != TCL_OK) + goto panic; result = Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &hval); if (result != TCL_OK) goto panic; Tcl_DecrRefCount(objv[1]); - return (hval); + return ((u_int32_t)hval); + +panic: /* + * We drop core on error, in diagnostic mode. See the comment in + * tcl_compare_callback. + */ + __db_err(dbp->dbenv, "Tcl h_hash callback failed"); + (void)__db_panic(dbp->dbenv, DB_RUNRECOVERY); + + DB_ASSERT(0); + + /* NOTREACHED */ + return (0); } /* @@ -3097,21 +3475,21 @@ tcl_rep_send(dbenv, control, rec, lsnp, eid, flags) interp = ip->i_interp; objv[0] = ip->i_rep_send; - control_o = Tcl_NewByteArrayObj(control->data, control->size); + control_o = Tcl_NewByteArrayObj(control->data, (int)control->size); Tcl_IncrRefCount(control_o); - rec_o = Tcl_NewByteArrayObj(rec->data, rec->size); + rec_o = Tcl_NewByteArrayObj(rec->data, (int)rec->size); Tcl_IncrRefCount(rec_o); eid_o = Tcl_NewIntObj(eid); Tcl_IncrRefCount(eid_o); if (LF_ISSET(DB_REP_PERMANENT)) - flags_o = Tcl_NewStringObj("perm", strlen("perm")); + flags_o = NewStringObj("perm", strlen("perm")); else if (LF_ISSET(DB_REP_NOBUFFER)) - flags_o = Tcl_NewStringObj("nobuffer", strlen("nobuffer")); + flags_o = NewStringObj("nobuffer", strlen("nobuffer")); else - flags_o = Tcl_NewStringObj("none", strlen("none")); + flags_o = NewStringObj("none", strlen("none")); Tcl_IncrRefCount(flags_o); myobjc = 2; @@ -3181,7 +3559,7 @@ tcl_db_malloc(size) return (NULL); Tcl_IncrRefCount(obj); - Tcl_SetObjLength(obj, size + sizeof(Tcl_Obj *)); + Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *))); buf = Tcl_GetString(obj); memcpy(buf, &obj, sizeof(&obj)); @@ -3200,7 +3578,7 @@ tcl_db_realloc(ptr, size) return (tcl_db_malloc(size)); obj = *(Tcl_Obj **)((Tcl_Obj **)ptr - 1); - Tcl_SetObjLength(obj, size + sizeof(Tcl_Obj *)); + Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *))); ptr = Tcl_GetString(obj); memcpy(ptr, &obj, sizeof(&obj)); diff --git a/db/tcl/tcl_dbcursor.c b/db/tcl/tcl_dbcursor.c index 489c387bc..f0ca788f4 100644 --- a/db/tcl/tcl_dbcursor.c +++ b/db/tcl/tcl_dbcursor.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_dbcursor.c,v 11.65 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_dbcursor.c,v 11.57 2003/05/17 15:15:45 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -43,7 +41,7 @@ dbc_Cmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* The argument objects */ { static const char *dbccmds[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "pget", #endif "close", @@ -54,7 +52,7 @@ dbc_Cmd(clientData, interp, objc, objv) NULL }; enum dbccmds { -#if CONFIG_TEST +#ifdef CONFIG_TEST DBCPGET, #endif DBCCLOSE, @@ -93,7 +91,7 @@ dbc_Cmd(clientData, interp, objc, objv) TCL_EXACT, &cmdindex) != TCL_OK) return (IS_HELP(objv[1])); switch ((enum dbccmds)cmdindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBCPGET: result = tcl_DbcGet(interp, objc, objv, dbc, 1); break; @@ -152,7 +150,7 @@ tcl_DbcPut(interp, objc, objv, dbc) DBC *dbc; /* Cursor pointer */ { static const char *dbcutopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-nodupdata", #endif "-after", @@ -164,7 +162,7 @@ tcl_DbcPut(interp, objc, objv, dbc) NULL }; enum dbcutopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST DBCPUT_NODUPDATA, #endif DBCPUT_AFTER, @@ -184,6 +182,9 @@ tcl_DbcPut(interp, objc, objv, dbc) u_int32_t flag; int elemc, freekey, freedata, i, optindex, result, ret; + COMPQUIET(dtmp, NULL); + COMPQUIET(ktmp, NULL); + result = TCL_OK; flag = 0; freekey = freedata = 0; @@ -217,7 +218,7 @@ tcl_DbcPut(interp, objc, objv, dbc) } i++; switch ((enum dbcutopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case DBCPUT_NODUPDATA: FLAG_CHECK(flag); flag = DB_NODUPDATA; @@ -363,9 +364,9 @@ tcl_DbcPut(interp, objc, objv, dbc) } out: if (freedata) - (void)__os_free(NULL, dtmp); + __os_free(NULL, dtmp); if (freekey) - (void)__os_free(NULL, ktmp); + __os_free(NULL, ktmp); return (result); } @@ -381,7 +382,8 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) int ispget; /* 1 for pget, 0 for get */ { static const char *dbcgetopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST + "-degree_2", "-dirty", "-get_both_range", "-multi", @@ -406,7 +408,8 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) NULL }; enum dbcgetopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST + DBCGET_DEGREE2, DBCGET_DIRTY, DBCGET_BOTH_RANGE, DBCGET_MULTI, @@ -438,9 +441,13 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) db_recno_t precno, recno; u_int32_t flag, op; int elemc, freekey, freedata, i, optindex, result, ret; -#if CONFIG_TEST +#ifdef CONFIG_TEST int bufsize; + + bufsize = 0; #endif + COMPQUIET(dtmp, NULL); + COMPQUIET(ktmp, NULL); result = TCL_OK; flag = 0; @@ -474,7 +481,10 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) } i++; switch ((enum dbcgetopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST + case DBCGET_DEGREE2: + flag |= DB_DEGREE_2; + break; case DBCGET_DIRTY: flag |= DB_DIRTY_READ; break; @@ -643,7 +653,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) op = flag & DB_OPFLAGS_MASK; switch (op) { case DB_GET_BOTH: -#if CONFIG_TEST +#ifdef CONFIG_TEST case DB_GET_BOTH_RANGE: #endif if (i != (objc - 2)) { @@ -703,10 +713,10 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) result = TCL_ERROR; goto out; } -#if CONFIG_TEST +#ifdef CONFIG_TEST if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) { - (void)__os_malloc(NULL, bufsize, &data.data); - data.ulen = bufsize; + (void)__os_malloc(NULL, (size_t)bufsize, &data.data); + data.ulen = (u_int32_t)bufsize; data.flags |= DB_DBT_USERMEM; } else #endif @@ -739,10 +749,10 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) goto out; } key.flags |= DB_DBT_MALLOC; -#if CONFIG_TEST +#ifdef CONFIG_TEST if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) { - (void)__os_malloc(NULL, bufsize, &data.data); - data.ulen = bufsize; + (void)__os_malloc(NULL, (size_t)bufsize, &data.data); + data.ulen = (u_int32_t)bufsize; data.flags |= DB_DBT_USERMEM; } else #endif @@ -761,7 +771,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) goto out; retlist = Tcl_NewListObj(0, NULL); - if (ret == DB_NOTFOUND) + if (ret != 0) goto out1; if (op == DB_GET_RECNO) { recno = *((db_recno_t *)data.data); @@ -806,9 +816,9 @@ out: if (data.data != NULL && flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) __os_free(dbc->dbp->dbenv, data.data); if (freedata) - (void)__os_free(NULL, dtmp); + __os_free(NULL, dtmp); if (freekey) - (void)__os_free(NULL, ktmp); + __os_free(NULL, ktmp); return (result); } @@ -901,7 +911,6 @@ tcl_DbcDup(interp, objc, objv, dbc) * Now duplicate the cursor. If successful, we need to create * a new cursor command. */ - snprintf(newname, sizeof(newname), "%s.c%d", dbip->i_name, dbip->i_dbdbcid); newdbcip = _NewInfo(interp, NULL, newname, I_DBC); @@ -910,10 +919,10 @@ tcl_DbcDup(interp, objc, objv, dbc) if (ret == 0) { dbip->i_dbdbcid++; newdbcip->i_parent = dbip; - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)dbc_Cmd, (ClientData)newdbc, NULL); - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(newdbcip, newdbc); Tcl_SetObjResult(interp, res); } else { diff --git a/db/tcl/tcl_env.c b/db/tcl/tcl_env.c index 21b82890b..e513b961d 100644 --- a/db/tcl/tcl_env.c +++ b/db/tcl/tcl_env.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_env.c,v 11.121 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_env.c,v 11.105 2003/09/04 20:45:44 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -53,8 +51,10 @@ env_Cmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* The argument objects */ { static const char *envcmds[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "attributes", + "errfile", + "errpfx", "lock_detect", "lock_id", "lock_id_free", @@ -109,6 +109,8 @@ env_Cmd(clientData, interp, objc, objv) "get_lk_max_lockers", "get_lk_max_locks", "get_lk_max_objects", + "get_mp_max_openfd", + "get_mp_max_write", "get_mp_mmapsize", "get_open_flags", "get_rep_limit", @@ -124,8 +126,10 @@ env_Cmd(clientData, interp, objc, objv) NULL }; enum envcmds { -#if CONFIG_TEST +#ifdef CONFIG_TEST ENVATTR, + ENVERRFILE, + ENVERRPFX, ENVLKDETECT, ENVLKID, ENVLKFREEID, @@ -180,6 +184,8 @@ env_Cmd(clientData, interp, objc, objv) ENVGETLKMAXLOCKERS, ENVGETLKMAXLOCKS, ENVGETLKMAXOBJECTS, + ENVGETMPMAXOPENFD, + ENVGETMPMAXWRITE, ENVGETMPMMAPSIZE, ENVGETOPENFLAG, ENVGETREPLIMIT, @@ -197,15 +203,16 @@ env_Cmd(clientData, interp, objc, objv) DB_ENV *dbenv; Tcl_Obj *res, *myobjv[3]; char newname[MSG_SIZE]; - int cmdindex, i, ncache, result, ret; + int cmdindex, i, intvalue1, intvalue2, ncache, result, ret; u_int32_t bytes, gbytes, value; size_t size; long shm_key; time_t timeval; const char *strval, **dirs; -#if CONFIG_TEST +#ifdef CONFIG_TEST DBTCL_INFO *logcip; DB_LOGC *logc; + char *strarg; u_int32_t lockid; long newval, otherval; #endif @@ -238,7 +245,7 @@ env_Cmd(clientData, interp, objc, objv) return (IS_HELP(objv[1])); res = NULL; switch ((enum envcmds)cmdindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case ENVLKDETECT: result = tcl_LockDetect(interp, objc, objv, dbenv); break; @@ -268,10 +275,10 @@ env_Cmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 3, objv, NULL); return (TCL_ERROR); } - result = Tcl_GetLongFromObj(interp, objv[2], (long *)&newval); + result = Tcl_GetLongFromObj(interp, objv[2], &newval); if (result != TCL_OK) return (result); - ret = dbenv->lock_id_free(dbenv, newval); + ret = dbenv->lock_id_free(dbenv, (u_int32_t)newval); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock id_free"); break; @@ -280,13 +287,14 @@ env_Cmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 4, objv, "current max"); return (TCL_ERROR); } - result = Tcl_GetLongFromObj(interp, objv[2], (long *)&newval); + result = Tcl_GetLongFromObj(interp, objv[2], &newval); if (result != TCL_OK) return (result); - result = Tcl_GetLongFromObj(interp, objv[3], (long *)&otherval); + result = Tcl_GetLongFromObj(interp, objv[3], &otherval); if (result != TCL_OK) return (result); - ret = __lock_id_set(dbenv, newval, otherval); + ret = __lock_id_set(dbenv, + (u_int32_t)newval, (u_int32_t)otherval); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock id_free"); break; @@ -317,11 +325,10 @@ env_Cmd(clientData, interp, objc, objv) * not "tied" to the env. That is, they * are NOT closed if the env is closed. */ - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)logc_Cmd, (ClientData)logc, NULL); - res = - Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); _SetInfoData(logcip, logc); } else { _DeleteInfo(logcip); @@ -393,22 +400,23 @@ env_Cmd(clientData, interp, objc, objv) * !!! Retrieve the client ID from the dbp handle directly. * This is for testing purposes only. It is dbp-private data. */ - res = Tcl_NewLongObj(dbenv->cl_id); + res = Tcl_NewLongObj((long)dbenv->cl_id); break; case ENVTXNSETID: if (objc != 4) { Tcl_WrongNumArgs(interp, 4, objv, "current max"); return (TCL_ERROR); } - result = Tcl_GetLongFromObj(interp, objv[2], (long *)&newval); + result = Tcl_GetLongFromObj(interp, objv[2], &newval); if (result != TCL_OK) return (result); - result = Tcl_GetLongFromObj(interp, objv[3], (long *)&otherval); + result = Tcl_GetLongFromObj(interp, objv[3], &otherval); if (result != TCL_OK) return (result); - ret = __txn_id_set(dbenv, newval, otherval); + ret = __txn_id_set(dbenv, + (u_int32_t)newval, (u_int32_t)otherval); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "lock id_free"); + "txn setid"); break; case ENVTXNRECOVER: result = tcl_TxnRecover(interp, objc, objv, dbenv, envip); @@ -425,6 +433,29 @@ env_Cmd(clientData, interp, objc, objv) case ENVATTR: result = tcl_EnvAttr(interp, objc, objv, dbenv); break; + case ENVERRFILE: + /* + * One args for this. Error if different. + */ + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "errfile"); + return (TCL_ERROR); + } + strarg = Tcl_GetStringFromObj(objv[2], NULL); + tcl_EnvSetErrfile(interp, dbenv, envip, strarg); + result = TCL_OK; + break; + case ENVERRPFX: + /* + * One args for this. Error if different. + */ + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pfx"); + return (TCL_ERROR); + } + strarg = Tcl_GetStringFromObj(objv[2], NULL); + result = tcl_EnvSetErrpfx(interp, dbenv, envip, strarg); + break; case ENVSETFLAGS: /* * Two args for this. Error if different. @@ -486,9 +517,9 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_cachesize(dbenv, &gbytes, &bytes, &ncache); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_cachesize")) == TCL_OK) { - myobjv[0] = Tcl_NewIntObj(gbytes); - myobjv[1] = Tcl_NewIntObj(bytes); - myobjv[2] = Tcl_NewIntObj(ncache); + myobjv[0] = Tcl_NewLongObj((long)gbytes); + myobjv[1] = Tcl_NewLongObj((long)bytes); + myobjv[2] = Tcl_NewLongObj((long)ncache); res = Tcl_NewListObj(3, myobjv); } break; @@ -503,7 +534,7 @@ env_Cmd(clientData, interp, objc, objv) res = Tcl_NewListObj(0, NULL); for (i = 0; result == TCL_OK && dirs[i] != NULL; i++) result = Tcl_ListObjAppendElement(interp, res, - Tcl_NewStringObj(dirs[i], strlen(dirs[i]))); + NewStringObj(dirs[i], strlen(dirs[i]))); } break; case ENVGETENCRYPTFLAGS: @@ -515,7 +546,7 @@ env_Cmd(clientData, interp, objc, objv) return (TCL_ERROR); } dbenv->get_errpfx(dbenv, &strval); - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case ENVGETFLAGS: result = env_GetFlags(interp, objc, objv, dbenv); @@ -528,7 +559,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_home(dbenv, &strval); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_home")) == TCL_OK) - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case ENVGETLGBSIZE: if (objc != 2) { @@ -538,7 +569,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lg_bsize(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lg_bsize")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETLGDIR: if (objc != 2) { @@ -548,7 +579,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lg_dir(dbenv, &strval); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lg_dir")) == TCL_OK) - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case ENVGETLGMAX: if (objc != 2) { @@ -558,7 +589,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lg_max(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lg_max")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETLGREGIONMAX: if (objc != 2) { @@ -568,7 +599,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lg_regionmax(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lg_regionmax")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETLKDETECT: result = env_GetLockDetect(interp, objc, objv, dbenv); @@ -581,7 +612,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lk_max_lockers(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lk_max_lockers")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETLKMAXLOCKS: if (objc != 2) { @@ -591,7 +622,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lk_max_locks(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lk_max_locks")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETLKMAXOBJECTS: if (objc != 2) { @@ -601,7 +632,30 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_lk_max_objects(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_lk_max_objects")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); + break; + case ENVGETMPMAXOPENFD: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = dbenv->get_mp_max_openfd(dbenv, &intvalue1); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "env get_mp_max_openfd")) == TCL_OK) + res = Tcl_NewIntObj(intvalue1); + break; + case ENVGETMPMAXWRITE: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = dbenv->get_mp_max_write(dbenv, &intvalue1, &intvalue2); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "env get_mp_max_write")) == TCL_OK) { + myobjv[0] = Tcl_NewIntObj(intvalue1); + myobjv[1] = Tcl_NewIntObj(intvalue2); + res = Tcl_NewListObj(2, myobjv); + } break; case ENVGETMPMMAPSIZE: if (objc != 2) { @@ -611,7 +665,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_mp_mmapsize(dbenv, &size); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_mp_mmapsize")) == TCL_OK) - res = Tcl_NewIntObj(size); + res = Tcl_NewLongObj((long)size); break; case ENVGETOPENFLAG: result = env_GetOpenFlag(interp, objc, objv, dbenv); @@ -624,8 +678,8 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_rep_limit(dbenv, &gbytes, &bytes); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_rep_limit")) == TCL_OK) { - myobjv[0] = Tcl_NewIntObj(gbytes); - myobjv[1] = Tcl_NewIntObj(bytes); + myobjv[0] = Tcl_NewLongObj((long)gbytes); + myobjv[1] = Tcl_NewLongObj((long)bytes); res = Tcl_NewListObj(2, myobjv); } break; @@ -647,7 +701,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_tas_spins(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_tas_spins")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETTIMEOUT: result = env_GetTimeout(interp, objc, objv, dbenv); @@ -660,7 +714,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_tmp_dir(dbenv, &strval); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_tmp_dir")) == TCL_OK) - res = Tcl_NewStringObj(strval, strlen(strval)); + res = NewStringObj(strval, strlen(strval)); break; case ENVGETTXMAX: if (objc != 2) { @@ -670,7 +724,7 @@ env_Cmd(clientData, interp, objc, objv) ret = dbenv->get_tx_max(dbenv, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_tx_max")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewLongObj((long)value); break; case ENVGETTXTIMESTAMP: if (objc != 2) { @@ -716,7 +770,7 @@ tcl_EnvRemove(interp, objc, objv, dbenv, envip) DBTCL_INFO *envip; /* Info pointer */ { static const char *envremopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "-overwrite", "-server", #endif @@ -732,7 +786,7 @@ tcl_EnvRemove(interp, objc, objv, dbenv, envip) NULL }; enum envremopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST ENVREM_OVERWRITE, ENVREM_SERVER, #endif @@ -773,7 +827,7 @@ tcl_EnvRemove(interp, objc, objv, dbenv, envip) } i++; switch ((enum envremopts)optindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case ENVREM_SERVER: /* Make sure we have an arg to check against! */ if (i >= objc) { @@ -821,7 +875,7 @@ tcl_EnvRemove(interp, objc, objv, dbenv, envip) } home = Tcl_GetStringFromObj(objv[i++], NULL); break; -#if CONFIG_TEST +#ifdef CONFIG_TEST case ENVREM_OVERWRITE: sflag |= DB_OVERWRITE; break; @@ -973,7 +1027,7 @@ _EnvInfoDelete(interp, envip) * Other types like log cursors and locks will just * get cleaned up here. */ - if (p->i_parent == envip) { + if (p->i_parent == envip) { switch (p->i_type) { case I_TXN: _TxnInfoDelete(interp, p); @@ -981,7 +1035,15 @@ _EnvInfoDelete(interp, envip) case I_MP: _MpInfoDelete(interp, p); break; - default: + case I_DB: + case I_DBC: + case I_ENV: + case I_LOCK: + case I_LOGC: + case I_MUTEX: + case I_NDBM: + case I_PG: + case I_SEQ: Tcl_SetResult(interp, "_EnvInfoDelete: bad info type", TCL_STATIC); @@ -997,7 +1059,7 @@ _EnvInfoDelete(interp, envip) _DeleteInfo(envip); } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * PUBLIC: int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, * PUBLIC: Tcl_Obj *)); @@ -1012,7 +1074,6 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) Tcl_Obj *onoff; /* On or off */ { static const char *verbwhich[] = { - "chkpt", "deadlock", "recovery", "rep", @@ -1020,7 +1081,6 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) NULL }; enum verbwhich { - ENVVERB_CHK, ENVVERB_DEAD, ENVVERB_REC, ENVVERB_REP, @@ -1043,9 +1103,6 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) return (IS_HELP(which)); switch ((enum verbwhich)optindex) { - case ENVVERB_CHK: - wh = DB_VERB_CHKPOINT; - break; case ENVVERB_DEAD: wh = DB_VERB_DEADLOCK; break; @@ -1080,7 +1137,7 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * PUBLIC: int tcl_EnvAttr __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); * @@ -1109,58 +1166,58 @@ tcl_EnvAttr(interp, objc, objv, dbenv) * We peek at the dbenv to determine what subsystems * we have available in this env. */ - myobj = Tcl_NewStringObj("-home", strlen("-home")); + myobj = NewStringObj("-home", strlen("-home")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; - myobj = Tcl_NewStringObj(dbenv->db_home, strlen(dbenv->db_home)); + myobj = NewStringObj(dbenv->db_home, strlen(dbenv->db_home)); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; if (CDB_LOCKING(dbenv)) { - myobj = Tcl_NewStringObj("-cdb", strlen("-cdb")); + myobj = NewStringObj("-cdb", strlen("-cdb")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (CRYPTO_ON(dbenv)) { - myobj = Tcl_NewStringObj("-crypto", strlen("-crypto")); + myobj = NewStringObj("-crypto", strlen("-crypto")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (LOCKING_ON(dbenv)) { - myobj = Tcl_NewStringObj("-lock", strlen("-lock")); + myobj = NewStringObj("-lock", strlen("-lock")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (LOGGING_ON(dbenv)) { - myobj = Tcl_NewStringObj("-log", strlen("-log")); + myobj = NewStringObj("-log", strlen("-log")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (MPOOL_ON(dbenv)) { - myobj = Tcl_NewStringObj("-mpool", strlen("-mpool")); + myobj = NewStringObj("-mpool", strlen("-mpool")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (RPC_ON(dbenv)) { - myobj = Tcl_NewStringObj("-rpc", strlen("-rpc")); + myobj = NewStringObj("-rpc", strlen("-rpc")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (REP_ON(dbenv)) { - myobj = Tcl_NewStringObj("-rep", strlen("-rep")); + myobj = NewStringObj("-rep", strlen("-rep")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; } if (TXN_ON(dbenv)) { - myobj = Tcl_NewStringObj("-txn", strlen("-txn")); + myobj = NewStringObj("-txn", strlen("-txn")); if ((result = Tcl_ListObjAppendElement(interp, retlist, myobj)) != TCL_OK) goto err; @@ -1188,12 +1245,13 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff) "-auto_commit", "-direct_db", "-direct_log", + "-dsync_log", + "-log_inmemory", "-log_remove", "-nolock", "-nommap", "-nopanic", "-nosync", - "-notdurable", "-overwrite", "-panic", "-wrnosync", @@ -1203,12 +1261,13 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff) ENVSF_AUTOCOMMIT, ENVSF_DIRECTDB, ENVSF_DIRECTLOG, + ENVSF_DSYNCLOG, + ENVSF_LOG_INMEMORY, ENVSF_LOG_REMOVE, ENVSF_NOLOCK, ENVSF_NOMMAP, ENVSF_NOPANIC, ENVSF_NOSYNC, - ENVSF_NOTDURABLE, ENVSF_OVERWRITE, ENVSF_PANIC, ENVSF_WRNOSYNC @@ -1239,6 +1298,12 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff) case ENVSF_DIRECTLOG: wh = DB_DIRECT_LOG; break; + case ENVSF_DSYNCLOG: + wh = DB_DSYNC_LOG; + break; + case ENVSF_LOG_INMEMORY: + wh = DB_LOG_INMEMORY; + break; case ENVSF_LOG_REMOVE: wh = DB_LOG_AUTOREMOVE; break; @@ -1248,9 +1313,6 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff) case ENVSF_NOMMAP: wh = DB_NOMMAP; break; - case ENVSF_NOTDURABLE: - wh = DB_TXN_NOT_DURABLE; - break; case ENVSF_NOSYNC: wh = DB_TXN_NOSYNC; break; @@ -1301,15 +1363,18 @@ tcl_EnvTest(interp, objc, objv, dbenv) { static const char *envtestcmd[] = { "abort", + "check", "copy", NULL }; enum envtestcmd { ENVTEST_ABORT, + ENVTEST_CHECK, ENVTEST_COPY }; static const char *envtestat[] = { "electinit", + "electvote1", "none", "predestroy", "preopen", @@ -1323,6 +1388,7 @@ tcl_EnvTest(interp, objc, objv, dbenv) }; enum envtestat { ENVTEST_ELECTINIT, + ENVTEST_ELECTVOTE1, ENVTEST_NONE, ENVTEST_PREDESTROY, ENVTEST_PREOPEN, @@ -1344,7 +1410,7 @@ tcl_EnvTest(interp, objc, objv, dbenv) } /* - * This must be the "copy" or "abort" portion of the command. + * This must be the "check", "copy" or "abort" portion of the command. */ if (Tcl_GetIndexFromObj(interp, objv[2], envtestcmd, "command", TCL_EXACT, &optindex) != TCL_OK) { @@ -1355,6 +1421,13 @@ tcl_EnvTest(interp, objc, objv, dbenv) case ENVTEST_ABORT: loc = &dbenv->test_abort; break; + case ENVTEST_CHECK: + loc = &dbenv->test_check; + if (Tcl_GetIntFromObj(interp, objv[3], &testval) != TCL_OK) { + result = IS_HELP(objv[3]); + return (result); + } + goto done; case ENVTEST_COPY: loc = &dbenv->test_copy; break; @@ -1376,6 +1449,10 @@ tcl_EnvTest(interp, objc, objv, dbenv) DB_ASSERT(loc == &dbenv->test_abort); testval = DB_TEST_ELECTINIT; break; + case ENVTEST_ELECTVOTE1: + DB_ASSERT(loc == &dbenv->test_abort); + testval = DB_TEST_ELECTVOTE1; + break; case ENVTEST_NONE: testval = 0; break; @@ -1408,7 +1485,7 @@ tcl_EnvTest(interp, objc, objv, dbenv) Tcl_SetResult(interp, "Illegal test location", TCL_STATIC); return (TCL_ERROR); } - +done: *loc = testval; Tcl_SetResult(interp, "0", TCL_STATIC); return (result); @@ -1520,13 +1597,13 @@ env_DbRemove(interp, objc, objv, dbenv) if (i != objc) { subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &subdblen); - if ((ret = __os_malloc(dbenv, subdblen + 1, - &subdb)) != 0) { + if ((ret = __os_malloc( + dbenv, (size_t)subdblen + 1, &subdb)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(subdb, subdbtmp, subdblen); + memcpy(subdb, subdbtmp, (size_t)subdblen); subdb[subdblen] = '\0'; } } else { @@ -1649,24 +1726,23 @@ env_DbRename(interp, objc, objv, dbenv) if (i == objc - 2) { subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &subdblen); - if ((ret = __os_malloc(dbenv, subdblen + 1, - &subdb)) != 0) { + if ((ret = __os_malloc( + dbenv, (size_t)subdblen + 1, &subdb)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(subdb, subdbtmp, subdblen); + memcpy(subdb, subdbtmp, (size_t)subdblen); subdb[subdblen] = '\0'; } - subdbtmp = - Tcl_GetByteArrayFromObj(objv[i++], &newlen); - if ((ret = __os_malloc(dbenv, newlen + 1, - &newname)) != 0) { + subdbtmp = Tcl_GetByteArrayFromObj(objv[i++], &newlen); + if ((ret = __os_malloc( + dbenv, (size_t)newlen + 1, &newname)) != 0) { Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC); return (0); } - memcpy(newname, subdbtmp, newlen); + memcpy(newname, subdbtmp, (size_t)newlen); newname[newlen] = '\0'; } else { Tcl_WrongNumArgs(interp, 3, objv, @@ -1709,7 +1785,9 @@ env_GetFlags(interp, objc, objv, dbenv) { DB_CDB_ALLDB, "-cdb_alldb" }, { DB_DIRECT_DB, "-direct_db" }, { DB_DIRECT_LOG, "-direct_log" }, + { DB_DSYNC_LOG, "-dsync_log" }, { DB_LOG_AUTOREMOVE, "-log_remove" }, + { DB_LOG_INMEMORY, "-log_inmemory" }, { DB_NOLOCKING, "-nolock" }, { DB_NOMMAP, "-nommap" }, { DB_NOPANIC, "-nopanic" }, @@ -1717,7 +1795,6 @@ env_GetFlags(interp, objc, objv, dbenv) { DB_PANIC_ENVIRONMENT, "-panic" }, { DB_REGION_INIT, "-region_init" }, { DB_TXN_NOSYNC, "-nosync" }, - { DB_TXN_NOT_DURABLE, "-notdurable" }, { DB_TXN_WRITE_NOSYNC, "-wrnosync" }, { DB_YIELDCPU, "-yield" }, { 0, NULL } @@ -1736,11 +1813,12 @@ env_GetFlags(interp, objc, objv, dbenv) for (i = 0; open_flags[i].flag != 0; i++) if (LF_ISSET(open_flags[i].flag)) { if (strlen(buf) > 0) - strncat(buf, " ", sizeof(buf)); - strncat(buf, open_flags[i].arg, sizeof(buf)); + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, open_flags[i].arg, sizeof(buf)); } - res = Tcl_NewStringObj(buf, strlen(buf)); + res = NewStringObj(buf, strlen(buf)); Tcl_SetObjResult(interp, res); } @@ -1797,11 +1875,12 @@ env_GetOpenFlag(interp, objc, objv, dbenv) for (i = 0; open_flags[i].flag != 0; i++) if (LF_ISSET(open_flags[i].flag)) { if (strlen(buf) > 0) - strncat(buf, " ", sizeof(buf)); - strncat(buf, open_flags[i].arg, sizeof(buf)); + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, open_flags[i].arg, sizeof(buf)); } - res = Tcl_NewStringObj(buf, strlen(buf)); + res = NewStringObj(buf, strlen(buf)); Tcl_SetObjResult(interp, res); } @@ -1848,11 +1927,12 @@ tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv) for (i = 0; encrypt_flags[i].flag != 0; i++) if (LF_ISSET(encrypt_flags[i].flag)) { if (strlen(buf) > 0) - strncat(buf, " ", sizeof(buf)); - strncat(buf, encrypt_flags[i].arg, sizeof(buf)); + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, encrypt_flags[i].arg, sizeof(buf)); } - res = Tcl_NewStringObj(buf, strlen(buf)); + res = NewStringObj(buf, strlen(buf)); Tcl_SetObjResult(interp, res); } @@ -1881,6 +1961,7 @@ env_GetLockDetect(interp, objc, objv, dbenv) { DB_LOCK_DEFAULT, "default" }, { DB_LOCK_EXPIRE, "expire" }, { DB_LOCK_MAXLOCKS, "maxlocks" }, + { DB_LOCK_MAXWRITE, "maxwrite" }, { DB_LOCK_MINLOCKS, "minlocks" }, { DB_LOCK_MINWRITE, "minwrite" }, { DB_LOCK_OLDEST, "oldest" }, @@ -1901,7 +1982,7 @@ env_GetLockDetect(interp, objc, objv, dbenv) if (lk_detect == lk_detect_returns[i].flag) answer = lk_detect_returns[i].name; - res = Tcl_NewStringObj(answer, strlen(answer)); + res = NewStringObj(answer, strlen(answer)); Tcl_SetObjResult(interp, res); } @@ -1919,11 +2000,6 @@ env_GetTimeout(interp, objc, objv, dbenv) Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *dbenv; { - int i, ret, result; - u_int32_t which; - const char *arg; - db_timeout_t timeout; - Tcl_Obj *res; static const struct { u_int32_t flag; char *arg; @@ -1932,6 +2008,13 @@ env_GetTimeout(interp, objc, objv, dbenv) { DB_SET_LOCK_TIMEOUT, "lock" }, { 0, NULL } }; + Tcl_Obj *res; + db_timeout_t timeout; + u_int32_t which; + int i, ret, result; + const char *arg; + + COMPQUIET(timeout, 0); if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, NULL); @@ -1951,7 +2034,7 @@ env_GetTimeout(interp, objc, objv, dbenv) ret = dbenv->get_timeout(dbenv, &timeout, which); err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_timeout")) == TCL_OK) { - res = Tcl_NewLongObj(timeout); + res = Tcl_NewLongObj((long)timeout); Tcl_SetObjResult(interp, res); } @@ -1969,21 +2052,22 @@ env_GetVerbose(interp, objc, objv, dbenv) Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *dbenv; { - int i, onoff, ret, result; - u_int32_t which; - const char *arg, *answer; - Tcl_Obj *res; static const struct { u_int32_t flag; char *arg; } verbose_flags[] = { - { DB_VERB_CHKPOINT, "chkpt" }, { DB_VERB_DEADLOCK, "deadlock" }, { DB_VERB_RECOVERY, "recovery" }, { DB_VERB_REPLICATION, "rep" }, { DB_VERB_WAITSFOR, "wait" }, { 0, NULL } }; + Tcl_Obj *res; + u_int32_t which; + int i, onoff, ret, result; + const char *arg, *answer; + + COMPQUIET(onoff, 0); if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, NULL); @@ -2004,9 +2088,77 @@ env_GetVerbose(interp, objc, objv, dbenv) err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env get_timeout")) == 0) { answer = onoff ? "on" : "off"; - res = Tcl_NewStringObj(answer, strlen(answer)); + res = NewStringObj(answer, strlen(answer)); Tcl_SetObjResult(interp, res); } return (result); } + +/* + * PUBLIC: void tcl_EnvSetErrfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, + * PUBLIC: char *)); + * + * tcl_EnvSetErrfile -- + * Implements the ENV->set_errfile command. + */ +void +tcl_EnvSetErrfile(interp, dbenv, ip, errf) + Tcl_Interp *interp; /* Interpreter */ + DB_ENV *dbenv; /* Database pointer */ + DBTCL_INFO *ip; /* Our internal info */ + char *errf; +{ + COMPQUIET(interp, NULL); + /* + * If the user already set one, free it. + */ + if (ip->i_err != NULL && ip->i_err != stdout && + ip->i_err != stderr) + (void)fclose(ip->i_err); + if (strcmp(errf, "/dev/stdout") == 0) + ip->i_err = stdout; + else if (strcmp(errf, "/dev/stderr") == 0) + ip->i_err = stderr; + else + ip->i_err = fopen(errf, "a"); + if (ip->i_err != NULL) + dbenv->set_errfile(dbenv, ip->i_err); +} + +/* + * PUBLIC: int tcl_EnvSetErrpfx __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, + * PUBLIC: char *)); + * + * tcl_EnvSetErrpfx -- + * Implements the ENV->set_errpfx command. + */ +int +tcl_EnvSetErrpfx(interp, dbenv, ip, pfx) + Tcl_Interp *interp; /* Interpreter */ + DB_ENV *dbenv; /* Database pointer */ + DBTCL_INFO *ip; /* Our internal info */ + char *pfx; +{ + int result, ret; + + /* + * Assume success. The only thing that can fail is + * the __os_strdup. + */ + result = TCL_OK; + Tcl_SetResult(interp, "0", TCL_STATIC); + /* + * If the user already set one, free it. + */ + if (ip->i_errpfx != NULL) + __os_free(dbenv, ip->i_errpfx); + if ((ret = __os_strdup(dbenv, pfx, &ip->i_errpfx)) != 0) { + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "__os_strdup"); + ip->i_errpfx = NULL; + } + if (ip->i_errpfx != NULL) + dbenv->set_errpfx(dbenv, ip->i_errpfx); + return (result); +} diff --git a/db/tcl/tcl_internal.c b/db/tcl/tcl_internal.c index 896c4a3e3..8e9651273 100644 --- a/db/tcl/tcl_internal.c +++ b/db/tcl/tcl_internal.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_internal.c,v 11.69 2004/05/06 02:01:41 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_internal.c,v 11.59 2003/08/14 17:55:29 mjc Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -23,7 +21,6 @@ static const char revid[] = "$Id: tcl_internal.c,v 11.59 2003/08/14 17:55:29 mjc #include "dbinc/tcl_db.h" #include "dbinc/db_page.h" #include "dbinc/db_am.h" -#include "dbinc_auto/db_ext.h" /* * @@ -43,20 +40,6 @@ static const char revid[] = "$Id: tcl_internal.c,v 11.59 2003/08/14 17:55:29 mjc * get/manipulate the info structure. */ -/* - * Prototypes for procedures defined later in this file: - */ -static void tcl_flag_callback __P((u_int32_t, const FN *, void *)); - -/* - * Private structure type used to pass both an interp and an object into - * a callback's single void *. - */ -struct __tcl_callback_bundle { - Tcl_Interp *interp; - Tcl_Obj *obj; -}; - #define GLOB_CHAR(c) ((c) == '*' || (c) == '?') /* @@ -185,7 +168,7 @@ _DeleteInfo(p) if (p->i_lockobj.data != NULL) __os_free(NULL, p->i_lockobj.data); if (p->i_err != NULL && p->i_err != stderr) { - fclose(p->i_err); + (void)fclose(p->i_err); p->i_err = NULL; } if (p->i_errpfx != NULL) @@ -210,21 +193,21 @@ _DeleteInfo(p) /* * PUBLIC: int _SetListElem __P((Tcl_Interp *, - * PUBLIC: Tcl_Obj *, void *, int, void *, int)); + * PUBLIC: Tcl_Obj *, void *, u_int32_t, void *, u_int32_t)); */ int _SetListElem(interp, list, elem1, e1cnt, elem2, e2cnt) Tcl_Interp *interp; Tcl_Obj *list; void *elem1, *elem2; - int e1cnt, e2cnt; + u_int32_t e1cnt, e2cnt; { Tcl_Obj *myobjv[2], *thislist; int myobjc; myobjc = 2; - myobjv[0] = Tcl_NewByteArrayObj((u_char *)elem1, e1cnt); - myobjv[1] = Tcl_NewByteArrayObj((u_char *)elem2, e2cnt); + myobjv[0] = Tcl_NewByteArrayObj((u_char *)elem1, (int)e1cnt); + myobjv[1] = Tcl_NewByteArrayObj((u_char *)elem2, (int)e2cnt); thislist = Tcl_NewListObj(myobjc, myobjv); if (thislist == NULL) return (TCL_ERROR); @@ -233,21 +216,46 @@ _SetListElem(interp, list, elem1, e1cnt, elem2, e2cnt) } /* - * PUBLIC: int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, int)); + * PUBLIC: int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, long)); */ int _SetListElemInt(interp, list, elem1, elem2) Tcl_Interp *interp; Tcl_Obj *list; void *elem1; - int elem2; + long elem2; +{ + Tcl_Obj *myobjv[2], *thislist; + int myobjc; + + myobjc = 2; + myobjv[0] = + Tcl_NewByteArrayObj((u_char *)elem1, (int)strlen((char *)elem1)); + myobjv[1] = Tcl_NewLongObj(elem2); + thislist = Tcl_NewListObj(myobjc, myobjv); + if (thislist == NULL) + return (TCL_ERROR); + return (Tcl_ListObjAppendElement(interp, list, thislist)); +} + +/* + * PUBLIC: int _SetListElemWideInt __P((Tcl_Interp *, + * PUBLIC: Tcl_Obj *, void *, int64_t)); + */ +int +_SetListElemWideInt(interp, list, elem1, elem2) + Tcl_Interp *interp; + Tcl_Obj *list; + void *elem1; + int64_t elem2; { Tcl_Obj *myobjv[2], *thislist; int myobjc; myobjc = 2; - myobjv[0] = Tcl_NewByteArrayObj((u_char *)elem1, strlen((char *)elem1)); - myobjv[1] = Tcl_NewIntObj(elem2); + myobjv[0] = + Tcl_NewByteArrayObj((u_char *)elem1, (int)strlen((char *)elem1)); + myobjv[1] = Tcl_NewWideIntObj(elem2); thislist = Tcl_NewListObj(myobjc, myobjv); if (thislist == NULL) return (TCL_ERROR); @@ -256,7 +264,7 @@ _SetListElemInt(interp, list, elem1, elem2) /* * PUBLIC: int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *, - * PUBLIC: db_recno_t, u_char *, int)); + * PUBLIC: db_recno_t, u_char *, u_int32_t)); */ int _SetListRecnoElem(interp, list, elem1, elem2, e2size) @@ -264,14 +272,14 @@ _SetListRecnoElem(interp, list, elem1, elem2, e2size) Tcl_Obj *list; db_recno_t elem1; u_char *elem2; - int e2size; + u_int32_t e2size; { Tcl_Obj *myobjv[2], *thislist; int myobjc; myobjc = 2; myobjv[0] = Tcl_NewWideIntObj((Tcl_WideInt)elem1); - myobjv[1] = Tcl_NewByteArrayObj(elem2, e2size); + myobjv[1] = Tcl_NewByteArrayObj(elem2, (int)e2size); thislist = Tcl_NewListObj(myobjc, myobjv); if (thislist == NULL) return (TCL_ERROR); @@ -309,17 +317,18 @@ _Set3DBTList(interp, list, elem1, is1recno, elem2, is2recno, elem3) myobjv[0] = Tcl_NewWideIntObj( (Tcl_WideInt)*(db_recno_t *)elem1->data); else - myobjv[0] = - Tcl_NewByteArrayObj((u_char *)elem1->data, elem1->size); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)elem1->data, (int)elem1->size); if (is2recno) myobjv[1] = Tcl_NewWideIntObj( (Tcl_WideInt)*(db_recno_t *)elem2->data); else - myobjv[1] = - Tcl_NewByteArrayObj((u_char *)elem2->data, elem2->size); + myobjv[1] = Tcl_NewByteArrayObj( + (u_char *)elem2->data, (int)elem2->size); - myobjv[2] = Tcl_NewByteArrayObj((u_char *)elem3->data, elem3->size); + myobjv[2] = Tcl_NewByteArrayObj( + (u_char *)elem3->data, (int)elem3->size); thislist = Tcl_NewListObj(3, myobjv); @@ -469,18 +478,21 @@ _ErrorSetup(interp, ret, errmsg) } /* - * PUBLIC: void _ErrorFunc __P((CONST char *, char *)); + * PUBLIC: void _ErrorFunc __P((const DB_ENV *, CONST char *, const char *)); */ void -_ErrorFunc(pfx, msg) +_ErrorFunc(dbenv, pfx, msg) + const DB_ENV *dbenv; CONST char *pfx; - char *msg; + const char *msg; { DBTCL_INFO *p; Tcl_Interp *interp; - int size; + size_t size; char *err; + COMPQUIET(dbenv, NULL); + p = _NameToInfo(pfx); if (p == NULL) return; @@ -579,70 +591,41 @@ _GetUInt32(interp, obj, resp) } /* - * tcl_flag_callback -- - * Callback for db_pr.c functions that contain the FN struct mapping - * flag values to meaningful strings. This function appends a Tcl_Obj - * containing each pertinent flag string to the specified Tcl list. + * _GetFlagsList -- + * Get a new Tcl object, containing a list of the string values + * associated with a particular set of flag values. + * + * PUBLIC: Tcl_Obj *_GetFlagsList __P((Tcl_Interp *, u_int32_t, const FN *)); */ -static void -tcl_flag_callback(flags, fn, vtcbp) +Tcl_Obj * +_GetFlagsList(interp, flags, fnp) + Tcl_Interp *interp; u_int32_t flags; - const FN *fn; - void *vtcbp; -{ const FN *fnp; - Tcl_Interp *interp; - Tcl_Obj *newobj, *listobj; +{ + Tcl_Obj *newlist, *newobj; int result; - struct __tcl_callback_bundle *tcbp; - tcbp = (struct __tcl_callback_bundle *)vtcbp; - interp = tcbp->interp; - listobj = tcbp->obj; + newlist = Tcl_NewObj(); - for (fnp = fn; fnp->mask != 0; ++fnp) + /* + * Append a Tcl_Obj containing each pertinent flag string to the + * specified Tcl list. + */ + for (; fnp->mask != 0; ++fnp) if (LF_ISSET(fnp->mask)) { - newobj = Tcl_NewStringObj(fnp->name, strlen(fnp->name)); + newobj = NewStringObj(fnp->name, strlen(fnp->name)); result = - Tcl_ListObjAppendElement(interp, listobj, newobj); + Tcl_ListObjAppendElement(interp, newlist, newobj); /* * Tcl_ListObjAppendElement is defined to return TCL_OK - * unless listobj isn't actually a list (or convertible + * unless newlist isn't actually a list (or convertible * into one). If this is the case, we screwed up badly * somehow. */ DB_ASSERT(result == TCL_OK); } -} - -/* - * _GetFlagsList -- - * Get a new Tcl object, containing a list of the string values - * associated with a particular set of flag values, given a function - * that can extract the right names for the right flags. - * - * PUBLIC: Tcl_Obj *_GetFlagsList __P((Tcl_Interp *, u_int32_t, - * PUBLIC: void (*)(u_int32_t, void *, - * PUBLIC: void (*)(u_int32_t, const FN *, void *)))); - */ -Tcl_Obj * -_GetFlagsList(interp, flags, func) - Tcl_Interp *interp; - u_int32_t flags; - void (*func) - __P((u_int32_t, void *, void (*)(u_int32_t, const FN *, void *))); -{ - Tcl_Obj *newlist; - struct __tcl_callback_bundle tcb; - - newlist = Tcl_NewObj(); - - memset(&tcb, 0, sizeof(tcb)); - tcb.interp = interp; - tcb.obj = newlist; - - func(flags, &tcb, tcl_flag_callback); return (newlist); } @@ -660,7 +643,7 @@ _debug_check() if (__debug_print != 0) { printf("\r%7d:", __debug_on); - fflush(stdout); + (void)fflush(stdout); } if (__debug_on++ == __debug_test || __debug_stop) __db_loadme(); @@ -702,7 +685,7 @@ _CopyObjBytes(interp, obj, newp, sizep, freep) *freep = 0; ret = Tcl_GetIntFromObj(interp, obj, &i); tmp = Tcl_GetByteArrayFromObj(obj, &len); - *sizep = len; + *sizep = (u_int32_t)len; if (ret == TCL_ERROR) { Tcl_ResetResult(interp); *newp = tmp; @@ -714,9 +697,9 @@ _CopyObjBytes(interp, obj, newp, sizep, freep) * at some other point so we cannot count on GetByteArray * keeping our pointer valid. */ - if ((ret = __os_malloc(NULL, len, &new)) != 0) + if ((ret = __os_malloc(NULL, (size_t)len, &new)) != 0) return (ret); - memcpy(new, tmp, len); + memcpy(new, tmp, (size_t)len); *newp = new; *freep = 1; return (0); diff --git a/db/tcl/tcl_lock.c b/db/tcl/tcl_lock.c index 0385a0fdf..4a3de36bd 100644 --- a/db/tcl/tcl_lock.c +++ b/db/tcl/tcl_lock.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_lock.c,v 11.59 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_lock.c,v 11.53 2003/11/26 23:14:22 ubell Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -25,7 +23,7 @@ static const char revid[] = "$Id: tcl_lock.c,v 11.53 2003/11/26 23:14:22 ubell E /* * Prototypes for procedures defined later in this file: */ -#if CONFIG_TEST +#ifdef CONFIG_TEST static int lock_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); static int _LockMode __P((Tcl_Interp *, Tcl_Obj *, db_lockmode_t *)); static int _GetThisLock __P((Tcl_Interp *, DB_ENV *, u_int32_t, @@ -47,9 +45,10 @@ tcl_LockDetect(interp, objc, objv, envp) DB_ENV *envp; /* Environment pointer */ { static const char *ldopts[] = { - "expire", "default", + "expire", "maxlocks", + "maxwrites", "minlocks", "minwrites", "oldest", @@ -58,9 +57,10 @@ tcl_LockDetect(interp, objc, objv, envp) NULL }; enum ldopts { - LD_EXPIRE, LD_DEFAULT, + LD_EXPIRE, LD_MAXLOCKS, + LD_MAXWRITES, LD_MINLOCKS, LD_MINWRITES, LD_OLDEST, @@ -79,38 +79,42 @@ tcl_LockDetect(interp, objc, objv, envp) return (IS_HELP(objv[i])); i++; switch ((enum ldopts)optindex) { - case LD_EXPIRE: - FLAG_CHECK(policy); - policy = DB_LOCK_EXPIRE; - break; case LD_DEFAULT: FLAG_CHECK(policy); policy = DB_LOCK_DEFAULT; break; + case LD_EXPIRE: + FLAG_CHECK(policy); + policy = DB_LOCK_EXPIRE; + break; case LD_MAXLOCKS: FLAG_CHECK(policy); policy = DB_LOCK_MAXLOCKS; break; - case LD_MINWRITES: + case LD_MAXWRITES: FLAG_CHECK(policy); - policy = DB_LOCK_MINWRITE; + policy = DB_LOCK_MAXWRITE; break; case LD_MINLOCKS: FLAG_CHECK(policy); policy = DB_LOCK_MINLOCKS; break; - case LD_OLDEST: + case LD_MINWRITES: FLAG_CHECK(policy); - policy = DB_LOCK_OLDEST; + policy = DB_LOCK_MINWRITE; break; - case LD_YOUNGEST: + case LD_OLDEST: FLAG_CHECK(policy); - policy = DB_LOCK_YOUNGEST; + policy = DB_LOCK_OLDEST; break; case LD_RANDOM: FLAG_CHECK(policy); policy = DB_LOCK_RANDOM; break; + case LD_YOUNGEST: + FLAG_CHECK(policy); + policy = DB_LOCK_YOUNGEST; + break; } } @@ -195,12 +199,12 @@ tcl_LockGet(interp, objc, objv, envp) result = _GetThisLock(interp, envp, lockid, flag, &obj, mode, newname); if (result == TCL_OK) { - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); } out: if (freeobj) - (void)__os_free(envp, otmp); + __os_free(envp, otmp); return (result); } @@ -268,7 +272,7 @@ tcl_LockStat(interp, objc, objv, envp) MAKE_STAT_LIST("Number of transaction timeouts", sp->st_ntxntimeouts); Tcl_SetObjResult(interp, res); error: - (void)__os_ufree(envp, sp); + __os_ufree(envp, sp); return (result); } @@ -420,6 +424,7 @@ tcl_LockVec(interp, objc, objv, envp) memset(&list, 0, sizeof(DB_LOCKREQ)); flag = 0; freeobj = 0; + otmp = NULL; /* * If -nowait is given, it MUST be first arg. @@ -503,10 +508,10 @@ tcl_LockVec(interp, objc, objv, envp) thisop); goto error; } - thisop = Tcl_NewStringObj(newname, strlen(newname)); + thisop = NewStringObj(newname, strlen(newname)); (void)Tcl_ListObjAppendElement(interp, res, thisop); - if (freeobj) { - (void)__os_free(envp, otmp); + if (freeobj && otmp != NULL) { + __os_free(envp, otmp); freeobj = 0; } continue; @@ -576,8 +581,8 @@ tcl_LockVec(interp, objc, objv, envp) if (ret != 0 && result == TCL_OK) result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock put"); - if (freeobj) { - (void)__os_free(envp, otmp); + if (freeobj && otmp != NULL) { + __os_free(envp, otmp); freeobj = 0; } /* @@ -733,7 +738,7 @@ _GetThisLock(interp, envp, lockid, flag, objp, mode, newname) ip->i_parent = envip; ip->i_locker = lockid; _SetInfoData(ip, lock); - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)lock_Cmd, (ClientData)lock, NULL); error: return (result); diff --git a/db/tcl/tcl_log.c b/db/tcl/tcl_log.c index dcb4fcbbd..68c678101 100644 --- a/db/tcl/tcl_log.c +++ b/db/tcl/tcl_log.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_log.c,v 11.61 2004/04/05 20:18:32 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_log.c,v 11.58 2003/04/24 16:25:54 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -86,7 +84,7 @@ tcl_LogArchive(interp, objc, objv, envp) if (result == TCL_OK) { res = Tcl_NewListObj(0, NULL); for (file = list; file != NULL && *file != NULL; file++) { - fileobj = Tcl_NewStringObj(*file, strlen(*file)); + fileobj = NewStringObj(*file, strlen(*file)); result = Tcl_ListObjAppendElement(interp, res, fileobj); if (result != TCL_OK) break; @@ -186,7 +184,7 @@ tcl_LogFile(interp, objc, objv, envp) } result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_file"); if (ret == 0) { - res = Tcl_NewStringObj(name, strlen(name)); + res = NewStringObj(name, strlen(name)); Tcl_SetObjResult(interp, res); } @@ -336,7 +334,7 @@ tcl_LogPut(interp, objc, objv, envp) result = Tcl_ListObjAppendElement(interp, res, intobj); Tcl_SetObjResult(interp, res); if (freedata) - (void)__os_free(NULL, dtmp); + __os_free(NULL, dtmp); return (result); } /* @@ -403,7 +401,7 @@ tcl_LogStat(interp, objc, objv, envp) MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait); Tcl_SetObjResult(interp, res); error: - (void)__os_ufree(envp, sp); + __os_ufree(envp, sp); return (result); } @@ -591,7 +589,7 @@ tcl_LogcGet(interp, objc, objv, logc) goto memerr; result = Tcl_ListObjAppendElement(interp, res, lsnlist); - dataobj = Tcl_NewStringObj(data.data, data.size); + dataobj = NewStringObj(data.data, data.size); if (dataobj == NULL) { goto memerr; } diff --git a/db/tcl/tcl_mp.c b/db/tcl/tcl_mp.c index 9bfd83095..29691a31c 100644 --- a/db/tcl/tcl_mp.c +++ b/db/tcl/tcl_mp.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_mp.c,v 11.58 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_mp.c,v 11.50 2003/09/04 20:45:45 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -25,7 +23,7 @@ static const char revid[] = "$Id: tcl_mp.c,v 11.50 2003/09/04 20:45:45 bostic Ex /* * Prototypes for procedures defined later in this file: */ -#if CONFIG_TEST +#ifdef CONFIG_TEST static int mp_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); static int pg_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); static int tcl_MpGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, @@ -58,14 +56,14 @@ _MpInfoDelete(interp, mpip) * mp. Remove its commands and info structure. */ nextp = LIST_NEXT(p, entries); - if (p->i_parent == mpip && p->i_type == I_PG) { + if (p->i_parent == mpip && p->i_type == I_PG) { (void)Tcl_DeleteCommand(interp, p->i_name); _DeleteInfo(p); } } } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_MpSync -- * @@ -100,8 +98,7 @@ tcl_MpSync(interp, objc, objv, envp) _debug_check(); ret = envp->memp_sync(envp, lsnp); - result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "memp sync"); - return (result); + return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "memp sync")); } /* @@ -118,11 +115,8 @@ tcl_MpTrickle(interp, objc, objv, envp) DB_ENV *envp; /* Environment pointer */ { - int pages; - int percent; - int result; - int ret; Tcl_Obj *res; + int pages, percent, result, ret; result = TCL_OK; /* @@ -298,9 +292,9 @@ tcl_Mp(interp, objc, objv, envp, envip) ip->i_parent = envip; ip->i_pgsz = pgsize; _SetInfoData(ip, mpf); - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)mp_Cmd, (ClientData)mpf, NULL); - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); error: @@ -353,6 +347,11 @@ tcl_MpStat(interp, objc, objv, envp) MAKE_STAT_LIST("Cache size (bytes)", sp->st_bytes); MAKE_STAT_LIST("Number of caches", sp->st_ncache); MAKE_STAT_LIST("Region size", sp->st_regsize); + MAKE_STAT_LIST("Maximum memory-mapped file size", sp->st_mmapsize); + MAKE_STAT_LIST("Maximum open file descriptors", sp->st_maxopenfd); + MAKE_STAT_LIST("Maximum sequential buffer writes", sp->st_maxwrite); + MAKE_STAT_LIST( + "Sleep after writing maximum buffers", sp->st_maxwrite_sleep); MAKE_STAT_LIST("Pages mapped into address space", sp->st_map); MAKE_STAT_LIST("Cache hits", sp->st_cache_hit); MAKE_STAT_LIST("Cache misses", sp->st_cache_miss); @@ -415,9 +414,9 @@ tcl_MpStat(interp, objc, objv, envp) } Tcl_SetObjResult(interp, res1); error: - (void)__os_ufree(envp, sp); + __os_ufree(envp, sp); if (savefsp != NULL) - (void)__os_ufree(envp, savefsp); + __os_ufree(envp, savefsp); return (result); } @@ -521,7 +520,7 @@ mp_Cmd(clientData, interp, objc, objv) ret = mp->get_clear_len(mp, &value); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mp get_clear_len")) == TCL_OK) - res = Tcl_NewIntObj(value); + res = Tcl_NewIntObj((int)value); break; case MPGETFILEID: if (objc != 2) { @@ -531,8 +530,7 @@ mp_Cmd(clientData, interp, objc, objv) ret = mp->get_fileid(mp, fileid); if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mp get_fileid")) == TCL_OK) - res = Tcl_NewStringObj((char *)fileid, - (int)DB_FILE_ID_LEN); + res = NewStringObj((char *)fileid, DB_FILE_ID_LEN); break; case MPGETFTYPE: if (objc != 2) { @@ -564,7 +562,7 @@ mp_Cmd(clientData, interp, objc, objv) if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mp get_pgcookie")) == TCL_OK) res = Tcl_NewByteArrayObj((u_char *)cookie.data, - cookie.size); + (int)cookie.size); break; } /* @@ -663,7 +661,7 @@ tcl_MpGet(interp, objc, objv, mp, mpip) return (TCL_ERROR); } _debug_check(); - pgno = ipgno; + pgno = (db_pgno_t)ipgno; ret = mp->get(mp, &pgno, flag, &page); result = _ReturnSetup(interp, ret, DB_RETOK_MPGET(ret), "mpool get"); if (result == TCL_ERROR) @@ -678,9 +676,9 @@ tcl_MpGet(interp, objc, objv, mp, mpip) ip->i_pgno = pgno; ip->i_pgsz = mpip->i_pgsz; _SetInfoData(ip, page); - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)pg_Cmd, (ClientData)page, NULL); - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); } error: @@ -761,7 +759,7 @@ pg_Cmd(clientData, interp, objc, objv) case PGSET: case PGPUT: result = tcl_Pg(interp, objc, objv, page, mp, pgip, - cmdindex == PGSET ? 0 : 1); + (enum pgcmds)cmdindex == PGSET ? 0 : 1); break; case PGINIT: result = tcl_PgInit(interp, objc, objv, page, pgip); @@ -849,9 +847,8 @@ tcl_PgInit(interp, objc, objv, page, pgip) DBTCL_INFO *pgip; /* Info pointer */ { Tcl_Obj *res; - size_t pgsz; long *p, *endp, newval; - int length, result; + int length, pgsz, result; u_char *s; result = TCL_OK; @@ -866,12 +863,11 @@ tcl_PgInit(interp, objc, objv, page, pgip) s = Tcl_GetByteArrayFromObj(objv[2], &length); if (s == NULL) return (TCL_ERROR); - memcpy(page, s, - ((size_t)length < pgsz) ? (size_t)length : pgsz); + memcpy(page, s, (size_t)((length < pgsz) ? length : pgsz)); result = TCL_OK; } else { p = (long *)page; - for (endp = p + (pgsz / sizeof(long)); p < endp; p++) + for (endp = p + ((u_int)pgsz / sizeof(long)); p < endp; p++) *p = newval; } res = Tcl_NewIntObj(0); @@ -888,9 +884,8 @@ tcl_PgIsset(interp, objc, objv, page, pgip) DBTCL_INFO *pgip; /* Info pointer */ { Tcl_Obj *res; - size_t pgsz; long *p, *endp, newval; - int length, result; + int length, pgsz, result; u_char *s; result = TCL_OK; @@ -907,7 +902,7 @@ tcl_PgIsset(interp, objc, objv, page, pgip) result = TCL_OK; if (memcmp(page, s, - ((size_t)length < pgsz) ? (size_t)length : pgsz ) != 0) { + (size_t)((length < pgsz) ? length : pgsz)) != 0) { res = Tcl_NewIntObj(0); Tcl_SetObjResult(interp, res); return (result); @@ -919,7 +914,7 @@ tcl_PgIsset(interp, objc, objv, page, pgip) * this value). Otherwise, if we finish the loop, we return 1 * (is set to this value). */ - for (endp = p + (pgsz/sizeof(long)); p < endp; p++) + for (endp = p + ((u_int)pgsz / sizeof(long)); p < endp; p++) if (*p != newval) { res = Tcl_NewIntObj(0); Tcl_SetObjResult(interp, res); diff --git a/db/tcl/tcl_rep.c b/db/tcl/tcl_rep.c index 0d0fd30fd..8be4b196a 100644 --- a/db/tcl/tcl_rep.c +++ b/db/tcl/tcl_rep.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_rep.c,v 11.105 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_rep.c,v 11.93 2003/09/12 16:23:13 sue Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -22,7 +20,7 @@ static const char revid[] = "$Id: tcl_rep.c,v 11.93 2003/09/12 16:23:13 sue Exp #include "db_int.h" #include "dbinc/tcl_db.h" -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepElect -- * Call DB_ENV->rep_elect(). @@ -37,23 +35,26 @@ tcl_RepElect(interp, objc, objv, dbenv) Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *dbenv; /* Environment pointer */ { - int eid, nsites, pri, result, ret; + int eid, nsites, nvotes, pri, result, ret; u_int32_t timeout; - if (objc != 5) { - Tcl_WrongNumArgs(interp, 5, objv, "nsites pri timeout"); + if (objc != 6) { + Tcl_WrongNumArgs(interp, 6, objv, "nsites pri timeout"); return (TCL_ERROR); } if ((result = Tcl_GetIntFromObj(interp, objv[2], &nsites)) != TCL_OK) return (result); - if ((result = Tcl_GetIntFromObj(interp, objv[3], &pri)) != TCL_OK) + if ((result = Tcl_GetIntFromObj(interp, objv[3], &nvotes)) != TCL_OK) return (result); - if ((result = _GetUInt32(interp, objv[4], &timeout)) != TCL_OK) + if ((result = Tcl_GetIntFromObj(interp, objv[4], &pri)) != TCL_OK) + return (result); + if ((result = _GetUInt32(interp, objv[5], &timeout)) != TCL_OK) return (result); _debug_check(); - if ((ret = dbenv->rep_elect(dbenv, nsites, pri, timeout, &eid)) != 0) + if ((ret = dbenv->rep_elect(dbenv, nsites, nvotes, + pri, timeout, &eid, 0)) != 0) return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_elect")); @@ -63,7 +64,7 @@ tcl_RepElect(interp, objc, objv, dbenv) } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepFlush -- * Call DB_ENV->rep_flush(). @@ -90,7 +91,7 @@ tcl_RepFlush(interp, objc, objv, dbenv) return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_flush")); } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepLimit -- * Call DB_ENV->set_rep_limit(). @@ -128,7 +129,7 @@ tcl_RepLimit(interp, objc, objv, dbenv) } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepRequest -- * Call DB_ENV->set_rep_request(). @@ -166,7 +167,7 @@ tcl_RepRequest(interp, objc, objv, dbenv) } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepStart -- * Call DB_ENV->rep_start(). @@ -233,7 +234,7 @@ tcl_RepStart(interp, objc, objv, dbenv) } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepProcessMessage -- * Call DB_ENV->rep_process_message(). @@ -307,6 +308,7 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv) * {HOLDELECTION 0} - HOLDELECTION, no other info needed. * {NEWMASTER #} - NEWMASTER and its ID. * {NEWSITE 0} - NEWSITE, no other info needed. + * {STARTUPDONE 0} - STARTUPDONE, no other info needed. * {ISPERM {LSN list}} - ISPERM and the perm LSN. * {NOTPERM {LSN list}} - NOTPERM and this msg's LSN. */ @@ -317,38 +319,46 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv) myobjv[1] = Tcl_NewIntObj(0); break; case DB_REP_DUPMASTER: - myobjv[0] = Tcl_NewByteArrayObj("DUPMASTER", - strlen("DUPMASTER")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"DUPMASTER", (int)strlen("DUPMASTER")); myobjv[1] = Tcl_NewIntObj(0); break; case DB_REP_HOLDELECTION: - myobjv[0] = Tcl_NewByteArrayObj("HOLDELECTION", - strlen("HOLDELECTION")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"HOLDELECTION", (int)strlen("HOLDELECTION")); myobjv[1] = Tcl_NewIntObj(0); break; case DB_REP_ISPERM: myobjv[0] = Tcl_NewLongObj((long)permlsn.file); myobjv[1] = Tcl_NewLongObj((long)permlsn.offset); lsnlist = Tcl_NewListObj(myobjc, myobjv); - myobjv[0] = Tcl_NewByteArrayObj("ISPERM", strlen("ISPERM")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"ISPERM", (int)strlen("ISPERM")); myobjv[1] = lsnlist; break; case DB_REP_NEWMASTER: - myobjv[0] = Tcl_NewByteArrayObj("NEWMASTER", - strlen("NEWMASTER")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"NEWMASTER", (int)strlen("NEWMASTER")); myobjv[1] = Tcl_NewIntObj(eid); break; case DB_REP_NEWSITE: - myobjv[0] = Tcl_NewByteArrayObj("NEWSITE", strlen("NEWSITE")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"NEWSITE", (int)strlen("NEWSITE")); myobjv[1] = Tcl_NewIntObj(0); break; case DB_REP_NOTPERM: myobjv[0] = Tcl_NewLongObj((long)permlsn.file); myobjv[1] = Tcl_NewLongObj((long)permlsn.offset); lsnlist = Tcl_NewListObj(myobjc, myobjv); - myobjv[0] = Tcl_NewByteArrayObj("NOTPERM", strlen("NOTPERM")); + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"NOTPERM", (int)strlen("NOTPERM")); myobjv[1] = lsnlist; break; + case DB_REP_STARTUPDONE: + myobjv[0] = Tcl_NewByteArrayObj( + (u_char *)"STARTUPDONE", (int)strlen("STARTUPDONE")); + myobjv[1] = Tcl_NewIntObj(0); + break; default: msg = db_strerror(ret); Tcl_AppendResult(interp, msg, NULL); @@ -361,15 +371,15 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv) Tcl_SetObjResult(interp, res); out: if (freectl) - (void)__os_free(NULL, ctmp); + __os_free(NULL, ctmp); if (freerec) - (void)__os_free(NULL, rtmp); + __os_free(NULL, rtmp); return (result); } #endif -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_RepStat -- * Call DB_ENV->rep_stat(). @@ -423,13 +433,18 @@ tcl_RepStat(interp, objc, objv, dbenv) /* * MAKE_STAT_* assumes 'res' and 'error' label. */ + if (sp->st_status == DB_REP_MASTER) + MAKE_STAT_LIST("Master", 1); + else + MAKE_STAT_LIST("Client", 1); MAKE_STAT_LSN("Next LSN expected", &sp->st_next_lsn); MAKE_STAT_LSN("First missed LSN", &sp->st_waiting_lsn); MAKE_STAT_LIST("Duplicate master conditions", sp->st_dupmasters); MAKE_STAT_LIST("Environment ID", sp->st_env_id); MAKE_STAT_LIST("Environment priority", sp->st_env_priority); MAKE_STAT_LIST("Generation number", sp->st_gen); - MAKE_STAT_LIST("In recovery", sp->st_in_recovery); + MAKE_STAT_LIST("Election generation number", sp->st_egen); + MAKE_STAT_LIST("Startup complete", sp->st_startup_complete); MAKE_STAT_LIST("Duplicate log records received", sp->st_log_duplicated); MAKE_STAT_LIST("Current log records queued", sp->st_log_queued); MAKE_STAT_LIST("Maximum log records queued", sp->st_log_queued_max); @@ -445,9 +460,15 @@ tcl_RepStat(interp, objc, objv, dbenv) MAKE_STAT_LIST("Message send failures", sp->st_msgs_send_failures); MAKE_STAT_LIST("Messages sent", sp->st_msgs_sent); MAKE_STAT_LIST("New site messages", sp->st_newsites); + MAKE_STAT_LIST("Number of sites in replication group", sp->st_nsites); MAKE_STAT_LIST("Transmission limited", sp->st_nthrottles); MAKE_STAT_LIST("Outdated conditions", sp->st_outdated); MAKE_STAT_LIST("Transactions applied", sp->st_txns_applied); + MAKE_STAT_LIST("Next page expected", sp->st_next_pg); + MAKE_STAT_LIST("First missed page", sp->st_waiting_pg); + MAKE_STAT_LIST("Duplicate pages received", sp->st_pg_duplicated); + MAKE_STAT_LIST("Pages received", sp->st_pg_records); + MAKE_STAT_LIST("Pages requested", sp->st_pg_requested); MAKE_STAT_LIST("Elections held", sp->st_elections); MAKE_STAT_LIST("Elections won", sp->st_elections_won); MAKE_STAT_LIST("Election phase", sp->st_election_status); @@ -455,13 +476,14 @@ tcl_RepStat(interp, objc, objv, dbenv) MAKE_STAT_LIST("Election generation number", sp->st_election_gen); MAKE_STAT_LSN("Election max LSN", &sp->st_election_lsn); MAKE_STAT_LIST("Election sites", sp->st_election_nsites); + MAKE_STAT_LIST("Election votes", sp->st_election_nvotes); MAKE_STAT_LIST("Election priority", sp->st_election_priority); MAKE_STAT_LIST("Election tiebreaker", sp->st_election_tiebreaker); MAKE_STAT_LIST("Election votes", sp->st_election_votes); Tcl_SetObjResult(interp, res); error: - (void)__os_ufree(dbenv, sp); + __os_ufree(dbenv, sp); return (result); } #endif diff --git a/db/tcl/tcl_seq.c b/db/tcl/tcl_seq.c new file mode 100644 index 000000000..6742a0713 --- /dev/null +++ b/db/tcl/tcl_seq.c @@ -0,0 +1,526 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2004 + * Sleepycat Software. All rights reserved. + * + * $Id: tcl_seq.c,v 11.11 2004/09/22 22:20:35 mjc Exp $ + */ + +#include "db_config.h" + +#ifdef HAVE_SEQUENCE +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <string.h> +#include <tcl.h> +#endif + +#include "db_int.h" +#include "dbinc/tcl_db.h" +#include "dbinc_auto/sequence_ext.h" + +/* + * Prototypes for procedures defined later in this file: + */ +static int tcl_SeqClose __P((Tcl_Interp *, + int, Tcl_Obj * CONST*, DB_SEQUENCE *, DBTCL_INFO *)); +static int tcl_SeqGet __P((Tcl_Interp *, + int, Tcl_Obj * CONST*, DB_SEQUENCE *)); +static int tcl_SeqRemove __P((Tcl_Interp *, + int, Tcl_Obj * CONST*, DB_SEQUENCE *, DBTCL_INFO *)); +static int tcl_SeqStat __P((Tcl_Interp *, + int, Tcl_Obj * CONST*, DB_SEQUENCE *)); +static int tcl_SeqGetFlags __P((Tcl_Interp *, + int, Tcl_Obj * CONST*, DB_SEQUENCE *)); + +/* + * + * PUBLIC: int seq_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); + * + * seq_Cmd -- + * Implements the "seq" widget. + */ +int +seq_Cmd(clientData, interp, objc, objv) + ClientData clientData; /* SEQ handle */ + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ +{ + static const char *seqcmds[] = { + "close", + "get", + "get_cachesize", + "get_db", + "get_flags", + "get_key", + "get_range", + "remove", + "stat", + NULL + }; + enum seqcmds { + SEQCLOSE, + SEQGET, + SEQGETCACHESIZE, + SEQGETDB, + SEQGETFLAGS, + SEQGETKEY, + SEQGETRANGE, + SEQREMOVE, + SEQSTAT + }; + DB *dbp; + DBT key; + DBTCL_INFO *dbip, *ip; + DB_SEQUENCE *seq; + Tcl_Obj *myobjv[2], *res; + db_seq_t min, max; + int cmdindex, ncache, result, ret; + + Tcl_ResetResult(interp); + seq = (DB_SEQUENCE *)clientData; + result = TCL_OK; + dbip = NULL; + if (objc <= 1) { + Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs"); + return (TCL_ERROR); + } + if (seq == NULL) { + Tcl_SetResult(interp, "NULL sequence pointer", TCL_STATIC); + return (TCL_ERROR); + } + + ip = _PtrToInfo((void *)seq); + if (ip == NULL) { + Tcl_SetResult(interp, "NULL info pointer", TCL_STATIC); + return (TCL_ERROR); + } + + /* + * Get the command name index from the object based on the dbcmds + * defined above. + */ + if (Tcl_GetIndexFromObj(interp, + objv[1], seqcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK) + return (IS_HELP(objv[1])); + + res = NULL; + switch ((enum seqcmds)cmdindex) { + case SEQGETRANGE: + ret = seq->get_range(seq, &min, &max); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "sequence get_range")) == TCL_OK) { + myobjv[0] = Tcl_NewWideIntObj(min); + myobjv[1] = Tcl_NewWideIntObj(max); + res = Tcl_NewListObj(2, myobjv); + } + break; + case SEQCLOSE: + result = tcl_SeqClose(interp, objc, objv, seq, ip); + break; + case SEQREMOVE: + result = tcl_SeqRemove(interp, objc, objv, seq, ip); + break; + case SEQGET: + result = tcl_SeqGet(interp, objc, objv, seq); + break; + case SEQSTAT: + result = tcl_SeqStat(interp, objc, objv, seq); + break; + case SEQGETCACHESIZE: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = seq->get_cachesize(seq, &ncache); + if ((result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "sequence get_cachesize")) == TCL_OK) + res = Tcl_NewIntObj(ncache); + break; + case SEQGETDB: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = seq->get_db(seq, &dbp); + if (ret == 0 && (dbip = _PtrToInfo((void *)dbp)) == NULL) { + Tcl_SetResult(interp, + "NULL db info pointer", TCL_STATIC); + return (TCL_ERROR); + } + + if ((result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "sequence get_db")) == TCL_OK) + res = NewStringObj(dbip->i_name, strlen(dbip->i_name)); + break; + case SEQGETKEY: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = seq->get_key(seq, &key); + if ((result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "sequence get_key")) == TCL_OK) + res = Tcl_NewByteArrayObj( + (u_char *)key.data, (int)key.size); + break; + case SEQGETFLAGS: + result = tcl_SeqGetFlags(interp, objc, objv, seq); + break; + } + + /* + * Only set result if we have a res. Otherwise, lower functions have + * already done so. + */ + if (result == TCL_OK && res) + Tcl_SetObjResult(interp, res); + return (result); +} + +/* + * tcl_db_stat -- + */ +static int +tcl_SeqStat(interp, objc, objv, seq) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DB_SEQUENCE *seq; /* Database pointer */ +{ + DB_SEQUENCE_STAT *sp; + u_int32_t flag; + Tcl_Obj *res, *flaglist, *myobjv[2]; + int result, ret; + char *arg; + + result = TCL_OK; + flag = 0; + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?-clear?"); + return (TCL_ERROR); + } + + if (objc == 3) { + arg = Tcl_GetStringFromObj(objv[2], NULL); + if (strcmp(arg, "-clear") == 0) + flag = DB_STAT_CLEAR; + else { + Tcl_SetResult(interp, + "db stat: unknown arg", TCL_STATIC); + return (TCL_ERROR); + } + } + + _debug_check(); + ret = seq->stat(seq, &sp, flag); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db stat"); + if (result == TCL_ERROR) + return (result); + + res = Tcl_NewObj(); + MAKE_STAT_LIST("Wait", sp->st_wait); + MAKE_STAT_LIST("No wait", sp->st_nowait); + MAKE_WSTAT_LIST("Current", sp->st_current); + MAKE_WSTAT_LIST("Cached", sp->st_value); + MAKE_WSTAT_LIST("Max Cached", sp->st_last_value); + MAKE_WSTAT_LIST("Min", sp->st_min); + MAKE_WSTAT_LIST("Max", sp->st_max); + MAKE_STAT_LIST("Cache size", sp->st_cache_size); + /* + * Construct a {name {flag1 flag2 ... flagN}} list for the + * seq flags. + */ + myobjv[0] = NewStringObj("Flags", strlen("Flags")); + myobjv[1] = + _GetFlagsList(interp, sp->st_flags, __db_get_seq_flags_fn()); + flaglist = Tcl_NewListObj(2, myobjv); + if (flaglist == NULL) { + result = TCL_ERROR; + goto error; + } + if ((result = + Tcl_ListObjAppendElement(interp, res, flaglist)) != TCL_OK) + goto error; + + Tcl_SetObjResult(interp, res); + +error: __os_ufree(seq->seq_dbp->dbenv, sp); + return (result); +} + +/* + * tcl_db_close -- + */ +static int +tcl_SeqClose(interp, objc, objv, seq, ip) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DB_SEQUENCE *seq; /* Database pointer */ + DBTCL_INFO *ip; /* Info pointer */ +{ + int result, ret; + + result = TCL_OK; + if (objc > 2) { + Tcl_WrongNumArgs(interp, 2, objv, ""); + return (TCL_ERROR); + } + + _DeleteInfo(ip); + _debug_check(); + + ret = seq->close(seq, 0); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "sequence close"); + return (result); +} + +/* + * tcl_SeqGet -- + */ +static int +tcl_SeqGet(interp, objc, objv, seq) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DB_SEQUENCE *seq; /* Sequence pointer */ +{ + static const char *seqgetopts[] = { + "-auto_commit", + "-nosync", + "-txn", + NULL + }; + enum seqgetopts { + SEQGET_AUTO_COMMIT, + SEQGET_NOSYNC, + SEQGET_TXN + }; + DB_TXN *txn; + Tcl_Obj *res; + db_seq_t value; + u_int32_t aflag, delta; + int i, end, optindex, result, ret; + char *arg, msg[MSG_SIZE]; + + result = TCL_OK; + txn = NULL; + aflag = 0; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?-args? delta"); + return (TCL_ERROR); + } + + /* + * Get the command name index from the object based on the options + * defined above. + */ + i = 2; + end = objc; + while (i < end) { + if (Tcl_GetIndexFromObj(interp, objv[i], seqgetopts, "option", + TCL_EXACT, &optindex) != TCL_OK) { + arg = Tcl_GetStringFromObj(objv[i], NULL); + if (arg[0] == '-') { + result = IS_HELP(objv[i]); + goto out; + } else + Tcl_ResetResult(interp); + break; + } + i++; + switch ((enum seqgetopts)optindex) { + case SEQGET_AUTO_COMMIT: + aflag |= DB_AUTO_COMMIT; + break; + case SEQGET_NOSYNC: + aflag |= DB_TXN_NOSYNC; + break; + case SEQGET_TXN: + if (i >= end) { + Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?"); + result = TCL_ERROR; + break; + } + arg = Tcl_GetStringFromObj(objv[i++], NULL); + txn = NAME_TO_TXN(arg); + if (txn == NULL) { + snprintf(msg, MSG_SIZE, + "Get: Invalid txn: %s\n", arg); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + result = TCL_ERROR; + } + break; + } /* switch */ + if (result != TCL_OK) + break; + } + if (result != TCL_OK) + goto out; + + if (i != objc - 1) { + Tcl_SetResult(interp, + "Wrong number of key/data given\n", TCL_STATIC); + result = TCL_ERROR; + goto out; + } + + if ((result = _GetUInt32(interp, objv[objc - 1], &delta)) != TCL_OK) + goto out; + + ret = seq->get(seq, txn, (int32_t)delta, &value, aflag); + result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret), "sequence get"); + if (ret == 0) { + res = Tcl_NewWideIntObj((Tcl_WideInt)value); + Tcl_SetObjResult(interp, res); + } +out: + return (result); +} +/* + */ +static int +tcl_SeqRemove(interp, objc, objv, seq, ip) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DB_SEQUENCE *seq; /* Sequence pointer */ + DBTCL_INFO *ip; /* Info pointer */ +{ + static const char *seqgetopts[] = { + "-auto_commit", + "-nosync", + "-txn", + NULL + }; + enum seqgetopts { + SEQGET_AUTO_COMMIT, + SEQGET_NOSYNC, + SEQGET_TXN + }; + DB_TXN *txn; + u_int32_t aflag; + int i, end, optindex, result, ret; + char *arg, msg[MSG_SIZE]; + + result = TCL_OK; + txn = NULL; + aflag = 0; + + _DeleteInfo(ip); + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?-args?"); + return (TCL_ERROR); + } + + /* + * Get the command name index from the object based on the options + * defined above. + */ + i = 2; + end = objc; + while (i < end) { + if (Tcl_GetIndexFromObj(interp, objv[i], seqgetopts, "option", + TCL_EXACT, &optindex) != TCL_OK) { + arg = Tcl_GetStringFromObj(objv[i], NULL); + if (arg[0] == '-') { + result = IS_HELP(objv[i]); + goto out; + } else + Tcl_ResetResult(interp); + break; + } + i++; + switch ((enum seqgetopts)optindex) { + case SEQGET_AUTO_COMMIT: + aflag |= DB_AUTO_COMMIT; + break; + case SEQGET_NOSYNC: + aflag |= DB_TXN_NOSYNC; + break; + case SEQGET_TXN: + if (i >= end) { + Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?"); + result = TCL_ERROR; + break; + } + arg = Tcl_GetStringFromObj(objv[i++], NULL); + txn = NAME_TO_TXN(arg); + if (txn == NULL) { + snprintf(msg, MSG_SIZE, + "Remove: Invalid txn: %s\n", arg); + Tcl_SetResult(interp, msg, TCL_VOLATILE); + result = TCL_ERROR; + } + break; + } /* switch */ + if (result != TCL_OK) + break; + } + if (result != TCL_OK) + goto out; + + ret = seq->remove(seq, txn, aflag); + result = _ReturnSetup(interp, + ret, DB_RETOK_DBGET(ret), "sequence remove"); +out: + return (result); +} + +/* + * tcl_SeqGetFlags -- + */ +static int +tcl_SeqGetFlags(interp, objc, objv, seq) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* How many arguments? */ + Tcl_Obj *CONST objv[]; /* The argument objects */ + DB_SEQUENCE *seq; /* Sequence pointer */ +{ + int i, ret, result; + u_int32_t flags; + char buf[512]; + Tcl_Obj *res; + + static const struct { + u_int32_t flag; + char *arg; + } seq_flags[] = { + { DB_SEQ_INC, "-inc" }, + { DB_SEQ_DEC, "-dec" }, + { DB_SEQ_WRAP, "-wrap" }, + { 0, NULL } + }; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + + ret = seq->get_flags(seq, &flags); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "db get_flags")) == TCL_OK) { + buf[0] = '\0'; + + for (i = 0; seq_flags[i].flag != 0; i++) + if (LF_ISSET(seq_flags[i].flag)) { + if (strlen(buf) > 0) + (void)strncat(buf, " ", sizeof(buf)); + (void)strncat( + buf, seq_flags[i].arg, sizeof(buf)); + } + + res = NewStringObj(buf, strlen(buf)); + Tcl_SetObjResult(interp, res); + } + + return (result); +} +#endif diff --git a/db/tcl/tcl_txn.c b/db/tcl/tcl_txn.c index 5686b7192..87c9d3667 100644 --- a/db/tcl/tcl_txn.c +++ b/db/tcl/tcl_txn.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_txn.c,v 11.69 2004/10/07 16:48:39 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_txn.c,v 11.63 2003/04/24 16:25:54 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -48,7 +46,7 @@ _TxnInfoDelete(interp, txnip) * txn. Remove its commands and info structure. */ nextp = LIST_NEXT(p, entries); - if (p->i_parent == txnip && p->i_type == I_TXN) { + if (p->i_parent == txnip && p->i_type == I_TXN) { _TxnInfoDelete(interp, p); (void)Tcl_DeleteCommand(interp, p->i_name); _DeleteInfo(p); @@ -143,7 +141,8 @@ tcl_Txn(interp, objc, objv, envp, envip) DBTCL_INFO *envip; /* Info pointer */ { static const char *txnopts[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST + "-degree_2", "-dirty", "-lock_timeout", "-txn_timeout", @@ -155,7 +154,8 @@ tcl_Txn(interp, objc, objv, envp, envip) NULL }; enum txnopts { -#if CONFIG_TEST +#ifdef CONFIG_TEST + TXNDEGREE2, TXNDIRTY, TXN_LOCK_TIMEOUT, TXN_TIMEOUT, @@ -172,7 +172,7 @@ tcl_Txn(interp, objc, objv, envp, envip) u_int32_t flag; int i, optindex, result, ret; char *arg, msg[MSG_SIZE], newname[MSG_SIZE]; -#if CONFIG_TEST +#ifdef CONFIG_TEST db_timeout_t lk_time, tx_time; u_int32_t lk_timeflag, tx_timeflag; #endif @@ -182,7 +182,9 @@ tcl_Txn(interp, objc, objv, envp, envip) parent = NULL; flag = 0; -#if CONFIG_TEST +#ifdef CONFIG_TEST + COMPQUIET(tx_time, 0); + COMPQUIET(lk_time, 0); lk_timeflag = tx_timeflag = 0; #endif i = 2; @@ -194,6 +196,9 @@ tcl_Txn(interp, objc, objv, envp, envip) i++; switch ((enum txnopts)optindex) { #ifdef CONFIG_TEST + case TXNDEGREE2: + flag |= DB_DEGREE_2; + break; case TXNDIRTY: flag |= DB_DIRTY_READ; break; @@ -202,14 +207,13 @@ tcl_Txn(interp, objc, objv, envp, envip) goto getit; case TXN_TIMEOUT: tx_timeflag = DB_SET_TXN_TIMEOUT; -getit: - if (i >= objc) { +getit: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, "?-txn_timestamp time?"); return (TCL_ERROR); } - result = Tcl_GetLongFromObj(interp, objv[i++], - (long *)(optindex == TXN_LOCK_TIMEOUT ? + result = Tcl_GetLongFromObj(interp, objv[i++], (long *) + ((enum txnopts)optindex == TXN_LOCK_TIMEOUT ? &lk_time : &tx_time)); if (result != TCL_OK) return (TCL_ERROR); @@ -271,11 +275,11 @@ getit: else ip->i_parent = envip; _SetInfoData(ip, txn); - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)txn, NULL); - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); -#if CONFIG_TEST +#ifdef CONFIG_TEST if (tx_timeflag != 0) { ret = txn->set_timeout(txn, tx_time, tx_timeflag); if (ret != 0) { @@ -373,7 +377,7 @@ tcl_TxnStat(interp, objc, objv, envp) } Tcl_SetObjResult(interp, res); error: - (void)__os_ufree(envp, sp); + __os_ufree(envp, sp); return (result); } @@ -422,7 +426,7 @@ txn_Cmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* The argument objects */ { static const char *txncmds[] = { -#if CONFIG_TEST +#ifdef CONFIG_TEST "discard", "id", "prepare", @@ -432,7 +436,7 @@ txn_Cmd(clientData, interp, objc, objv) NULL }; enum txncmds { -#if CONFIG_TEST +#ifdef CONFIG_TEST TXNDISCARD, TXNID, TXNPREPARE, @@ -443,8 +447,9 @@ txn_Cmd(clientData, interp, objc, objv) DBTCL_INFO *txnip; DB_TXN *txnp; Tcl_Obj *res; + u_int32_t tid; int cmdindex, result, ret; -#if CONFIG_TEST +#ifdef CONFIG_TEST u_int8_t *gid; #endif @@ -471,7 +476,7 @@ txn_Cmd(clientData, interp, objc, objv) res = NULL; switch ((enum txncmds)cmdindex) { -#if CONFIG_TEST +#ifdef CONFIG_TEST case TXNDISCARD: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); @@ -491,8 +496,8 @@ txn_Cmd(clientData, interp, objc, objv) return (TCL_ERROR); } _debug_check(); - ret = txnp->id(txnp); - res = Tcl_NewIntObj(ret); + tid = txnp->id(txnp); + res = Tcl_NewIntObj((int)tid); break; case TXNPREPARE: if (objc != 3) { @@ -594,7 +599,7 @@ tcl_TxnCommit(interp, objc, objv, txnp, txnip) return (result); } -#if CONFIG_TEST +#ifdef CONFIG_TEST /* * tcl_TxnRecover -- * @@ -623,7 +628,7 @@ for (i = 0; i < count; i++) { \ ip->i_parent = envip; \ p = &prep[i]; \ _SetInfoData(ip, p->txn); \ - Tcl_CreateObjCommand(interp, newname, \ + (void)Tcl_CreateObjCommand(interp, newname, \ (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)p->txn, NULL); \ result = _SetListElem(interp, res, newname, strlen(newname), \ p->gid, DB_XIDDATASIZE); \ diff --git a/db/tcl/tcl_util.c b/db/tcl/tcl_util.c index 08b169cd9..13a6d6a9d 100644 --- a/db/tcl/tcl_util.c +++ b/db/tcl/tcl_util.c @@ -1,16 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999-2003 + * Copyright (c) 1999-2004 * Sleepycat Software. All rights reserved. + * + * $Id: tcl_util.c,v 11.43 2004/06/10 17:20:57 bostic Exp $ */ #include "db_config.h" -#ifndef lint -static const char revid[] = "$Id: tcl_util.c,v 11.38 2003/04/23 18:54:40 bostic Exp $"; -#endif /* not lint */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> @@ -47,10 +45,8 @@ bdb_RandCommand(interp, objc, objv) enum rcmds { RRAND, RRAND_INT, RSRAND }; - long t; - int cmdindex, hi, lo, result, ret; Tcl_Obj *res; - char msg[MSG_SIZE]; + int cmdindex, hi, lo, result, ret; result = TCL_OK; /* @@ -83,29 +79,21 @@ bdb_RandCommand(interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "lo hi"); return (TCL_ERROR); } - result = Tcl_GetIntFromObj(interp, objv[2], &lo); - if (result != TCL_OK) - break; - result = Tcl_GetIntFromObj(interp, objv[3], &hi); - if (result == TCL_OK) { -#ifndef RAND_MAX -#define RAND_MAX 0x7fffffff -#endif - t = rand(); - if (t > RAND_MAX) { - snprintf(msg, MSG_SIZE, - "Max random is higher than %ld\n", - (long)RAND_MAX); - Tcl_SetResult(interp, msg, TCL_VOLATILE); - result = TCL_ERROR; - break; - } - _debug_check(); - ret = (int)(((double)t / ((double)(RAND_MAX) + 1)) * - (hi - lo + 1)); - ret += lo; - res = Tcl_NewIntObj(ret); + if ((result = + Tcl_GetIntFromObj(interp, objv[2], &lo)) != TCL_OK) + return (result); + if ((result = + Tcl_GetIntFromObj(interp, objv[3], &hi)) != TCL_OK) + return (result); + if (lo < 0 || hi < 0) { + Tcl_SetResult(interp, + "Range value less than 0", TCL_STATIC); + return (TCL_ERROR); } + + _debug_check(); + ret = lo + rand() % ((hi - lo) + 1); + res = Tcl_NewIntObj(ret); break; case RSRAND: /* @@ -115,16 +103,17 @@ bdb_RandCommand(interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "seed"); return (TCL_ERROR); } - result = Tcl_GetIntFromObj(interp, objv[2], &lo); - if (result == TCL_OK) { + if ((result = + Tcl_GetIntFromObj(interp, objv[2], &lo)) == TCL_OK) { srand((u_int)lo); res = Tcl_NewIntObj(0); } break; } + /* - * Only set result if we have a res. Otherwise, lower - * functions have already done so. + * Only set result if we have a res. Otherwise, lower functions have + * already done so. */ if (result == TCL_OK && res) Tcl_SetObjResult(interp, res); @@ -150,13 +139,12 @@ tcl_Mutex(interp, objc, objv, envp, envip) DBTCL_INFO *ip; Tcl_Obj *res; _MUTEX_DATA *md; - int i, mode, nitems, result, ret; + int i, nitems, mode, result, ret; char newname[MSG_SIZE]; md = NULL; result = TCL_OK; - mode = nitems = ret = 0; - memset(newname, 0, MSG_SIZE); + ret = 0; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "mode nitems"); @@ -169,6 +157,7 @@ tcl_Mutex(interp, objc, objv, envp, envip) if (result != TCL_OK) return (TCL_ERROR); + memset(newname, 0, MSG_SIZE); snprintf(newname, sizeof(newname), "%s.mutex%d", envip->i_name, envip->i_envmutexid); ip = _NewInfo(interp, NULL, newname, I_MUTEX); @@ -192,12 +181,11 @@ tcl_Mutex(interp, objc, objv, envp, envip) if (__os_calloc(NULL, 1, sizeof(_MUTEX_DATA), &md) != 0) goto posixout; md->env = envp; - md->n_mutex = nitems; - md->size = sizeof(_MUTEX_ENTRY) * nitems; + md->size = sizeof(_MUTEX_ENTRY) * (u_int)nitems; + md->reginfo.dbenv = envp; md->reginfo.type = REGION_TYPE_MUTEX; - md->reginfo.id = INVALID_REGION_TYPE; - md->reginfo.mode = mode; + md->reginfo.id = INVALID_REGION_ID; md->reginfo.flags = REGION_CREATE_OK | REGION_JOIN_OK; if ((ret = __db_r_attach(envp, &md->reginfo, md->size)) != 0) goto posixout; @@ -220,16 +208,16 @@ tcl_Mutex(interp, objc, objv, envp, envip) envip->i_envmutexid++; ip->i_parent = envip; _SetInfoData(ip, md); - Tcl_CreateObjCommand(interp, newname, + (void)Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)mutex_Cmd, (ClientData)md, NULL); - res = Tcl_NewStringObj(newname, strlen(newname)); + res = NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); return (TCL_OK); posixout: if (ret > 0) - Tcl_PosixError(interp); + (void)Tcl_PosixError(interp); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mutex"); _DeleteInfo(ip); |