diff options
Diffstat (limited to 'lib/libc/db/recno/rec_put.c')
-rw-r--r-- | lib/libc/db/recno/rec_put.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lib/libc/db/recno/rec_put.c b/lib/libc/db/recno/rec_put.c index 8c3bae5..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; + t->bt_cursor.rcursor = nrec; - SET(t, R_MODIFIED); + 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); |