1
0
Files
irix-657m-src/eoe/lib/libdb/dbhash-bigdata.c
2022-09-29 17:59:04 +03:00

121 lines
2.7 KiB
C

/*
* Bug in Berkeley DB 1.85, DB_HASH, Big data.
* When trying to store data that is bigger than 4075 bytes
* the 'put' silently fails (it returns success but somehow corrupts
* the database) and a subsequent 'get' gives: no such key
*
* The problem doesn't exist in DB_BTREE.
* A possible workaround would be to use DB_BTREE
*/
#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#include <stdarg.h>
static u_int flags = 0;
static void err(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
(void)fprintf(stderr, "\n");
exit(1);
}
#define NOOVERWRITE "put failed, would overwrite key\n"
void put(DB *dbp, DBT *kp, DBT *dp)
{
switch (dbp->put(dbp, kp, dp, flags)) {
case 0:
break;
case -1:
err("put: %s", strerror(errno));
/* NOTREACHED */
case 1:
(void)write(2, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
break;
}
}
void getdata(DB *dbp, DBT *kp, DBT *dp)
{
switch (dbp->get(dbp, kp, dp, flags)) {
case 0:
return;
case -1:
err("getdata: %s", strerror(errno));
/* NOTREACHED */
case 1:
err("Compiler -O2 bug: getdata failed, no such key.");
/* NOTREACHED */
}
}
void main()
{
const char * testdb = "test.db";
size_t size;
void * s;
DB * db;
DBT key, data1, data2;
char buf1[6000], buf2[6000], *mykey = "somekey";
unlink(testdb);
/* init, make them different */
s = (void *) buf1; memset(s, 'X', 5000);
s = (void *) buf2; memset(s, 'z', 5000);
key.data = (void *) mykey;
key.size = strlen(mykey);
data1.data = buf1;
data1.size = 5000;
data2.data = buf2;
data1.size = 5000;
for (size = 4073; size <= 9075; size += 151) {
if ((db = dbopen(testdb, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR,
DB_HASH, NULL)) == NULL) {
err("dbopen(%s, ...): %s", testdb, strerror(errno));
}
data1.size = size;
put(db, &key, &data1);
if (db->close(db))
err("db->close: %s", strerror(errno));
if ((db = dbopen(testdb, O_RDONLY,
S_IRUSR|S_IWUSR, DB_HASH, NULL)) == NULL) {
err("dbopen(%s, ...): %s", testdb, strerror(errno));
}
getdata(db, &key, &data2);
if (strncmp(data1.data, data2.data, size) != 0) {
fprintf(stderr, "BUG stored data of size=%lu is incorrect\n", size);
} else {
fprintf(stderr, "size=%lu: OK\n", size);
}
if (db->close(db))
err("db->close: %s", strerror(errno));
}
exit(0);
}