[5289] in Athena Bugs
ndbm doesn't emulate dbm correctly
daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Tue Jun 26 13:56:46 1990
Date: Tue, 26 Jun 90 13:56:31 -0400
From: Jonathan I. Kamens <jik@pit-manager.MIT.EDU>
To: bugs@ATHENA.MIT.EDU
In article <7453@gollum.twg.com>, dwh@twg.com (Dave W. Hamaker) writes:
|> The dbm(3x) data base subroutines, as rewritten to use ndbm(3x), contain
|> the call: dbm_nextkey(cur_db, key). However, the dbm_nextkey function does
|> not take two parameters; it takes a single parameter.
|>
|> On a Vax, the result of this discrepancy is that the second parameter is
|> ignored, which is consistent with the way the ndbm subroutines are designed
|> to operate. It is not consistent with the way the old dbm
subroutines worked
|> and introduces a subtle change in the semantics of the nextkey() function:
|> the old version could handle two or more interleaved nextkey() scans
|> simultaneously; and could even cope with dbinit()'s of other databases,
|> followed by a dbinit() back to the original, between nextkey() calls.
|>
|> Most software is unlikely to be affected by this change in semantics;
|> certainly no program which does straight-forward access to a single
|> database is likely to care. However, we have encountered a major piece
|> of software which is impacted by the change. As a consequence, we have
|> made the changes which follow to dbm and ndbm, and offer them for the
|> consideration by Berkeley CSRG. The changes add a feature to ndbm for
|> internal use by the dbm routines which allows dbm_fetch() to have the
|> (optional) side-effect of setting the dbm_nextkey() pointers. The dbm
|> nextkey() function is then changed to use this feature (and to call
|> dbm_nextkey() with one parameter).
|>
|> -Dave Hamaker
|> Senior Software Engineer
|> The Wollongong Group
|> dwh@twg.com
|> ...!ucbvax!sun!amdahl!twg-ap!dwh
|>
|>
|> *** /usr/src/usr.lib/libdbm/dbm.c dbm.c 5.3 (Berkeley) 85/08/15
|> --- dbm.c Tue Apr 24 13:17:02 1990
|> ***************
|> *** 105,109 ****
|> item.dptr = 0;
|> return (item);
|> }
|> ! return (dbm_nextkey(cur_db, key));
|> }
|> --- 105,112 ----
|> item.dptr = 0;
|> return (item);
|> }
|> ! cur_db->dbm_flags |= _DBM_FETCH_AND_SET;
|> ! (void) dbm_fetch(cur_db, key);
|> ! cur_db->dbm_flags &= ~_DBM_FETCH_AND_SET;
|> ! return (dbm_nextkey(cur_db));
|> }
|>
|>
|> *** /usr/src/include/ndbm.h ndbm.h 5.1 (Berkeley) 5/30/85
|> --- ndbm.h Tue Apr 24 13:05:54 1990
|> ***************
|> *** 28,39 ****
|> char dbm_dirbuf[DBLKSIZ]; /* directory file block buffer */
|> } DBM;
|>
|> ! #define _DBM_RDONLY 0x1 /* data base open read-only */
|> ! #define _DBM_IOERR 0x2 /* data base I/O error */
|>
|> #define dbm_rdonly(db) ((db)->dbm_flags & _DBM_RDONLY)
|>
|> #define dbm_error(db) ((db)->dbm_flags & _DBM_IOERR)
|> /* use this one at your own risk! */
|> #define dbm_clearerr(db) ((db)->dbm_flags &= ~_DBM_IOERR)
|>
|> --- 28,43 ----
|> char dbm_dirbuf[DBLKSIZ]; /* directory file block buffer */
|> } DBM;
|>
|> ! #define _DBM_RDONLY 0x1 /* data base open read-only */
|> ! #define _DBM_IOERR 0x2 /* data base I/O error */
|> ! #define _DBM_FETCH_AND_SET 0x4 /* used by old dbm to preserve */
|> ! /* old nextkey() semantics */
|>
|> #define dbm_rdonly(db) ((db)->dbm_flags & _DBM_RDONLY)
|>
|> #define dbm_error(db) ((db)->dbm_flags & _DBM_IOERR)
|> +
|> + #define dbm_fetch_and_set(db) ((db)->dbm_flags & _DBM_FETCH_AND_SET)
|> /* use this one at your own risk! */
|> #define dbm_clearerr(db) ((db)->dbm_flags &= ~_DBM_IOERR)
|>
|>
|>
|> *** /usr/src/lib/libc/gen/ndbm.c ndbm.c 5.4 (Berkeley) 9/4/87
|> --- ndbm.c Tue Apr 24 13:30:57 1990
|> ***************
|> *** 99,106 ****
|> dbm_access(db, dcalchash(key));
|> if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) {
|> item = makdatum(db->dbm_pagbuf, i+1);
|> ! if (item.dptr != NULL)
|> return (item);
|> }
|> err:
|> item.dptr = NULL;
|> --- 99,111 ----
|> dbm_access(db, dcalchash(key));
|> if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) {
|> item = makdatum(db->dbm_pagbuf, i+1);
|> ! if (item.dptr != NULL) {
|> ! if (dbm_fetch_and_set(db)) {
|> ! db->dbm_blkptr = db->dbm_pagbno;
|> ! db->dbm_keyptr = i + 3;
|> ! }
|> return (item);
|> + }
|> }
|> err:
|> item.dptr = NULL;
Jonathan Kamens USnail:
MIT Project Athena 11 Ashford Terrace
jik@Athena.MIT.EDU Allston, MA 02134
Office: 617-253-8495 Home: 617-782-0710