[comp.bugs.4bsd] ndbm

ed@mtxinu.UUCP (04/25/87)

From: ed (Ed Gould)

Description:
	The new database library, ndbm(3), does not implement all of
	the functionality of the dbm(3) library that it superceded.
	Now that dbm is implemented by calling ndbm, some things no
	longer work reliably.

Repeat-By:
	Inspect the code.  In dbm.c, function nextkey(key) calls
	dbm_nextkey(cur_db, key).  The declaration of dbm_nextkey()
	in ndbm.c takes only one parameter.  Thus, the successor of
	a specified key may not be generated.

	If one process - a Yellow Pages server for example - is doing
	successor lookups for randomly-ordered requests, some of the
	lookups will return incorrect successors.

Fix:
	Apply the following diffs to ndbm.c and dbm.c.  A new
	function, dbm_do_nextkey() is declared to do the work that
	dbm_nextkey is documented to do; dbm_nextkey now calls
	dbm_do_nextkey with a null key.  Nextkey() calls dbm_do_nextkey()
	directly.

	*** /usr/src/lib/libc/gen/ndbm.c	Mon Aug 18 19:37:04 1986
	--- ndbm.c	Fri Apr 24 15:25:12 1987
	***************
	*** 214,238 ****
	  }
	  
	  datum
	! dbm_firstkey(db)
	! 	DBM *db;
	! {
	! 
	! 	db->dbm_blkptr = 0L;
	! 	db->dbm_keyptr = 0;
	! 	return (dbm_nextkey(db));
	! }
	! 
	! datum
	! dbm_nextkey(db)
		register DBM *db;
	  {
		struct stat statb;
		datum item;
	  
		if (dbm_error(db) || fstat(db->dbm_pagf, &statb) < 0)
			goto err;
		statb.st_size /= PBLKSIZ;
		for (;;) {
			if (db->dbm_blkptr != db->dbm_pagbno) {
				db->dbm_pagbno = db->dbm_blkptr;
	--- 214,235 ----
	  }
	  
	  datum
	! dbm_do_nextkey(db, key)
		register DBM *db;
	+ 	datum key;
	  {
		struct stat statb;
		datum item;
	+ 	register i;
	  
		if (dbm_error(db) || fstat(db->dbm_pagf, &statb) < 0)
			goto err;
		statb.st_size /= PBLKSIZ;
	+ 	if(key.dptr != NULL) {
	+ 		dbm_access(db, dcalchash(key));
	+ 		if ((i = finddatum(db->dbm_pagbuf, key)) >= 0)
	+ 			db->dbm_keyptr = i + 2;
	+ 	}
		for (;;) {
			if (db->dbm_blkptr != db->dbm_pagbno) {
				db->dbm_pagbno = db->dbm_blkptr;
	***************
	*** 259,264 ****
	--- 256,280 ----
		item.dptr = NULL;
		item.dsize = 0;
		return (item);
	+ }
	+ 
	+ static	datum	nullkey	= {NULL, 0};
	+ 
	+ datum
	+ dbm_firstkey(db)
	+ 	DBM *db;
	+ {
	+ 
	+ 	db->dbm_blkptr = 0L;
	+ 	db->dbm_keyptr = 0;
	+ 	return (dbm_do_nextkey(db, nullkey));
	+ }
	+ 
	+ datum
	+ dbm_nextkey(db)
	+ 	DBM *db;
	+ {
	+ 	return(dbm_do_nextkey(db, nullkey));
	  }
	  
	  static



	*** /usr/src/usr.lib/libdbm/dbm.c	Tue Aug 26 12:35:06 1986
	--- dbm.c	Fri Apr 24 15:05:09 1987
	***************
	*** 99,104 ****
	--- 99,105 ----
	  datum key;
	  {
		datum item;
	+ 	datum dbm_do_nextkey();
	  
		if (cur_db == NODB) {
			printf(no_db);
	***************
	*** 105,109 ****
			item.dptr = 0;
			return (item);
		}
	! 	return (dbm_nextkey(cur_db, key));
	  }
	--- 106,110 ----
			item.dptr = 0;
			return (item);
		}
	! 	return (dbm_do_nextkey(cur_db, key));
	  }

-- 
Ed Gould                    mt Xinu, 2560 Ninth St., Berkeley, CA  94710  USA
{ucbvax,decvax}!mtxinu!ed   +1 415 644 0146

"A man of quality is not threatened by a woman of equality."