[5289] in Athena Bugs

home help back first fref pref prev next nref lref last post

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

home help back first fref pref prev next nref lref last post