summaryrefslogtreecommitdiffstats
path: root/lib/libc/db/recno/rec_put.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/db/recno/rec_put.c')
-rw-r--r--lib/libc/db/recno/rec_put.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/lib/libc/db/recno/rec_put.c b/lib/libc/db/recno/rec_put.c
index 590d45b..1afae0d 100644
--- a/lib/libc/db/recno/rec_put.c
+++ b/lib/libc/db/recno/rec_put.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1990, 1993
+ * Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_put.c 8.3 (Berkeley) 3/1/94";
+static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -66,7 +66,7 @@ __rec_put(dbp, key, data, flags)
u_int flags;
{
BTREE *t;
- DBT tdata;
+ DBT fdata, tdata;
recno_t nrec;
int status;
@@ -78,11 +78,38 @@ __rec_put(dbp, key, data, flags)
t->bt_pinned = NULL;
}
+ /*
+ * If using fixed-length records, and the record is long, return
+ * EINVAL. If it's short, pad it out. Use the record data return
+ * memory, it's only short-term.
+ */
+ if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
+ if (data->size > t->bt_reclen)
+ goto einval;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_reclen) :
+ realloc(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ memmove(t->bt_rdata.data, data->data, data->size);
+ memset((char *)t->bt_rdata.data + data->size,
+ t->bt_bval, t->bt_reclen - data->size);
+ fdata.data = t->bt_rdata.data;
+ fdata.size = t->bt_reclen;
+ } else {
+ fdata.data = data->data;
+ fdata.size = data->size;
+ }
+
switch (flags) {
case R_CURSOR:
- if (!ISSET(t, B_SEQINIT))
+ if (!F_ISSET(&t->bt_cursor, CURS_INIT))
goto einval;
- nrec = t->bt_rcursor;
+ nrec = t->bt_cursor.rcursor;
break;
case R_SETCURSOR:
if ((nrec = *(recno_t *)key->data) == 0)
@@ -115,11 +142,11 @@ einval: errno = EINVAL;
* already in the database. If skipping records, create empty ones.
*/
if (nrec > t->bt_nrecs) {
- if (!ISSET(t, R_EOF | R_INMEM) &&
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, nrec) == RET_ERROR)
return (RET_ERROR);
if (nrec > t->bt_nrecs + 1) {
- if (ISSET(t, R_FIXLEN)) {
+ if (F_ISSET(t, R_FIXLEN)) {
if ((tdata.data =
(void *)malloc(t->bt_reclen)) == NULL)
return (RET_ERROR);
@@ -133,18 +160,18 @@ einval: errno = EINVAL;
if (__rec_iput(t,
t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
return (RET_ERROR);
- if (ISSET(t, R_FIXLEN))
+ if (F_ISSET(t, R_FIXLEN))
free(tdata.data);
}
}
- if ((status = __rec_iput(t, nrec - 1, data, flags)) != RET_SUCCESS)
+ if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
return (status);
if (flags == R_SETCURSOR)
- t->bt_rcursor = nrec;
-
- SET(t, R_MODIFIED);
+ t->bt_cursor.rcursor = nrec;
+
+ F_SET(t, R_MODIFIED);
return (__rec_ret(t, NULL, nrec, key, NULL));
}
@@ -171,7 +198,7 @@ __rec_iput(t, nrec, data, flags)
PAGE *h;
indx_t index, nxtindex;
pgno_t pg;
- size_t nbytes;
+ u_int32_t nbytes;
int dflags, status;
char *dest, db[NOVFLSIZE];
@@ -187,7 +214,7 @@ __rec_iput(t, nrec, data, flags)
tdata.data = db;
tdata.size = NOVFLSIZE;
*(pgno_t *)db = pg;
- *(size_t *)(db + sizeof(pgno_t)) = data->size;
+ *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
dflags = P_BIGDATA;
data = &tdata;
} else
@@ -246,7 +273,7 @@ __rec_iput(t, nrec, data, flags)
WR_RLEAF(dest, data, dflags);
++t->bt_nrecs;
- SET(t, B_MODIFIED);
+ F_SET(t, B_MODIFIED);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
OpenPOWER on IntegriCloud